/*
    Utility objects and functions
    version 1.0
    gpeters@gcpeters.com
    07/31/01
    
    Copyright (c) 2001 Grant Peters.
    This code is free for use, and modify 
    with the precept that this copyright information
    remains with all implementations of this source code.
    
    Thank you, and enjoy.

Object Classes
UserAgent */
function UserAgent() {
	var __re;
	var __version;
    // store color depth
    this.color = screen.colorDepth;
    //store refs to navigator props appVersion, and userAgent
    this.userAgent=navigator.userAgent;
	this.appName=navigator.appName;
	this.appVersion=parseFloat(navigator.appVersion);
	// detect opera
	this.isOp = this.userAgent.indexOf('Opera')>-1;
	this.isMinOp4=this.isMinOp5=this.isMinOp6=this.isMinOp7=this.isMinOp7_5=false;
	if(this.isOp) {
		if(this.appName=='Opera') {
			__version=this.appVersion;
		} else {
		    __re=new RegExp('Opera (\\d+\\.\\d+)');
			__re.test(this.userAgent);
			__version=parseFloat(RegExp['$1']);
		}
		this.isMinOp4=__version>=4;
		this.isMinOp5=__version>=5;
		this.isMinOp6=__version>=6;
		this.isMinOp7=__version>=7;
		this.isMinOp7_5=__version>=7.5;
	}
	//detect konqueror &/or safari
	this.isKHTML=this.userAgent.indexOf('KHTML')>-1||this.userAgent.indexOf('Konqueror')>-1||this.userAgent.indexOf('AppleWebKit')>-1;
	this.isMinSF1=this.isMinSF1_2=false;
	this.isMinKQ2_2=this.isMinKQ3=this.isMinKQ3_1=this.isMinKQ3_2=false;
	if(this.isKHTML) {
		this.isSF=this.userAgent.indexOf('AppleWebKit')>-1;
		this.isKQ=this.userAgent.indexOf('Konqueror')>-1;
		if(this.isSF) {
			__re=new RegExp('AppleWebKit\\/(\\d+(?:\\.\\d*)?)');
			__re.test(this.userAgent);
			var apWebKitVersion=parseFloat(RegExp['$1']);
			this.isMinSF1=apWebKitVersion>=85;
			this.isMinSF1_2=apWebKitVersion>=124;
		} else if(this.isKQ) {
			__re=new RegExp('Konqueror\\/(\\d+(?:\\.\\d+(?:\\.\\d)?)?)');
			__re.test(this.userAgent);
			this.isMinKQ2_2=this.__compareVersions(RegExp['$1'],'2.2')>=0;
			this.isMinKQ3=this.__compareVersions(RegExp['$1'],'3.0')>=0;
			this.isMinKQ3_1=this.__compareVersions(RegExp['$1'],'3.1')>=0;
			this.isMinKQ3_2=this.__compareVersions(RegExp['$1'],'3.2')>=0;
		}
	}
	// detect IE
	this.isIE=this.userAgent.indexOf('compatible')>-1&&this.userAgent.indexOf('MSIE')>-1&&!this.isOP;
	this.isMinIE4=this.isMinIE5=this.isMinIE5_5=this.isMinIE6=this.isMinIE7=false;
	if(this.isIE) {
		__re=new RegExp('MSIE (\\d+\\.\\d+);');
		__re.test(this.userAgent);
		__version=parseFloat(RegExp['$1']);
		this.isMinIE4=__version>=4;
		this.isMinIE5=__version>=5;
		this.isMinIE5_5=__version>=5.5;
		this.isMinIE6=__version>=6;
		this.isMinIE7=__version>=7;
	}
	// detect mozilla
	this.isMZ=this.userAgent.indexOf('Gecko')>-1&&!this.isKHTML;
	this.isMinMZ1=this.isMinMZ1_4=this.isMinMZ1_5=this.isMinMZ1_8=false;
	if(this.isMZ) {
		__re=new RegExp('rv:(\\d+\\.\\d+(?:\\.\\d+)?)');
		__re.test(this.userAgent);
		this.isMinMZ1=this.__compareVersions(RegExp['$1'],'1.0')>=0;
		this.isMinMZ1_4=this.__compareVersions(RegExp['$1'],'1.4')>=0;
		this.isMinMZ1_5=this.__compareVersions(RegExp['$1'],'1.5')>=0;
		this.isMinMZ1_8=this.__compareVersions(RegExp['$1'],'1.8')>=0;
	}
	//detect netscape
	this.isNS=!this.isIE&&!this.isOP&&!this.isMZ&&!this.isKHTML&&
	          (this.userAgent.indexOf('Mozilla')==0)&&(this.appName=='Netscape')&&
			  (this.appVersion>=4.0&&this.appVersion<5.0);
	this.isMinNS4=this.isMinNS4_5=this.isMinNS4_7=this.isMinNS4_8=false;
	if(this.isNS) {
		this.isMinNS4=true;
		this.isMinNS4_5=this.appVersion>=4.5;
		this.isMinNS4_7=this.appVersion>=4.7;
		this.isMinNS4_8=this.appVersion>=4.8;
	}
	// detect OS
	this.isWIN=(/^Win(?:32|dows)/).test(navigator.platform);
	this.isMAC=(/^Mac(?:68k|PPC|intosh)/).test(navigator.platofrm);
	this.isUNIX=navigator.platofrm=='X11'&&!this.isWIN&&!this.isMAC;
	this.isWIN95=this.isWIN98=this.isWINNT4=this.isWIN2k=this.isWINME=this.isWINXP=false;
	this.isMAC68=this.isMACPPC=false;
	this.isSUNOS=this.isSUNOS4=this.isSUNOS5=this.isSUNOS5_5=false;
	// handle windows
	if(this.isWIN) {
		this.isWIN95=(/Win(?:95|dows 95)/).test(this.userAgent);
		this.isWIN98=(/Win(?:98|dows 98)/).test(this.userAgent);
		this.isWINME=(/Win(?: 9x 4.90|dows ME)/).test(this.userAgent);
		this.isWIN2k=(/Windows (?:NT 5.0|2000)/).test(this.userAgent);
		this.isWINXP=(/Windows (?:NT 5.1|XP)/).test(this.userAgent);
		this.isWINNT4=(/Win(?:dows\s)?NT\s?(?:4\.0)?/).test(this.userAgent)&&(!this.isWINME&&!this.isWIN2K&&!this.isWINXP);
	}
	// handle mac OS
	if(this.isMAC) {
		this.isMAC68K=(/(?:Mac_)?68(?:000|K)/).test(this.userAgent);
		this.isMACPPC=(/(?:Mac_)?P(?:ower)?PC/).test(this.userAgent);
	}
	// handle unix
	if(this.isUNIX) {
		this.isSUNOS=this.userAgent.indexOf('SunOS')>-1;
		if(this.isSUNOS) {
			__re=new RegExp('SunOS (\\d+\\.\\d+(?:\\.\\d+)?)');
			this.isSUNOS4=this.__compareVersion(RegExp['$1'],'4.0');
			this.isSUNOS5=this.__compareVersion(RegExp['$1'],'5.0');
			this.isSUNOS5_5=this.__compareVersion(RegExp['$1'],'5.5');
		}
	}
}//end UserAgent c'tor
UserAgent.prototype.__compareVersions=function(vers1,vers2) {
	var versArr1=vers1.split('.');
	var versArr2=vers2.split('.');
	if(versArr1.length>versArr2.length)
	    for(var i=0;i<versArr1.length-versArr2.length;i++)
		    versArr2.push('0');
	else if(versArr1.length<versArr2.length)
	    for(var i=0;i<versArr2.length-versArr1.length;i++)
		    versArr1.push('0');
	for(var i=0;i<versArr1.length;i++) {
		if(versArr1[i]<versArr2[i]) return -1;
		else if(versArr1[i]>versArr2[i]) return 1;
	}
	return 0;
}

// StringBuffer
function StringBuffer() {this.__strings__=new Array();};
StringBuffer.prototype.append=function(str) {this.__strings__.push(str);};
StringBuffer.prototype.appendLine=function(str) {this.__strings__.push(str+"\n");};
StringBuffer.prototype.toString=function() {return this.__strings__.join('');};
StringBuffer.prototype.clear=function() {this.__strings__=new Array();};

// Dimension object
function Dimension(width,height) {
    this.width=width;
    this.height=height;
}
Dimension.prototype.getWidth =function(){return this.width;};
Dimension.prototype.getHeight=function(){return this.height;};

//String addons
String.prototype.stripMarkUp = function() {return this.replace(/<(?:.|\s)*?>/g,'');};

// Utitlity Objects
// Util Object
var Util=new Object();

Util.getClientDim=function() {
	var cw,ch;
	if (self.innerHeight) {// all except Explorer
		cw = self.innerWidth;
		ch = self.innerHeight;
	} else if (document.documentElement&&document.documentElement.clientHeight) {// Explorer 6 Strict Mode
		cw = document.documentElement.clientWidth;
		ch = document.documentElement.clientHeight;
	} else if (document.body) {// other Explorers 
		cw = document.body.clientWidth;
		ch = document.body.clientHeight;
	}
	return new Dimension(cw,ch);
};

Util.launchWindow=function (htmlSrc, name, dimension, windowProps, x, y) {
    var w=dimension.getWidth();
    var h=dimension.getHeight();
    var props='width=' + w + ',height=' + h;
    if(windowProps) props += ',' + windowProps;
    var mw=window.open(htmlSrc,name,props);
    mw.moveTo(x,y);
    return mw;
};

Util.launchWindowCentered=function(htmlSrc,name,dimension,windowProps) {
	var x=(screen.width/2)-(dimension.getWidth()/2);
    var y=(screen.height/2)-(dimension.getHeight()/2);
    return this.launchWindow(htmlSrc,name,dimension,windowProps,x,y);
};

Util.colToArr=function(collection) {
	var arr = new Array();
	for(var i=0;i<collection.length;i++) arr[i]=collection[i];
	return arr;
};

Util.sortTable=function(tableID,col,dataType,bgColor) {
	var table=document.getElementById(tableID);
	var tBody=table.tBodies[0];
	var trArr=Util.colToArr(tBody.rows);
	if(table.currSortCol==col) trArr.reverse();
	else trArr.sort(Util.generateCompareTRS(col,dataType));
	var frag=document.createDocumentFragment();
	for(var i=0;i<trArr.length;i++) {
		if(bgColor)
		    for(var j=0;j<trArr[i].cells.length;j++)
	            trArr[i].cells[j].style.backgroundColor=(j==col)?bgColor:'transparent';
		frag.appendChild(trArr[i]);
	}
	tBody.appendChild(frag);
	table.currSortCol=col;
};

Util.convert=function(value,toDataType) {
	switch(toDataType) {
		case 'number': return parseFloat(value);
		case 'date'  : return new Date(Date.parse(value));
		default      : return value.toString();
	}
};

Util.generateCompareTRS=function(col,dataType) {
	return function(tr1,tr2) {
		if(tr1.cells[col].getAttribute('value')) {
			var value1=Util.convert(tr1.cells[col].getAttribute('value'),dataType);
			var value2=Util.convert(tr2.cells[col].getAttribute('value'),dataType);
		} else {
			var value1=Util.convert(tr1.cells[col].firstChild.nodeValue,dataType);
			var value2=Util.convert(tr2.cells[col].firstChild.nodeValue,dataType);
		}
		return (value1<value2)?-1:(value1>value2)?1:0;
	};
};

Util.setCookie=function(name,value,expiresDate,domain,path,isSecure) {
	var cookieStr=name+'='+encodeURIComponent(value);
	if(expiresDate) cookieStr+='; expires='+expiresDate.toGMTString();
	if(domain) cookieStr+='; domain='+domain;
	if(path) cookieStr+='; path='+path;
	if(isSecure) cookieStr+='; secure';
	document.cookie=cookieStr;
};

Util.getCookie=function(name) {
	var re=new RegExp('(?:; )?'+name+'=([^;]*);?');
	if(re.test(document.cookie))
	    return decodeURIComponent(RegExp["$1"]);
	return false;
};
// correctly handle PNG transparency in Win IE 5.5 & 6.

Util.correctPNG=function() {
   var arVersion = navigator.appVersion.split("MSIE")
   var version = parseFloat(arVersion[1])
   if ((version >= 5.5) && (document.body.filters)) {
      for(var i=0; i<document.images.length; i++) {
         var img = document.images[i]
         var imgName = img.src.toUpperCase()
         if (imgName.substring(imgName.length-3, imgName.length) == "PNG") {
            var imgID = (img.id) ? "id='" + img.id + "' " : ""
            var imgClass = (img.className) ? "class='" + img.className + "' " : ""
            var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
            var imgStyle = "display:inline-block;" + img.style.cssText 
            if (img.align == "left") imgStyle = "float:left;" + imgStyle
            if (img.align == "right") imgStyle = "float:right;" + imgStyle
            if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle
            var strNewHTML = "<span " + imgID + imgClass + imgTitle
            + " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
            + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
            + "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>" 
            img.outerHTML = strNewHTML
            i = i-1
         }
      }
   }    
};

// RegExpUtil Object
var RegExpUtil=new Object();
//this my seem like a waste, but it allows for literal expressions to be tested in a semantic way
RegExpUtil.test=function(re,str) {return re.test(str);};

// EventUtil Object
var EventUtil=new Object();

EventUtil.getEvent=function() {
	if(window.event)
		return this.standardizeEventObj(window.event);
	return EventUtil.getEvent.caller.arguments[0];
};

EventUtil.standardizeEventObj=function(evtObject) {
	var ua = new UserAgent();
	if(ua.isIE&&ua.isWIN) {
	    evtObject.charCode=(evtObject.type=='keypress')?evtObject.keyCode:0;
		evtObject.eventPhase=2;
		evtObject.isChar=(evtObject.charCode>0);
		evtObject.pageX=evtObject.clientX+document.body.scrollLeft;
		evtObject.pageY=evtObject.clientY+document.body.scrollTop;
		evtObject.target=evtObject.srcElement;
		evtObject.time=(new Date()).getTime();
		if(evtObject.type=='mouseout') evtObject.relatedTarget=evtObject.toElement;
		else if(evtObject.type=='mouseover') evtObject.relatedTarget=evtObject.fromElement;
		evtObject.preventDefault=function() {this.returnValue=false;};
		evtObject.stopPropagation=function() {this.cancelBubble=true;};
	}
	return evtObject;
};

EventUtil.addEventHandler=function(evtTarget,evtType,evtHandler) {
	if(evtTarget.addEventListener) {
		evtTarget.addEventListener(evtType,evtHandler,false);
	} else if(evtTarget.attachEvent) {
		evtTarget.attachEvent('on'+evtType,evtHandler);
	} else {
		evtTarget['on'+evtType]=evtHandler;
	}
};

EventUtil.removeEventHandler=function(evtTarget,evtType,evtHandler) {
	if(evtTarget.removeEventListener) {
		evtTarget.removeEventListener(evtType,evtHandler,false);
	} else if(evtTarget.detachEvent) {
		evtTarget.detachEvent('on'+evtType,evtHandler);
	} else {
		target['on'+evtType]=null;
	}
};

// FormUtil Object
var FormUtil=new Object();

FormUtil.setTextBoxOnFocusHandlers=function() {
	var fields=document.getElementsByTagName('input');
	var areas=document.getElementsByTagName('textarea');
	for(var i=0;i<fields.length;i++)
	    if(fields[i].type=='text'||fields[i].type=='password')
		    fields[i].onfocus=function(){this.select();};
	for(var i=0;i<areas.length;i++)
	    areas[i].onfocus=function(){this.select();};
};

FormUtil.tabForward=function(textBox,maxLength) {
	var form=textBox.form;
	if(form.elements[form.elements.length-1]!=textBox&&textBox.value.length==maxLength) {
		for(var i=0;i<form.elements.length;i++) {
			if(form.elements[i]==textBox) {
				for(var j=i+1;j<form.length;j++) {
					if(form.elements[j].type!='hidden') {
						form.elements[j].focus();
						return;
					}
				}
				return;
			}
		}
	}
};

FormUtil.focusOnFirst=function(formName) {
	if(document.forms.length>0) {
		var form=document.forms[(formName||0)];
		for(var i=0;i<form.elements.length;i++) {
			var field=form.elements[i];
			if(field.type!='hidden') {
				field.focus();
				if(field.value)field.select();
				return;
			}
		}
	}
};

FormUtil.disable=function(form) {
	form=form||document.forms[0];
	if(form) {
		for(var i=0;i<form.elements.length;i++) {
			var field=form.elements[i];
			if(field.type!='hidden')field.disabled=true;
		}
	}
};

FormUtil.enable=function(form) {
	form=form||document.forms[0];
	if(form) {
		for(var i=0;i<form.elements.length;i++) {
			var field=form.elements[i];
			if(field.type!='hidden')field.disabled=false;
		}
	}
};

// Helpers
FormUtil.checkEmail  =function (email) {return FormUtil.checkValue('email',email.replace(/\s/g,''));};
FormUtil.checkPhone  =function(phone)  {return FormUtil.checkValue('phone',phone.replace(/\D/g,''));};
FormUtil.checkZipcode=function(zipcode)  {return FormUtil.checkValue('zipcode',zipcode.replace(/[\s]/g,''));};

FormUtil.checkValue=function(type,value) {
	var re=new RegExp();
	if(type=='email') {
		re=/^(?:\w+\.?)*\w+@(?:\w+\.)*\w+$/;
		return re.test(value);
	} else if(type=='phone') {
		re=/^\d{10}$/;
		return (re.test(value))?value:false;
	} else if(type=='zipcode') {
		re=/^\d{5}-?(?:\d{4})?$/;
		return (re.test(value))?value:false;
	}
	return false;
};
// ListUtil Object
var ListUtil=new Object();

ListUtil.getSelectedIndexes=function(listBox) {
	var arr=new Array();
	for(var i=0;i<listBox.options.length;i++)
		if(listBox.options[i].selected) arr.push(i)
};

ListUtil.add=function(listBox,name,value) {
	var opt=document.createElement('option');
	opt.appendChild(document.createTextNode(name));
	if(arguments.length==3) opt.setAttribute('value',value);
	listBox.appendChild(opt);
};

ListUtil.move=function(lsitBoxFrom,listBoxTo,index) {
	var opt=listBoxFrom.options[index];
	if(opt!=null) listBoxTo.appendChild(opt);
};

ListUtil.shiftUp=function(listBox,index) {
	if(index>0) {
		var opt=listBox.options[index];
		var prevOpt=listBox.options[index-1];
		listBox.insertBefore(opt,prevOPt);
	}
};

ListUtil.shiftDown=function(listBox,index) {
	if(index<listBox.options.length-1) {
		var opt=listBox.options[index];
		var nextOpt=listBox.options[index+1];
		listBox.insertBefore(nextOpt,opt);
	}
};

//FlashUtil Object
var FlashUtil=new Object();
FlashUtil.isFlashInstalled=false;
FlashUtil.flashVersion=0;
FlashUtil.detectFlash=function() {
	if (navigator.plugins && navigator.plugins.length) {
		x = navigator.plugins["Shockwave Flash"];
		if (x) {
			FlashUtil.isFlashInstalled = true;
			if (x.description) {
				y = x.description;
				FlashUtil.flashVersion = y.charAt(y.indexOf('.')-1);
			}
		}
		if (navigator.plugins["Shockwave Flash 2.0"]) {
			FlashUtil.isFlashInstalled = true;
			FlashUtil.flashVersion = 2;
		}
	} else if (navigator.mimeTypes && navigator.mimeTypes.length) {
		x = navigator.mimeTypes['application/x-shockwave-flash'];
		if (x && x.enabledPlugin)
			FlashUtil.isFlashInstalled = true;
	} else {
		var buffer=new StringBuffer();
		buffer.appendLine('<scr'+'ipt type="text/vbscript">');
		buffer.appendLine('on error resume next');
		buffer.appendLine('For i=2 to 20');
		buffer.appendLine('If Not(IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash." & i))) Then');
		buffer.appendLine('Else');
		buffer.appendLine('FlashUtil.isFlashInstalled=true');
		buffer.appendLine('FlashUtil.flashVersion=i');
		buffer.appendLine('End If');
		buffer.appendLine('Next');
		buffer.appendLine('</scr'+'ipt>');
		document.write(buffer);
	}
};
FlashUtil.addContent=function(dir,loaderSWF,realSWF,width,height,uid,
					          quality,wmode,altImgPath,altImgWidth,altImgHeight,altImgAltTxt) {
	if(!FlashUtil.flashContent) FlashUtil.flashContent=new Array();
	var contentObj=new Object();
	contentObj.dir=dir;
	contentObj.loaderSWF=loaderSWF||'';
	contentObj.realSWF=realSWF;
	contentObj.url=(loaderSWF) ? dir+loaderSWF+'?path='+dir+realSWF:dir+realSWF;
	contentObj.width=width;
	contentObj.height=height;
	contentObj.quality=quality||'best';
	contentObj.wmode=wmode||'opaque';
	if(uid) {
    	contentObj.uid=uid;
		contentObj.url+=((loaderSWF)?'&':'?')+'uid='+uid;
	}
	contentObj.altImgPath=altImgPath||'';
	contentObj.altImgWidth=altImgWidth||'';
	contentObj.altImgHeight=altImgHeight||'';
	contentObj.altImgAltTxt=altImgAltTxt||'';
	FlashUtil.flashContent[uid]=contentObj;
};
FlashUtil.writeContent=function(id,elemID) {
	var contentObj=FlashUtil.flashContent[id];
	var htmlStr='<object type="application/x-shockwave-flash" data="'+contentObj.url+'" ';
	htmlStr+='width="'+contentObj.width+'" height="'+contentObj.height+'">';
	htmlStr+='<param name="movie" value="'+contentObj.url+'" />';
	htmlStr+='<param name="quality" value="'+contentObj.quality+'" />';
	htmlStr+='<param name="wmode" value="'+contentObj.wmode+'" />';
	if(contentObj.altImgPath) {
    	htmlStr+='<img src="'+contentObj.altImgPath+'" width="'+contentObj.altImgWidth+'" height="'+
		           contentObj.altImgHeight+'" alt="'+contentObj.altImgAltTxt+'" />';
	}
	if(contentObj.uid) {
		htmlStr+='<param name="flashvars" value="uid='+contentObj.uid+'" />';
	}
	htmlStr+='</object>';
	if(elemID) {
		document.getElementById(elemID).innerHTML=htmlStr;
	} else {
		document.write(htmlStr);
	}
};