// Original File Name: Framework.js
// Framework Functions
// This file contains javascript functions that we probably want to have access to on every page in our application.

function Trim(sStr) 
{
    var sOut = sStr;
	if (sOut != null)
	{
		//get rid of leading spaces 
	    while (sOut.substring(0, 1) == ' ')
	    {
	        sOut = sOut.substring(1, sOut.length);
		}
	
	    //get rid of trailing spaces 
	    while (sOut.substring(sOut.length - 1, sOut.length) == ' ')
	    {
	        sOut = sOut.substring(0, sOut.length - 1);
		}
	}
	else 
	{
		sOut = "";
	}

   	return sOut.toString();
	
	//Regular expressions dont work with empty strings on mac OS9
	//return Rtrim(Ltrim(sStr));
}

String.prototype.trim = function()
{
	//return Trim(this);
	return this.replace(/^\s+/, '').replace(/\s+$/, ''); 
}

function GetElementArray() {
	var elements = new Array();
	for (var i = 0; i < arguments.length; i++) {
		var element = arguments[i];
		if (typeof element == 'string')
			element = document.getElementById(element);
		if (arguments.length == 1)
			return element;
		elements.push(element);
	}
	return elements;
}

function GetInt(oObj) {
	var nNum = new Number(oObj);
	if (nNum.valueOf() != NaN) {
		return nNum.valueOf();
	} else {
		return 0;
	}
}


function AddOnLoadAction(sAction) {
	alert("Setting OnLoad Action = " + sAction );
	if (document.OnLoadAction) {
		document.OnLoadAction += '\n' + sAction;
	} else {
		document.OnLoadAction = sAction;
	}
}

function Join(obj, delimiter)
{
	var s = "";
	
	if( typeof(delimiter) == "undefined" || delimiter == null )
		delimiter = ",";

	if( obj==null || obj.length <= 0 )
		return s;
		
	for( var i = 0; i < obj.length; i++ )
	{
		s = s + ((s=="") ? "":delimiter) + obj[i].toString();
	}
	
	return s;
}

function GetBoolean(oObj) {
	if (!oObj) {
		return false;
	}

	switch (oObj.toString().toLowerCase()) {
		case "yes" :
		case "true" :
		case "1" :
			return true;
	}
	return false;
}

String.prototype.GetBoolean = function() {
	return GetBoolean(this);
}

/****************************** date)format.js *********************************
 *
 * Object Extension for Date object
 *   description:
 *          -Stores day and month arrays in Date object 
 *          -Provides a format function to 'pretty' print
 *           the date in custom formats
 *   parameters:
 *          format - accpets any variation of the following list
 *                 yyyy  is a 4-digit year - i.e., 2002   
 *                 yy    is a 2-digit year - i.e., 02
 *                 month is the full month - i.e., September
 *                 mon   is the first three letters of the month - i.e., Sep
 *                 mmm   is the number of the month - i.e., 9
 *                 hh    is hours - i.e., 3
 *				   hh24  is hours in military time - i.e., 3 
 *                 mm    is minutes (always 2-digit) - i.e., 05
 *                 ss    is seconds (always 2-digit) - i.e., 08
 *                 ddd   is the first three letters of the day - i.e., Wed
 *                 dd    is the numerical day of the month - i.e, 25
 *                 day   is the full day of the week - i.e., Wednesday
 *                 timezone is the the timezone in hours from GMT - i.e., GMT+5
 *                 time24   is the time based on a 24 hour clock - i.e., 18:24   
 *                 time     is the time based on am/pm - i.e., 6:24PM  
 *				   meridian AM or PM
 *   example:
 *           myDate = newDate()
 *           myDate.format("day, month dd, yyyy hh:mm:ss timezone")
 *           would return "Wednesday, September 25, 2002 12:14:11 GMT-5"
 *   note: 
 *           If customizing the DateFormat function be aware that the ordering
 *           of the replace calls
 *   author:
 *           Scott Connelly scottsweep@yahoo.com 1/3/2002
 *	     Modified by Laban Eilers eilers@zoominfo.com 9/23/03
 ******************************************************************************/ 
 
//Store the date info in the Date object
Date.prototype.Months = ["January", "February", "March", 
                         "April", "May", "June", "July", 
                         "August", "September", "October", 
                         "November", "December"];
Date.prototype.Days = ["Sunday", "Monday", "Tuesday", 
                       "Wednesday", "Thursday", 
                       "Friday", "Saturday"];
Date.prototype.format = DateFormat;

function DateFormat(sFormat) {
   var sDate = sFormat;

   //yyyy  is a 4-digit year - i.e., 2002  
   sDate = sDate.replace( new RegExp("yyyy", "gi"), this.getFullYear() );
   //yy    is a 2-digit year - i.e., 02
   sDate = sDate.replace( new RegExp("yy", "gi"), new String( this.getFullYear() ).substring(2,4) );
   //month is the full month - i.e., September
   sDate = sDate.replace( new RegExp("month", "gi"), this.Months[this.getMonth()] );
   //mon   is the first three letters of the month - i.e., Sep
   sDate = sDate.replace( new RegExp("mon", "gi"), new String( this.Months[this.getMonth()] ).substring(0,3) );
   //mmm   is the number of the month - i.e., 9
   sDate = sDate.replace( new RegExp("mmm", "gi"), (this.getMonth() + 1) );   
   //hh    is hours - i.e., 3
   sDate = sDate.replace( new RegExp("hh", "gi"), (this.getHours() > 12) ? (this.getHours() - 12) : (this.getHours()) );
   //hh24    is hours - i.e., 3
   sDate = sDate.replace( new RegExp("hh", "gi"), this.getHours() );
   //mm    is minutes (always 2-digit) - i.e., 05
   var mm = new String( this.getMinutes() );
   if (mm.length == 1) mm = "0" + mm; //pad if single digit
   sDate = sDate.replace( new RegExp("mm", "gi"), mm );
   //ss    is seconds (always 2-digit) - i.e., 08
   var ss = new String( this.getSeconds() );
   if (ss.length == 1) ss = "0" + ss; //pad if single digit
   sDate = sDate.replace( new RegExp("ss", "gi"), ss ); 
   //ddd   is the first three letters of the day - i.e., Wed
   sDate = sDate.replace( new RegExp("ddd", "gi"), new String( this.Days[this.getDay()] ).substring(0,3) );
   //dd    is the numerical day of the month - i.e, 25
   sDate = sDate.replace( new RegExp("dd", "gi"), this.getDate() );
   //day   is the full day of the week - i.e., Wednesday
   sDate = sDate.replace( new RegExp("day", "gi"), this.Days[this.getDay()] );
   //meridian  AM/PM
   sDate = sDate.replace( new RegExp("meridian", "gi"), ((this.getHours() < 12) ? 'AM' : 'PM') );

   //timezone is the the timezone in hours from GMT - i.e., GMT+5
   var d = new Date();
   tz = d.getTimezoneOffset();
   timezone = "";
   if (tz < 0)
      timezone = "GMT-" +  tz / 60;
   else if (tz == 0)
      timezone = "GMT";
   else
      timezone = "GMT+" + tz / 60;
   sDate = sDate.replace( new RegExp("timezone", "gi"), timezone );
   
   //time24   is the time based on a 24 hour clock - i.e., 18:24   
   var minutes = new String( this.getMinutes() );
   if (minutes.length == 1) minutes = "0" + minutes; //pad if single digit
   var time24 = new String( this.getHours() + ":" + minutes );
   sDate = sDate.replace( new RegExp("time24", "gi"), time24 );
   
   //time     is the time based on am/pm - i.e., 6:24PM
   var time;
   var ampm;
   var hour = this.getHours();
   if ( hour < 12) {
      if (hour == 0) hour = 12;
         ampm = "AM"
   } else {
      if (hour !=12)
         hour = hour - 12;
      ampm = "PM";   
   }
   time = new String(hour + ":" + minutes + ampm);     
   sDate = sDate.replace( new RegExp("time", "gi"), time );

   return sDate;   
}


// Original File Name: UIFunctions.js
// User Interface Functions
// Functions that are commonly used on web pages with UI elements

function ToggleElement( id ) {
	var oElement = document.getElementById( id );
	
	if ( oElement.style.display != 'none' ) {
		oElement.style.display = 'none';
	} else {
		oElement.style.display = '';
	}

}

function IsHidden( id ) {
	var oElement = document.getElementById( id );
	
	if ( oElement.style.display == 'none' ) {
		return true;
	} else {
		return false;
	}
}

//generic method to get the value of a form field
function GetFormValue(oObj) {
	if (oObj[0] && oObj[0].type == 'radio') {
		return GetRadioValue(oObj);
	} else if (oObj.type == 'radio') {
		return GetRadioValue(oObj.form.elements[oObj.name]);
	} else if (oObj.tagName == 'SELECT') {
		return GetSelectValue(oObj);
	} else if (oObj.type == 'checkbox') {
		return oObj.checked ? oObj.value : '';
	} else {
		return oObj.value;
	}
}

//generic method to set the value of a form field
function SetFormValue(oObj, sValue) {
	if (oObj[0] && oObj[0].type == 'radio') {
		SetRadioValue(oObj, sValue);
	} else if (oObj.type == 'radio') {
		SetRadioValue(oObj.form.elements[oObj.name], sValue);
	} else if (oObj.tagName == 'SELECT') {
		SetSelectValue(oObj, sValue);
	} else {
		oObj.value = sValue;
	}
}

//returns the radio array's value 
function GetRadioValue(oRadio){
	if (oRadio.form)
		oRadio = oRadio.form.elements[oRadio.name];
	if (oRadio){
		if (oRadio.length){
			for (var i=0; i<oRadio.length; i++) {
				if (oRadio[i].checked){
					return oRadio[i].value;
				}
			}
		} else {
			if (oRadio.checked){
				return oRadio.value;
			}
		}
	}
	return "";
}

function SetRadioValue(oRadio, sValue){
	if (oRadio){
		if (oRadio.length){
			for (var i=0; i<oRadio.length; i++) {
				if (oRadio[i].value == sValue){
					oRadio[i].checked = true;
				}
			}
		} else {
			if (oRadio.value == sValue){
				oRadio.checked = true;
			}
		}
	}
}

function GetSelectValue(oSelect) {
	if (oSelect) {
		if (oSelect.multiple) {
			var arr = new Array();
			for (var i=0; i<oSelect.options.length; i++) {
				if (oSelect.options[i].selected) {
					arr[arr.length] = oSelect.options[i].value;
				}
			}
			
			return arr.join(",");
		} else {
			if (oSelect.selectedIndex > -1) {
				return oSelect.options[oSelect.selectedIndex].value;
			}
		}
	}
	return "";
}

function GetSelectText(oSelect) {
	if (oSelect) {
		if (oSelect.multiple) {
			var arr = new Array();
			for (var i=0; i<oSelect.options.length; i++) {
				if (oSelect.options[i].selected) {
					arr[arr.length] = oSelect.options[i].text;
				}
			}
			
			return arr.join(",");
		} else {
			if (oSelect.selectedIndex > -1) {
				return oSelect.options[oSelect.selectedIndex].text;
			}
		}
	}
	return "";
}

function GetRadioLabelText(oRadio) {
	var i;
	var sSelectedID = null;
	if (oRadio){
		if (oRadio.length){
			for (i=0; i<oRadio.length; i++) {
				if (oRadio[i].checked){
					sSelectedID = oRadio[i].id;
				}
			}
		} else {
			if (oRadio.checked){
				sSelectedID = oRadio.id;
			}
		}
	}
	
	if (sSelectedID == null) {
		return "";
	} else {
		var arrLabels = document.getElementsByTagName("LABEL");
		for (i=0; i<arrLabels.length; i++) {
			if (arrLabels[i].htmlFor == sSelectedID) {
				return arrLabels[i].innerHTML;
			}
		}
		
		return "";
	}
}

function SetSelectValue(oSelect, sValue, bRemoveOthers) {
	if (!bRemoveOthers && oSelect.multiple) {
		oSelect.selectedIndex = -1;
	}
	if (oSelect) {
		for (var i=0; i<oSelect.options.length; i++) {
			if (oSelect.options[i].value == sValue) {
				oSelect.options[i].selected = true;
				return true;
			}
		}
	}
	return false;
}

function DisableMultiSelect(oSelect) {
	for (var i=0; i<oSelect.options.length; i++) {
		if (oSelect.options[i].selected) {
			oSelect.options[i].selectedDisabled = true;
			oSelect.options[i].selected = false;
			oSelect.options[i].style.backgroundColor = "#CCCCCC";
		}
	}
	
	//IE rendering bug fix- add and remove a new option, and the colors will refresh
	if (document.all) {
		oSelect.options.add(new Option("", ""));
		oSelect.options.remove(oSelect.options.length-1);
	}
	
	oSelect.style.backgroundColor = "#EEEEEE";
	oSelect.disabled = true;
}

function EnableMultiSelect(oSelect) {
	for (var i = 0; i < oSelect.options.length; i++) {
		if (oSelect.options[i].selectedDisabled) {
			oSelect.options[i].selected = true;
			oSelect.options[i].selectedDisabled = null;
			oSelect.options[i].style.backgroundColor = "";
		}
	}
	
	oSelect.disabled = false;
	oSelect.style.backgroundColor = "#FFFFFF";
	
	//IE rendering bug fix- add and remove a new option, and the colors will refresh
	if (document.all) {
		oSelect.options.add(new Option("", ""));
		oSelect.options.remove(oSelect.options.length - 1);
	}
}

function GetAttributeEx(oObj, sAttrName) {
	if (!oObj) {
		return "";
	} else if (typeof(eval('oObj.' + sAttrName)) != "undefined") {
		return eval('oObj.' + sAttrName);
	} else if (!oObj.getAttribute) {
		return "";
	} else if (oObj.getAttribute(sAttrName) == null) {
		return "";
	} else {
		return oObj.getAttribute(sAttrName);
	}
}

function ResetForm(frm) {
	window.status = "Resetting form ...";
	
	for (var i=0; i<frm.elements.length; i++) {
		var ele = frm.elements[i];
		var defval = GetAttributeEx(ele, "defval");
		
		if (ele.type == 'radio') {
			if (defval == '') {
				// select the first radio button element
				if (!ele.checked && ele.id == frm.elements[ele.name][0].id)
					ele.click();				//to fire the 'onclick' event
			} else if (!ele.checked && ele.value == ele.defval)
					ele.click();
		} else if (ele.tagName == 'SELECT') {
			if (!SetSelectValue (ele, defval)) {
				if (ele.type == "select-multiple")
					ele.selectedIndex = -1;
				else
					ele.selectedIndex = 0;
			}
		} else if (ele.type == 'checkbox') {
			if (defval == '') {
				if (ele.checked) ele.click();
			}
			else {
				if (ele.value == defval && !ele.checked) ele.click();
				else if (ele.value != defval && ele.checked) ele.click();
			}	
		} 
		else if (ele.type == 'text') {
			ele.value = defval;
		}
	}
	window.status = "Done";
	return;
}

var enableDefaultAction = true;

function SetDefaultAction(e, objName) {
	var obj = document.getElementById(objName);
	if (obj == null || !enableDefaultAction) return;

	var keynum = (window.event) ? e.keyCode: e.which;
	if (keynum == 13) obj.click();
}

function DisableDocument(oDoc) {
	var arrItems = oDoc.getElementsByTagName("A");
	for (var i=0; i<arrItems.length; i++) {
		arrItems[i].onclick = function() {return false;};
		arrItems[i].href = "#";
		arrItems[i].style.cursor = "default";
	}
}



// Get a variable from the query string - Added by Jeff C. 8/3/2006
// Returns empty string if variable doesn't exist

function getQueryVariable(variable) {
  var query = window.location.search.substring(1);
  var vars = query.split("&");
  for (var i=0;i<vars.length;i++) {
    var pair = vars[i].split("=");
    if (pair[0] == variable) {
      return pair[1];
    }
  } 
  return "";
}


// Adds a function to the page's onLoad event - Added by Jeff C. 8/3/2006
// Much cleaner alternative to <body onLoad="foo()"> and can add multiple
// functions without breaking existing ones.

function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	}
	else {
		window.onload = function() {
			oldonload();
			func();
		}
	}
}

// Returns an array of all DOM elements with a certain CSS class - Added by Jeff C. 8/3/2006
// You can optionally limit the search to a certain node or tag type, via
// the second and third parameters

function getElementsByClass(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp('(^|\\s)'+searchClass+'(\\s|$)');
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}

// General purpose DOM function to add a node after another node

function insertAfter(parent, node, referenceNode) {
	parent.insertBefore(node, referenceNode.nextSibling);
}

// It can be used to check/uncheck the checkbox in a table cell element
// also, set <input type="checkbox" onclick="event.cancelBubble=true;">
function CheckUncheck (oCell) {
	for (var i=0; i<oCell.childNodes.length; i++) {
		var ele = oCell.childNodes[i];
		if (ele.type == 'checkbox') {
			ele.checked = !ele.checked;
			return true;
		}
	}
	return false;
}

// Function to be used for getting the dimensions of browser window.
// will return correct size regardless of browser type/version.
function BrowserSizePositions()
{
	var iClientWidth		= 0;
	var iClientHeight		= 0;
	var iDocumentWidth	= 0;
	var iDocumentHeight	= 0;
	var iScrollX			= 0;
	var iScrollY			= 0;
	
	// Get the visible size of the browser window
	if( typeof( window.innerWidth ) == 'number' )
	{
		//Non-IE
		iClientWidth	= window.innerWidth;
		iClientHeight	= window.innerHeight;
	}
	else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
	{
			//IE 6+ in 'standards compliant mode'
			iClientWidth	= document.documentElement.clientWidth;
			iClientHeight	= document.documentElement.clientHeight;
	}
	else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) 
	{
			//IE 4 compatible
			iClientWidth	= document.body.clientWidth;
			iClientHeight	= document.body.clientHeight;
		}
		
		// Get the document size (NOTE: IE6 and Mozilla Strict only)
		{
			iDocumentWidth		= document.body.clientWidth;
			iDocumentHeight	= document.body.clientHeight;
		}
		
		// Get the scroll position 
		if( typeof( window.pageYOffset ) == 'number' )
		{
			//Netscape compliant
			iScrollX = window.pageXOffset;
			iScrollY = window.pageYOffset;
		} 
		else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) )
		{
			//DOM compliant
			iScrollX = document.body.scrollLeft;
			iScrollY = document.body.scrollTop;
		}
		else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) )
		{
			//IE6 standards compliant mode
			iScrollX = document.documentElement.scrollLeft;
			iScrollY = document.documentElement.scrollTop;
		}
	
	this.ClientWidth		= iClientWidth;
	this.ClientHeight		= iClientHeight;
	this.DocumentWidth	= iDocumentWidth;
	this.DocumentHeight	= iDocumentHeight;
	this.ScrollX			= iScrollX;
	this.ScrollY			= iScrollY;
}

//Original File Name: layers.js

function IsObjectVisible(oObj) {
	var oTemp = oObj;
	
	//finds the first parent with the visiblity property set
	while (oTemp.parentNode) {
		if (oTemp.style && (oTemp.style.visibility != "")) {
			if (oTemp.style.visibility == "hidden") {
				return false;
			} else if (oTemp.style.visibility == "visible") {
				//its visible, see if its display propery is set
				break;
			}
		}
		
		oTemp = oTemp.parentNode;
	}
	
	//sees if any parent node has display set to none (inheritance cant be overriden)
	oTemp = oObj;
	
	while (oTemp.parentNode) {
		if (oTemp.style && (oTemp.style.display != "")) {
			if (oTemp.style.display == "none") {
				return false;
			} 
		}
		
		oTemp = oTemp.parentNode;
	}
	
	return true;
}

//hides all the select menus that overlap the given layer
function HideOverlappingSelects(oLayer) {
//if this is IE, hide selects that overlap the progress bar
	if ((document.all || (Browser.OS == OS_MAC && Browser.UserAgent == BROWSER_GECKO)) && oLayer) {
		var i;
		var arrSelects = document.getElementsByTagName('SELECT');
		var arrSelectsIgnore = oLayer.getElementsByTagName('SELECT');
		
		//prevents selects inside the div from being hidden
		for (i=0; i<arrSelectsIgnore.length; i++) {
			arrSelectsIgnore[i].overlap_ignore = true;
		}		

		for (i=0; i<arrSelects.length; i++) {
			//if the select overlaps the progress bar, and is visible, hide it and mark it
			if (DoesOverlap(oLayer, arrSelects[i]) && !arrSelects[i].overlap_ignore) {
				if (IsObjectVisible(arrSelects[i])) {
					arrSelects[i].style.visibility = 'hidden';
					arrSelects[i].overlap_hidden = true; //set expando value
					arrSelects[i].overlap_hidden_layer = oLayer.id;
					
					if (Browser.OS == OS_MAC && Browser.UserAgent == BROWSER_GECKO) {
						arrSelects[i].style.display = 'none';
					} else {
						CreateTempSelectDiv(arrSelects[i]);
					}
					
				}
			}
		}
	}
}

//shows the selects hidden by calling HideOverlappingSelects with the same layer
function ShowOverlappingSelects(oLayer) {
	if ((document.all || (Browser.OS == OS_MAC && Browser.UserAgent == BROWSER_GECKO)) && oLayer) {
		var arrSelects = document.getElementsByTagName('SELECT');
		var arrSelectsIgnore = oLayer.getElementsByTagName('SELECT');
		
		for (var i=0; i<arrSelects.length; i++) {
			if (arrSelects[i].overlap_hidden) { //read expando value
				if (arrSelects[i].overlap_hidden_layer == oLayer.id) {
					arrSelects[i].style.visibility = 'visible';
					if (Browser.OS == OS_MAC && Browser.UserAgent == BROWSER_GECKO) {
						arrSelects[i].style.display = 'block';
					}  else {
						RemoveTempSelectDiv(arrSelects[i]);
					}
				} 
			}
		}
		
		//prevents selects inside the div from being hidden
		for (i=0; i<arrSelectsIgnore.length; i++) {
			arrSelectsIgnore[i].overlap_ignore = false;
		}		
	}
}

//creates a div that looks just like the select object
function CreateTempSelectDiv(oSelect) {
	var oCoords = new ObjCoordinates(oSelect);
	var oTempDiv = document.createElement('<div id="' + oSelect.name + '_tempDiv" style="position:absolute; left:0px; top:0px; width:0px; height:0px; z-index:1"></div>');
	oTempDiv.style.width = oCoords.Width;
	oTempDiv.style.height = oCoords.Height;
	oTempDiv.style.top = oCoords.Top;
	oTempDiv.style.left = oCoords.Left;
	oTempDiv.style.border = "2px inset";
	oTempDiv.style.paddingLeft = "3px";
	oTempDiv.style.paddingTop = "0px";
	oTempDiv.style.fontFamily = 'Arial';

	if (oSelect.style.fontSize == '') {
		oTempDiv.style.fontSize = '11px';
	} else {
		oTempDiv.style.fontSize = parseInt(oSelect.style.fontSize) - 1;
	}

	oTempDiv.style.overflowY = 'scroll';
	
	if (oSelect.className == '') {
		oTempDiv.style.backgroundColor = "#FFFFFF";
	}

	if (oSelect.multiple) {
		oTempDiv.className = oSelect.className;
		oTempDiv.disabled = true;
		
		oTempDiv.style.overflowX = 'auto';
		oTempDiv.style.height = oCoords.Height;
		oTempDiv.style.width = oCoords.Width;
		for (var i=0; i<oSelect.options.length; i++) {
			oTempDiv.innerHTML += oSelect.options[i].text + '<br>';
			if (i >= 5) {
				break;
			}
		}
	} else {
		
		if (oSelect.selectedIndex >= 0) {
			oTempDiv.innerHTML = oSelect.options[oSelect.selectedIndex].innerHTML;
		}
	}
	document.body.appendChild(oTempDiv);
}

//removes the cooresponding "fake select" div
function RemoveTempSelectDiv(oSelect) {
	var oTemp = document.getElementById(oSelect.name + '_tempDiv');
	if (oTemp) {
		oTemp.removeNode(true);
	}
}

//wrapper object which makes it easy to access the coordinates of an HTML element
function ObjCoordinates(oObj) {
	if (!oObj) {
		return false;
	}
	
	this.Obj = oObj;
	
	this.Left = GetIeX(oObj);
	this.Top = GetIeY(oObj);
	this.Right = this.Left + parseInt(oObj.offsetWidth);
	this.Bottom = this.Top + parseInt(oObj.offsetHeight);
	
	this.Height = this.Bottom - this.Top;
	this.Width = this.Right - this.Left;
}

function GetName(oObj) {
	if (!oObj.id || oObj.id == '') {
		return oObj.name;
	} else {
		return oObj.id;
	}
}

function DoesOverlap(oObj, oCompareObj) {
	var cdObj = new ObjCoordinates(oObj);
	var cdCompareObj = new ObjCoordinates(oCompareObj);
	
	if (cdCompareObj.Left > cdObj.Left && cdCompareObj.Left < cdObj.Right) {
		if (cdCompareObj.Top > cdObj.Top && cdCompareObj.Top < cdObj.Bottom) {
			return true;
		} else if (cdCompareObj.Bottom > cdObj.Top && cdCompareObj.Bottom < cdObj.Bottom) {
			return true;
		}
	} else if (cdCompareObj.Right > cdObj.Left && cdCompareObj.Right < cdObj.Right) {
		if (cdCompareObj.Top > cdObj.Top && cdCompareObj.Top < cdObj.Bottom) {
			return true;
		} else if (cdCompareObj.Bottom > cdObj.Top && cdCompareObj.Bottom < cdObj.Bottom) {
			return true;
		}
	}
	
	return false;
}

function GetIeX(element) {
    var xPos = GetOffsetLeft(element);
    var tempElement = GetOffsetParent(element);
	
    while (tempElement != null) {
        xPos += GetOffsetLeft(tempElement);
		
		if (tempElement.tagName != "BODY") { 
			xPos -= tempElement.scrollLeft;
			
		}
		
        tempElement = GetOffsetParent(tempElement);
    }
	
    return xPos;
}

function GetIeY(element) {
    var yPos = GetOffsetTop(element);
    var tempElement = GetOffsetParent(element);

    while (tempElement != null) {
        yPos += GetOffsetTop(tempElement);

		if (tempElement.tagName != "BODY") {
			yPos -= tempElement.scrollTop;
		}
        tempElement = GetOffsetParent(tempElement);
    }
    return yPos;
}

//returns an object given its name as a string
function FindObj(n, d) {
  var p,i,x;  
  if (!d) d=document; 
  if ((p=n.indexOf("?"))>0 && parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; 
	n=n.substring(0,p);
  }
  if (!(x=d[n])&&d.all) x=d.all[n]; 
  for (i=0; !x && i < d.forms.length; i++) x=d.forms[i][n];
  for(i=0; !x && d.layers && i<d.layers.length; i++) x=FindObj(n,d.layers[i].document);
  if(!x && document.getElementById) x=document.getElementById(n); 
  return x;
}

//this function returns the position of an image
//coordinate should be supplied as 'x' or 'y'
function GetObjPositionLC(sName, sCoordinate, bScrollCoords){
	var oObj;

	if (typeof(sName) == "string") {
		oObj = FindObj(sName);
	} else if (typeof(sName) == "object") {
		oObj = sName;
	}

	if (document.layers) { //netscape
		return eval("theImage." + sCoordinate);
	} else { //DOM
		if (sCoordinate == 'x'){
			return GetIeX(oObj, bScrollCoords);
		} else {
			return GetIeY(oObj, bScrollCoords);
		}
	}
}

//given an object, returns the parent div tag (search tip layer)
function GetParentDiv(oObj, sAttributeName, sAttributeValue) {
	var oTemp = oObj;
	while (oTemp.parentNode) {
		if (oTemp.tagName == 'DIV') {
			if (sAttributeName && sAttributeValue) {
				if (GetAttributeEx(oTemp, sAttributeName) == sAttributeValue) {
					return oTemp;
				}
			} else {
				return oTemp;
			}
		} 
			
		oTemp = oTemp.parentNode;
	}
}

//given an object, returns the parent div tag (search tip layer)
function GetOffsetParent(oObj) {
	var oTemp = null;

	if (document.all) {
		oTemp = oObj.offsetParent;
	} else {
		if (oObj.offsetParent != oObj.parentNode && oObj.parentNode.tagName == "DIV") {
			oTemp = oObj.parentNode;
		} else {
			oTemp = oObj.offsetParent;
		}
	}

	if (oTemp != oObj) {
		return oTemp;
	} else {
		return null;
	}
}

//given an object, returns the parent div tag (search tip layer)
function GetOffsetTop(oObj) {
	if (document.all) {
		return oObj.offsetTop;
	} else {
		var oOffsetParent = GetOffsetParent(oObj);
		
		if (!oOffsetParent) {
			return 0;
		} else if (oOffsetParent.tagName == "DIV") {
			//if (oOffsetParent.style.overflow == "scroll") {
				//return (oObj.offsetTop - oOffsetParent.offsetTop) + 3;	
			//} else {
				return oObj.offsetTop - oOffsetParent.offsetTop;
			//}
		} else {
			return oObj.offsetTop;	
		}
	}
}

//given an object, returns the parent div tag (search tip layer)
function GetOffsetLeft(oObj) {
	if (document.all) {
		return oObj.offsetLeft;
	} else {
		var oOffsetParent = GetOffsetParent(oObj);
		
		if (!oOffsetParent) {
			return 0;
		} else if (oOffsetParent.tagName == "DIV") {
			//if (oOffsetParent.style.overflow == "scroll") {
				//return (oObj.offsetTop - oOffsetParent.offsetLeft) + 3;	
			//} else {
				return oObj.offsetLeft - oOffsetParent.offsetLeft;
			//}
		} else {
			return oObj.offsetLeft;	
		}
	}
}

//Get the exact position and dimension of any HTML element on the page
function GetObjectPosition(obj)
{
	if(!obj) return false;
	
	var iLeft = 0;
	var iTop = 0;
	var oTemp = obj;
	
	if (oTemp.offsetParent) {
		iLeft = oTemp.offsetLeft;
		iTop = oTemp.offsetTop;
		while (oTemp = oTemp.offsetParent)
		{
			iLeft += oTemp.offsetLeft;
			iTop += oTemp.offsetTop;
		}
	}
	this.top	= iTop;
	this.left 	= iLeft;
	this.bottom = this.top + parseInt(obj.offsetHeight);
	this.right	= this.left + parseInt(obj.offsetWidth);
	this.height	= this.bottom - this.top;
	this.width	= this.right - this.left;
}

//Original File Name: SelectionHandling.js
//Handles an array of checkboxes for a specific form
function GetCheckboxes(oForm)
{
	var aCheckboxes = new Array();

	if( oForm )
	{
		for( var i = 0; i < oForm.elements.length; i++ )
		{
			if( oForm.elements[i].type == 'checkbox')
			{
				if(oForm.elements[i].disabled == false)
				{
					aCheckboxes[aCheckboxes.length] = oForm.elements[i];
				}
			}
		}
	}
	
	return aCheckboxes;
}

function CheckAll(oForm)
{
	var aCheckboxes = GetCheckboxes(oForm);

	for( var i = 0; i < aCheckboxes.length; i++ )
	{
		aCheckboxes[i].checked = true;
	}
}

function UncheckAll(oForm)
{
	var aCheckboxes = GetCheckboxes(oForm);
	
	for( var i = 0; i < aCheckboxes.length; i++ )
	{
		aCheckboxes[i].checked = false;
	}
}

function GetSelectedCheckboxes(oForm)
{
	var aOutput = new Array();
	var aCheckboxes = GetCheckboxes(oForm);
	
	for( var i = 0; i < aCheckboxes.length; i++ )
	{
		if( aCheckboxes[i].checked )
			aOutput[aOutput.length] = aCheckboxes[i].value;
	}

	return aOutput;
}
function GetSelectedCheckboxesEx(oForm, exAttrName)
{
	var aOutput = new Array();
	var aCheckboxes = GetCheckboxes(oForm);
	
	for( var i = 0; i < aCheckboxes.length; i++ )
	{
		if( aCheckboxes[i].checked )
			aOutput[aOutput.length] = GetAttributeEx(aCheckboxes[i], exAttrName);
	}

	return aOutput;
}

//Original File Name: ModalDialog.js
//OpenModalDialog(sUrl, nWidth, nHeight, bScrollable, bResizable) //locks opener until dialog is released
//OpenDialog(sUrl, nWidth, nHeight, bScrollable, bResizable) //cleans itself up after leaving the opener page
//OpenWindow(sUrl, nWidth, nHeight, bScrollable, bResizable) //normal floating window

//To add additional parameters, use:
//DialogOptions.AddParam(sName, sValue)
var g_sModalWinName;
var g_bModalWinOpen;
var g_tmrModalWin;
var g_winMain;
var g_oOpener;
var fw_config_ImageDirectory = '/images';

window.SupportsModalDialogs = true;
window.RefreshAfterCloseModal = false;
window.IsModalWindow = false;

if (window.opener) {
	g_oOpener = window.opener;
}

function OpenModalDialog(sUrl, nWidth, nHeight, bScrollable, bResizable) {
	OpenDialog(sUrl, nWidth, nHeight, bScrollable, bResizable);
	//EAK 4/17/2007 made all modal dialog just be regular dialogs
	/*var winModal;
	
	//if this is netscape or AOL, open a normal window
	var bIsAOL = (navigator.appVersion.indexOf('AOL') != -1);
	var bIsNetscape = (document.layers && !document.all);
	
	if (bIsAOL || bIsNetscape) {
		OpenDialog(sUrl, nWidth, nHeight, bScrollable, bResizable);
	}

	var sFeatures = DialogOptions.GetString(nWidth, nHeight, bScrollable, bResizable);
	DialogOptions.Clear();
	
	//open the window
	try {
		winModal = window.open(sUrl, DialogOptions.WindowName, sFeatures);
	} catch (e) {
		
	}
	
	//detect popup blocking software
	if (!VerifyWindowOpened(winModal)) {
		return;
	}
	
	ModalEnableWindow(window, false);
	
	if (Browser.UserAgent == BROWSER_KONQUEROR) {
		ResizeWindow(nWidth, nHeight, winModal);
	}
	
	//set the global variables so we can reference this window from other functions
	g_sModalWinName = 'window.ModalWinRef'; //TODO clean up later
	g_bModalWinOpen = true;
	
	//return a reference to the window
	window.ModalWinRef = winModal;
	return winModal;*/
}

function ResizeWindow(nWidth, nHeight, oWindow) {
	nHeight = ModalGetHeight(nHeight);
	
	var nX = (screen.availWidth / 2) - (nWidth / 2);
	var nY = (screen.availHeight / 2) - (nHeight / 2);
	
	if (!oWindow) {
		oWindow = window;
	}
	
	if (oWindow.statusbar && window.statusbar.visible) {
		nHeight += 20;
	}
	
	oWindow.resizeTo(nWidth, nHeight);
	oWindow.moveTo(nX, nY);

	//HACK workaround for IE on WinXP SP2- IE doesnt resize properly the first time
	//also fix for safari
	if (IsWinXPSP2() || Browser.UserAgent == BROWSER_KONQUEROR || CheckBrowserOS(BROWSER_SAFARI)) {
		oWindow.setTimeout('window.resizeTo(' + nWidth + ', ' + nHeight + ');window.moveTo(' + nX + ', '+ nY + ');', 10);
	}
}

function ResizeWindowDontCenter(nWidth, nHeight, oWindow) {
	nHeight = ModalGetHeight(nHeight);

	if (!oWindow) {
		oWindow = window;
	}
	
	if (oWindow.statusbar && window.statusbar.visible) {
		nHeight += 20;
	}
	
	oWindow.resizeTo(nWidth, nHeight);
	
	//HACK workaround for IE on WinXP SP2- IE doesnt resize properly the first time
	if (IsWinXPSP2()) {
		oWindow.setTimeout('window.resizeTo(' + nWidth + ', ' + nHeight + ');', 10);
	}
}

function ModalDeadEnd(){
	try { //aol fix

		var winModal = window.ModalWinRef;
		//If the window already exists, Then refocus it
		if (winModal && !winModal.closed) {

			//workaround for netscape win98/ME bug
			if (document.all || (navigator.userAgent.indexOf('Windows NT') != -1)) {
				winModal.focus();
			} else {
				//occurs only on netscape  win98/ME
				setTimeout('eval(g_sModalWinName).focus();', 0);
			}
		//the window has been closed, or never has been opened- 
		} else {
			if (g_bModalWinOpen){
				//return the events to normal
				ModalEnableWindow(window, true);
				g_bModalWinOpen = false;
			}
		}
	} catch (e) {
		//alert(e.number);
	}
	return false;
}

function ModalEnableWindow(win, bDoEnable){
	var doc = win.document;
	var veilLayer = doc.getElementById('veilLayer');
	
	if (!veilLayer) {
		return;
	}

	//Netscape/Gecko browsers
	if (!win.document.all) {
		win.captureEvents(Event.CLICK | Event.MOUSEDOWN | Event.MOUSEUP | Event.FOCUS | Event.UNLOAD);
	}

	//add global event hanlders
	win.onfocus = bDoEnable ? null : ModalDeadEnd;
	win.onresize = bDoEnable ? null : ModalDeadEnd;
	win.onresizestart = bDoEnable ? null : ModalDeadEnd;
	win.onscroll = bDoEnable ? null : ModalDeadEnd;
	
	try {
		doc.body.onclick = bDoEnable ? null : ModalDeadEnd;
		doc.body.onselect = bDoEnable ? null : ModalDeadEnd;
		doc.body.onselectstart = bDoEnable ? null : ModalDeadEnd;
		doc.body.oncontextmenu = bDoEnable ? null : ModalDeadEnd;
	
		//win.onunload = bDoEnable ? null : ModalHandleErrors;

		veilLayer.style.display = bDoEnable ? 'none' : 'block';
		veilLayer.style.width = doc.body.scrollWidth-1;
		veilLayer.style.height = doc.body.scrollHeight-1;

	} catch (e) {
		return; //the document may have been closed
	}
	
	if (bDoEnable){
		win.focus();
	}
}

//if the user finds a way to unload the host page, get rid of the popup window too.
function ModalHandleErrors(){
	try {
		var winModal = window.ModalWinRef;
		if (winModal && !winModal.closed){
			winModal.close();
		}
		ModalEnableWindow(window, true);
	} catch (e) {
		//alert('error caught');
	}
}

//when the modal window is closed, this is called in IE
function ModalOnClose(){
	try {
		if (g_oOpener) {
			ModalEnableWindow(g_oOpener, true);
		}
	} catch (e) {
		//do nothing
	}

	try {
		if (g_oOpener.RefreshAfterCloseModal){
			//refresh the window, but dont reload- they may have post data
			if (g_oOpener.ProgressBar) {
				g_oOpener.ProgressBar.Show('Loading...');
			}	
			g_oOpener.document.location.reload(true);
		}
	} catch (e) {
		//alert('error- finish modal: ' + e.description);
	}
}

function ModalReleaseOpenerOnClose(){
	//attach the IE unload event
	window.onunload = ModalOnClose;
	if (!document.all) {
		window.captureEvents(Event.UNLOAD);
	}
}

function ModalAllowRefresh() {
	try {
		opener.RefreshAfterCloseModal = false;
	} catch (e) {
		//do nothing
	}
	RefreshAfterCloseModal = false;
	window.onunload = null;
}

function ModalWriteVeil(){
	document.write('<div id="veilLayer" style="position:absolute; left:1px; top:1px; width:1px; height:1px; z-index:20; display:none; background-image: url(' + fw_config_ImageDirectory + '/spacer.gif); layer-background-image: url(' + fw_config_ImageDirectory + '/spacer.gif)">');
	document.write('<img src="' + fw_config_ImageDirectory + '/spacer.gif" alt="" name="veilImageBlock" id="veilImageBlock" width="100%" height="100%" border="0" style="cursor: not-allowed;" onClick="ModalDeadEnd();return false;" galleryimg="no">');
	document.write('</div>');
}

//Modeless dialogs
function OpenWindow(sUrl, nWidth, nHeight, bScrollable, bResizable) {
	OpenDialog(sUrl, nWidth, nHeight, bScrollable, bResizable, true);
}

function OpenDialog(sUrl, nWidth, nHeight, bScrollable, bResizable, bLeaveOpen) {
	if (!bLeaveOpen) {
		bLeaveOpen = false;
	}
	
	//build feature string
	var sFeatures = DialogOptions.GetString(nWidth, nHeight, bScrollable, bResizable);
	DialogOptions.Clear();

	if (!g_winMain || g_winMain.closed) {
		try {
			g_winMain = window.open(sUrl, DialogOptions.WindowName, sFeatures);
		} catch (e) {
			//do nothing
		}
		//detect popup blocking software
		if (!VerifyWindowOpened(g_winMain)) {
			return;
		}
	} else {
		// bring existing window to focus
		g_winMain.close();
		g_winMain = window.open(sUrl, DialogOptions.WindowName, sFeatures);
		g_winMain.focus();
	}
	
	if (Browser.UserAgent == BROWSER_KONQUEROR) {
		ResizeWindow(nWidth, nHeight, g_winMain);
	}
	
	if (!bLeaveOpen) {
		if (!document.all) {
			window.captureEvents(Event.UNLOAD);
		}
		window.onunload = CleanDialog;
	}
}

function CleanDialog() {
	if (g_winMain) {
		g_winMain.close();
	}
}

function DialogOptionsManager() {
	this.ParamArray = new Array();
	this.ParamArrayValues = new Array();
	this.DoPopupBlockerMessage = true;
	this.WindowName = "_blank";
	
	this.AddParam = function(sName, sValue) {
		var nIndex = this.ParamArray.length;
		
		for (var i=0; i<this.ParamArray.length; i++) {
			if (this.ParamArray[i] == sValue) {
				nIndex = i;
				break;
			}
		}
		
		this.ParamArray[nIndex] = sName;
		this.ParamArrayValues[nIndex] = sValue;
	}
	
	this.GetString = function(nWidth, nHeight, bScrollable, bResizable) {
		nHeight = ModalGetHeight(nHeight);
		
		if (nWidth > screen.availWidth){
			nWidth = screen.availWidth;
		}
		if (nHeight > screen.availHeight){
			nHeight = screen.availHeight;
		}

		if (typeof(bScrollable) == "undefined") {
			bScrollable = true;
		}
		if (typeof(bResizable) == "undefined") {
			bResizable = true;
		}
		
		//open the window at the center of the screen by default
		var nX = (screen.availWidth / 2) - (nWidth / 2);
		var nY = (screen.availHeight / 2) - (nHeight / 2);
		
		//build feature string
		var sFeatures = 'width=' + nWidth + ',';
		sFeatures += 'height=' + nHeight + ',';
		sFeatures += 'screenX=' +  nX + 'px,';
		sFeatures += 'screenY=' +  nY + 'px,';
		sFeatures += 'top=' +  nY + 'px,';
		sFeatures += 'left=' +  nX + 'px,';
		sFeatures += 'status=no,';
		sFeatures += 'scrollbars=' + (bScrollable ? 'yes' : 'no') + ',';
		sFeatures += 'resizable=' + (bResizable ? 'yes' : 'no');
		
		
		for (var i=0; i<this.ParamArray.length; i++) {
			sFeatures += ',' + this.ParamArray[i] + '=' + this.ParamArrayValues[i];
		}

		return sFeatures;
	}
	
	this.Clear = function() {
		this.ParamArray = new Array();
		this.AddParam('status', 'no');
		this.AddParam('titlebar', 'no');
	}
	
	this.Clear();
}

function VerifyWindowOpened(oWin) {
	if (!oWin || oWin.closed) {
		if (DialogOptions.DoPopupBlockerMessage) {
			alert('This feature requires a dialog which was blocked by a popup blocking program in your browser. You must disable popup blocking for this site in order to use this feature.');
		}
		return false;
	}
	
	return true;
}

function IsWinXPSP2() {
	if (Browser.UserAgent == BROWSER_IE && Browser.OS == OS_WINXP && Browser.SP == 2) {
		return true;
	}
	
	return false;
}

//on winXP SP2, returns a slightly larger window size to compensate for the status bar
function ModalGetHeight(nHeight) {
	if (IsWinXPSP2()) {
		return nHeight + 20;
	} else {
		return nHeight;
	}
}

//*******************************************************
//Set global properties and event handlers
//*******************************************************

var DialogOptions = new DialogOptionsManager();

if (window.opener){
	try {
		if (window.opener.opener) {
			//alert('is modal');
			if (window.opener.opener.g_sModalWinName) {
				window.IsModalWindow = true;
			}
		}
		
		if (window.opener) {
			if (window.opener.g_sModalWinName) {
					//alert(window.opener.g_sModalWinName);
				//if (window.opener.g_sModalWinName == window.name) {
					window.IsModalWindow = true;
				//}
			}
		}
	} catch (e) {
		//alert('custom error: ' + e.description);
	}
}

if (window.IsModalWindow){
	window.focus();
	ModalEnableWindow(opener, false);
	ModalReleaseOpenerOnClose();
}

ModalWriteVeil();

//Original File Name: validation.js
/*
FormValidator class

description
**********************************
Validates a form based on custom attributes in HTML tags.

Constructor
**********************************
new FormValidator(frm)- frm is a reference to an HTML form object

Methods
**********************************
Validate()- boolean- performs internal validation and returns true if validation passed.
IsOneFieldFilled() - boolean- true if one field is filled (not counting fields with the "dontvalidate" attribute set true)

Properties
**********************************
IsError- boolean- returns true if there was an error found in the last Call to Validate()
ErrorMessage- string- contains an error message from the last Call to Validate()
ErrorField- object reference- contains a reference to the field which caused the validation to fail

HTML attribute reference
**********************************
displayname: The name of the field as it should appear in error messages.
required: if true, the field must be filled before the form will validate.
validation: a semicolon seperated list of either validation types or custom function names which adhere to the
	"Validator function interface" described below. Validation types are:
		"integer"
		"number"
		"alphanumeric"
		"date"
		"phone"
		"zip"
		"email"
		"creditcard"
errormessage[num]: The custom error message that will display if the cooresponding validator fails. 
	1 based- i.e. errorMessage2="error message" will be returned if the second validator function fails.
	Error messages should include the strings "#field#" and "#value#" where the cooresponding field or value
	should be displayed.
condition: a javascript expression which must return true for the field to pass validation.
conditionerror: If the "contition" attribute returns false, this message is returned.
dontvalidate: Wont consider the field when Validate() is called
emptyvalue: If the selected value matches this emptyvalue attribute, the field is considered empty for the purposes of validation.

Validator function interface
**********************************
Validation functions must implement the following interface:
function [function name](sValue, bGetMessage)

if bGetMessage is true, the function should return a specific error message. Error messages should use the #field# and #value# convention. If it is false or null, the function should return true or false.

Usage example
**********************************
var oValidator = new FormValidator(document.form1);
	
if (!oValidator.Validate()) {
	alert(oValidator.ErrorMessage);
	oValidator.ErrorField.focus();
	return false;
} else {
	document.form1.submit();
}

*/


var MAX_CHARS_TEXTAREA = 102399;
var MIN_CPP_DATE = new Date('1/1/1970 12:00:00 AM');
var MAX_CPP_DATE = new Date('1/19/2038 3:14:07 AM');

var ERR_MSG_VALIDATE_INTEGER = "Please enter a valid integer for the field \"#field#\".";
var ERR_MSG_VALIDATE_NUMBER = "Please enter a valid number for the field \"#field#\".";
var ERR_MSG_VALIDATE_ALPHANUMERIC = "The field \"#field#\" must be alphanumeric.";
var ERR_MSG_VALIDATE_DATE = "Please enter a valid date for the field \"#field#\" in the format " + new Date().format('mmm/dd/yyyy') + ".";
var ERR_MSG_VALIDATE_CPP_DATE = "Please enter a date for the field \"#field#\" which is after " + MIN_CPP_DATE.format("month dd, yyyy") + " and before " + MAX_CPP_DATE.format("month dd, yyyy") + ".";
var ERR_MSG_VALIDATE_ZIP = "Please enter a valid zip/postal code for the field \"#field#\".";
var ERR_MSG_VALIDATE_EMAIL = "The email address \"#value#\" is not valid. Please check it before you continue.";
var ERR_MSG_VALIDATE_WWW = "The website address \"#value#\" is not valid. Please check it before you continue.";
var ERR_MSG_VALIDATE_CREDITCARD = "The credit card number \"#value#\" is not valid. Please enter a valid credit card number.";
var ERR_MSG_VALIDATE_SECURITYCODE = "The security code \"#value#\" is not valid. Please enter a valid security code.";
var ERR_MSG_VALIDATE_TEXTAREA = "The field \"#field#\" contains more than " + MAX_CHARS_TEXTAREA + " characters, which is the limit allowed. Please shorten the entry in this field.";
var ERR_MSG_VALIDATE_PHONE = "The phone number \"#value#\" is not valid. Please enter a valid phone number, e.g. 555-255-4896.";

function ValidateFormData(frm) {
	var oValidator = new FormValidator(frm);
		
	if (!oValidator.Validate()) {
		alert(oValidator.ErrorMessage);
		oValidator.ErrorField.focus();
		return false;
	} else return true;
}

function FormValidator(frm) {
	this.IsError = false;
	this.ErrorMessage = "";
	this.ErrorField = null;
	
	var m_bOneFieldFilled = null;
	var ERR_TYPE_REQUIRED = -1;
	var ERR_TYPE_CUSTOM = 0;
	var ERR_TYPE_CONDITIONAL = -2;
	
	this.Validate = function() { //public
		var fValidatorRef;
		var bIsValid, bEmpty, bRequired;
		var i, j;
		var arrCustomValidators;
		var sValue;
		var sCondition;
		var sMessage;
		var bIsEnabled;
		var bDoValidate;
		var sDefaultValue;
		
		m_bOneFieldFilled = false;

		this.IsError = false;
		this.ErrorMessage = '';
		this.ErrorField = null;

		for (i=0; i<frm.elements.length; i++) {
			
			if (frm.elements[i].tagName == 'FIELDSET') {
				continue;
			}
			
			bIsValid = false;
			sValue = GetFieldValue(frm.elements[i]);
			bRequired = GetBoolean(GetAttributeEx(frm.elements[i], "required"));
			bIsEnabled = !frm.elements[i].disabled && frm.elements[i].style.display != 'none';
			bDoValidate = !GetBoolean(GetAttributeEx(frm.elements[i], "dontvalidate")) && (frm.elements[i].type != 'hidden' || GetAttributeEx(frm.elements[i], "dontvalidate") == "false") && frm.elements[i].type != 'button' && frm.elements[i].type != 'submit' && frm.elements[i].type != 'image';
			sDefaultValue = GetAttributeEx(frm.elements[i], "emptyvalue");
			
			sMessage = "";
			bEmpty = (sValue == sDefaultValue);
			if (!bEmpty && bDoValidate && bIsEnabled) {
				m_bOneFieldFilled = true;
			}

			//if the field is required, validate that it isnt empty
			if (bRequired && bIsEnabled) {
				if (sValue == "") {
					SetError(frm.elements[i], ERR_TYPE_REQUIRED, this);
					return false;
				}
			}
			
			//standard and custom validation
			if (GetAttributeEx(frm.elements[i], "validation") != "" && (!bEmpty || bRequired) && bIsEnabled) {
				//support multiple validation functions
				arrCustomValidators = GetAttributeEx(frm.elements[i], "validation").split(";");
				
				for (j=0; j<arrCustomValidators.length; j++) {
					//the validation attribute can contain either validator keys or function names
					fValidatorRef = eval(GetValidatorFromKey(arrCustomValidators[j]));
					if (!fValidatorRef(sValue)) {
						//check and see if the validator function implements the bGetMessage argument interface
						sMessage = fValidatorRef(sValue, true)
						if (sMessage) {
							SetError(frm.elements[i], j+1, this, sMessage);
						} else {
							SetError(frm.elements[i], j+1, this);
						}
						
						return false;
					} 
				}
			}
			
			//conditional validation
			if (GetAttributeEx(frm.elements[i], "condition") != "" && (!bEmpty || bRequired) && bIsEnabled) {
				//support multiple validation functions
				sCondition = GetAttributeEx(frm.elements[i], "condition").replace(/this/gi, "frm.elements[i]");

				if (!eval(sCondition)) {
					SetError(frm.elements[i], ERR_TYPE_CONDITIONAL, this);
					return false; 
				}
			}
		}
		
		return true;
	}
	
	this.IsOneFieldFilled = function() {
		return m_bOneFieldFilled;
	}
	
	var SetError = function(oObj, nMessageNum, oParent, sOverrideMessage) { //private
		var bCustom = true;

		if (nMessageNum == ERR_TYPE_REQUIRED || nMessageNum == ERR_TYPE_CONDITIONAL) {
			bCustom = false;
		}
		
		oParent.ErrorField = oObj;
		oParent.IsError = true;
		
		//use the error message wich cooresponds to the validation function from the errormessage[num] attribute
		if (GetAttributeEx(oObj, "errorMessage" + nMessageNum) != "" && bCustom) {
			//support dynamic error messages if they are enclosed in parens ()
			if (oObj.getAttribute("errorMessage" + nMessageNum).indexOf("(") == 0) {
				oParent.ErrorMessage = ProcessMessage(oObj, eval(oObj.getAttribute("errorMessage" + nMessageNum)));
			} else {
				oParent.ErrorMessage = ProcessMessage(oObj, oObj.getAttribute("errorMessage" + nMessageNum));
			}
		//use the error message wich cooresponds to the validation function from the errormessage attribute
		} else if (GetAttributeEx(oObj, "errorMessage") != "" && bCustom) {
			oParent.ErrorMessage = ProcessMessage(oObj, GetAttributeEx(oObj, "errorMessage"));
		//use the error message from the functions bGetMessage argument interface
		} else if (sOverrideMessage && bCustom) {
			oParent.ErrorMessage = ProcessMessage(oObj, sOverrideMessage);
		//use the conditionmessage attribute
		} else if (GetAttributeEx(oObj, "conditionMessage") != "" && nMessageNum == ERR_TYPE_CONDITIONAL) {
			oParent.ErrorMessage = ProcessMessage(oObj, GetAttributeEx(oObj, "conditionMessage"));
		//use the "required"/default message
		} else {
			if (oObj.type.toLowerCase().indexOf('select') != -1) {
				oParent.ErrorMessage = "Please select a value for the field \"" + GetAttributeEx(oObj, "displayName") + "\".";
			} else if (oObj.type.toLowerCase() == 'checkbox' || oObj.type.toLowerCase() == 'radio') {
				oParent.ErrorMessage = "Please check the field \"" + GetAttributeEx(oObj, "displayName") + "\".";	
			} else {
				oParent.ErrorMessage = "Please fill in the field \"" + GetAttributeEx(oObj, "displayName") + "\".";
			}
		}
	}
	
	var ProcessMessage = function(oObj, sMessage) { //private
		return sMessage.replace(/\#field\#/gi, GetAttributeEx(oObj, "displayName").trim()).replace(/\#value\#/gi, GetFieldValue(oObj));
	}
	
	var GetFieldValue = function(oObj) { //private
		if (oObj.type.toLowerCase().indexOf('text') != -1 || oObj.type.toLowerCase().indexOf('password') != -1 || oObj.type.toLowerCase().indexOf('hidden') != -1) {
			return Trim(oObj.value);
		} else if (oObj.type.toLowerCase().indexOf('select') != -1) {
			return GetSelectValue(oObj);
		} else if (oObj.type.indexOf('radio') != -1) {
			return GetRadioValue(oObj);
		} else if (oObj.type == 'checkbox') {
			return oObj.checked;
		}
	}
	
	var GetValidatorFromKey = function(sKey) {
		return m_arrValidatorMap[sKey.toLowerCase()] ? m_arrValidatorMap[sKey.toLowerCase()] : sKey;
	}
	
	var m_arrValidatorMap = {
		"integer" : "ValidateInteger",
		"number" : "ValidateNumber",
		"alphanumeric" : "ValidateAlphanumeric",
		"date" : "ValidateDate",
		"cppdate" : "ValidateCppDate",
		"phone" : "ValidatePhone",
		"zip" : "ValidateZip",
		"email" : "ValidateEmail",
		"multiemail" : "ValidateMultiEmail",
		"creditcard" : "ValidateCreditCard",
		"securitycode" : "ValidateSecurityCode",
		"textarea" : "ValidateTextAreaLength",
		"website" : "ValidateWebsite"
	}
}



//a collection of functions used to validate form input
function IsLetter(c) {
	return ( ((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")) )
}

function IsDigit(c) {   
	return ((c >= "0") && (c <= "9"))
}

function IsInteger (s) {
    if(s == null || s.length == 0) return false;

    for (var i = 0; i < s.length; i++) {
        if (!IsDigit(s.charAt(i))) return false;
    }
    return true;
}

function IsLetterOrDigit(c) {   
	return (IsLetter(c) || IsDigit(c))
}

function ValidateAlphanumeric(sStr, bGetMessage) {   
	var i;
	var validated = true;
    if (sStr.length < 1){
		return bGetMessage ? "" : true;
	}
    for (i = 0; i<sStr.length; i++){   
        c = sStr.charAt(i);
        if (!(IsLetter(c) || IsDigit(c) || (c == '_'))){  //allows underscores as well
        	return bGetMessage ? ERR_MSG_VALIDATE_ALPHANUMERIC : false;
		}
    }
    return bGetMessage ? "" : true;
}

function ValidateDate(sDate, bGetMessage) {
    //Returns true if value is a date format or is NULL
    //otherwise returns false	

    if (sDate.length == 0) {
        return bGetMessage ? "" : true;
	}

    //Returns true if value is a date in the mm/dd/yyyy format
	var nSplit = sDate.indexOf('/');

	if (nSplit == -1 || nSplit == sDate.length) {
		return bGetMessage ? ERR_MSG_VALIDATE_DATE : false;
	}

    var sMonth = sDate.substring(0, nSplit);

	if (sMonth.length == 0) {
        return bGetMessage ? ERR_MSG_VALIDATE_DATE : false;
	}

	nSplit = sDate.indexOf('/', nSplit + 1);

	if (nSplit == -1 || (nSplit + 1 ) == sDate.length) {
		return bGetMessage ? ERR_MSG_VALIDATE_DATE : false;
	}

    var sDay = sDate.substring((sMonth.length + 1), nSplit);

	if (sDay.length == 0) {
        return bGetMessage ? ERR_MSG_VALIDATE_DATE : false;
	}

	var sYear = sDate.substring(nSplit + 1);

	if (!ValidateInteger(sMonth)) {//check month
		return bGetMessage ? ERR_MSG_VALIDATE_DATE : false;
	} else if (!ValidateRange(sMonth, 1, 12)) {//check month
		return bGetMessage ? ERR_MSG_VALIDATE_DATE : false;
	} else if (!ValidateInteger(sYear)) {//check year
		return bGetMessage ? ERR_MSG_VALIDATE_DATE : false;
	} else if (!ValidateRange(sYear, 0, 9999)) {//check year
		return bGetMessage ? ERR_MSG_VALIDATE_DATE : false;
	} else if (!ValidateInteger(sDay)) {//check day
		return bGetMessage ? ERR_MSG_VALIDATE_DATE : false;
	} else if (!ValidateDay(sYear, sMonth, sDay)) {// check day
		return bGetMessage ? ERR_MSG_VALIDATE_DATE : false;
	} else {
		return bGetMessage ? "" : true;
	}
}

function ValidateDay(nYear, nMonth, nDay) {
	var nMaxDay = 31;

	if (nMonth == 4 || nMonth == 6 || nMonth == 9 || nMonth == 11) {
		nMaxDay = 30;
	} else if (nMonth == 2) {
		if (nYear % 4 > 0) {
			nMaxDay =28;
		} else if (nYear % 100 == 0 && nYear % 400 > 0) {
			nMaxDay = 28;
		} else {
			nMaxDay = 29;
		}
	}

	return ValidateRange(nDay, 1, nMaxDay); //check day
}

function ValidateInteger(sInteger, bGetMessage) {
    //Returns true if value is a number or is NULL
    //otherwise returns false	
    if (sInteger.length == 0) {
        return bGetMessage ? "" : true;
	}
	
	if (sInteger.indexOf('.') != -1) {
		return bGetMessage ? ERR_MSG_VALIDATE_INTEGER : false;
	}

    //The first character can be + -  blank or a digit.
	var sChar = sInteger.indexOf('.')
	
    if (sChar < 1) {
		if (!ValidateNumber(sInteger)) {
			return bGetMessage ? ERR_MSG_VALIDATE_INTEGER : false;
		}
		return bGetMessage ? "" : true;
    } else {
		return bGetMessage ? ERR_MSG_VALIDATE_INTEGER : false;
	}
}

function ValidateNumberRange(sNumber, nMinValue, nMaxValue) {
    if (nMinValue != null) {
        if (sNumber < nMinValue) {
			return false;
		}
	}

    if (nMaxValue != null) {
		if (sNumber > nMaxValue) {
			return false;
		}
	}
	
    return true;
}

function ValidateNumber(sNumber, bGetMessage) {
    //Returns true if value is a number or is NULL
    //otherwise returns false	

    if (sNumber.length == 0) {
        return bGetMessage ? "" : true;
	}
    //Returns true if value is a number defined as
    //   having an optional leading + or -.
    //   having at most 1 decimal point.
    //   otherwise containing only the characters 0-9.
	var sStartFormat = " .+-0123456789";
	var sNumberFormat = " .0123456789";
	var sChar;
	var bIsDecimal = false;
	var bIsTrailingBlank = false;
	var bIsDigits = false;

    //The first character can be + - .  blank or a digit.
	sChar = sStartFormat.indexOf(sNumber.charAt(0))
	
    //Was it a decimal?
	if (sChar == 1) {
	    bIsDecimal = true;
	} else if (sChar < 1) {
		return bGetMessage ? ERR_MSG_VALIDATE_NUMBER : false;
	}
		
	//was it a sole "-"?
	if (sNumber == '-' || sNumber == '+') {
		return bGetMessage ? ERR_MSG_VALIDATE_NUMBER : false;
	}
        
	//Remaining characters can be only . or a digit, but only one decimal.
	for (var i=1; i<sNumber.length; i++) {
		sChar = sNumberFormat.indexOf(sNumber.charAt(i))
		if (sChar < 0) {
			return bGetMessage ? ERR_MSG_VALIDATE_NUMBER : false;
		} else if (sChar == 1) {
			if (bIsDecimal) {		// Second decimal.
				return bGetMessage ? ERR_MSG_VALIDATE_NUMBER : false;
			} else {
				bIsDecimal = true;
			}
		} else if (sChar == 0) {
			if (bIsDecimal || bIsDigits) {	
				bIsTrailingBlank = true;
			}
        // ignore leading blanks
		} else if (bIsTrailingBlank) {
			return bGetMessage ? ERR_MSG_VALIDATE_NUMBER : false;
		} else {
			bIsDigits = true;
		}
	}	

    return bGetMessage ? "" : true;
}

function ValidateRange(sNumber, nMinValue, nMaxValue) {
    //If value is in range Then return true else return false
	if (sNumber.length == 0) {
        return true;
	}

    if (!ValidateNumber(sNumber)) {
		return false;
	} else {
		return (ValidateNumberRange((eval(sNumber)), nMinValue, nMaxValue));
	}
	
	return true;
}

function ValidatePhone(sPhoneNumber, bGetMessage) {
    if (sPhoneNumber.length == 0) {
        return bGetMessage ? "" : true;
	}
		
    if (sPhoneNumber.length != 12) {
        return bGetMessage ? ERR_MSG_VALIDATE_PHONE : false;
	}
	// check if first 3 characters represent a valid area code
    if (!ValidateNumber(sPhoneNumber.substring(0,3))) {
		return bGetMessage ? ERR_MSG_VALIDATE_PHONE : false;
    } else if (!ValidateNumberRange((eval(sPhoneNumber.substring(0,3))), 100, 1000)) {
		return bGetMessage ? ERR_MSG_VALIDATE_PHONE : false;
	}

	// check if area code/exchange separator is either a'-' or ' '
	if (sPhoneNumber.charAt(3) != "-" && sPhoneNumber.charAt(3) != " ") {
        return bGetMessage ? ERR_MSG_VALIDATE_PHONE : false;
	}

	// check if  characters 5 - 7 represent a valid exchange
    if (!ValidateNumber(sPhoneNumber.substring(4,7))) {
		return bGetMessage ? ERR_MSG_VALIDATE_PHONE : false;
    } else if (!ValidateNumberRange((eval(sPhoneNumber.substring(4,7))), 100, 1000)) {
		return bGetMessage ? ERR_MSG_VALIDATE_PHONE : false;
	}
	
	// check if exchange/number separator is either a'-' or ' '
	if (sPhoneNumber.charAt(7) != "-" && sPhoneNumber.charAt(7) != " ") {
        return bGetMessage ? ERR_MSG_VALIDATE_PHONE : false;
	}

	// make sure last for digits are a valid integer
	if (sPhoneNumber.charAt(8) == "-" || sPhoneNumber.charAt(8) == "+") {
        return bGetMessage ? ERR_MSG_VALIDATE_PHONE : false;
	} else {
		if (!ValidateInteger(sPhoneNumber.substring(8,12))) {
			return bGetMessage ? ERR_MSG_VALIDATE_PHONE : false;
		}
		return bGetMessage ? "" : true;
	}
}

function ValidateZip(sZip, bGetMessage) {
    if (sZip.length == 0) {
        return bGetMessage ? "" : true;
	}
		
    if (sZip.length != 5 && sZip.length != 10) {
        return bGetMessage ? ERR_MSG_VALIDATE_ZIP : false;
	}

	// make sure first 5 digits are a valid integer
	if (sZip.charAt(0) == "-" || sZip.charAt(0) == "+") {
        return bGetMessage ? ERR_MSG_VALIDATE_ZIP : false;
	}
	if (!ValidateInteger(sZip.substring(0,5))) {
		return bGetMessage ? ERR_MSG_VALIDATE_ZIP : false;
	}

	if (sZip.length == 5) {
		return bGetMessage ? "" : true;
	}
	
	// check if separator is either a'-' or ' '
	if (sZip.charAt(5) != "-" && sZip.charAt(5) != " ") {
        return bGetMessage ? ERR_MSG_VALIDATE_ZIP : false;
	}

	// check if last 4 digits are a valid integer
	if (sZip.charAt(6) == "-" || sZip.charAt(6) == "+") {
        return bGetMessage ? ERR_MSG_VALIDATE_ZIP : false;
	}

	if (!ValidateInteger(sZip.substring(6,10))) {
		return bGetMessage ? ERR_MSG_VALIDATE_ZIP : false;
	}
	return bGetMessage ? "" : true;
}

function ValidateCreditCard(sCreditCardNum, bGetMessage) {
	var sWhiteSpace = " -";
	var sCcNumParsed = "";
	var sChar;

    if (sCreditCardNum.length == 0) {
        return bGetMessage ? "" : true;
	}
	
	// remove white space
	for (var i = 0; i < sCreditCardNum.length; i++) {
		sChar = sWhiteSpace.indexOf(sCreditCardNum.charAt(i));
		if (sChar < 0) {
			sCcNumParsed += sCreditCardNum.substring(i, (i + 1));
		}
	}	

	// if all white space return error
    if (sCcNumParsed.length == 0) {
        return bGetMessage ? ERR_MSG_VALIDATE_CREDITCARD : false;
	}
	 	
	// make sure number is a valid integer
	if (sCcNumParsed.charAt(0) == "+") {
        return bGetMessage ? ERR_MSG_VALIDATE_CREDITCARD : false;
	}

	if (!ValidateInteger(sCcNumParsed)) {
		return bGetMessage ? ERR_MSG_VALIDATE_CREDITCARD : false;
	}

	var bIsDoubleDigit = (sCcNumParsed.length % 2 == 1) ? false : true;
	var nCheckDigit = 0;
	var nTempDigit;

	for (var i=0; i<sCcNumParsed.length; i++) {
		nTempDigit = eval(sCcNumParsed.charAt(i));

		if (bIsDoubleDigit) {
			nTempDigit *= 2;
			nCheckDigit += (nTempDigit % 10);

			if ((nTempDigit / 10) >= 1.0) {
				nCheckDigit++;
			}

			bIsDoubleDigit = false;
		} else {
			nCheckDigit += nTempDigit;
			bIsDoubleDigit = true;
		}
	}	
	
	for (i=0; i<sCcNumParsed.length; i++) {
    	if (isNaN(sCcNumParsed.charAt(i))) {
            return bGetMessage ? ERR_MSG_VALIDATE_CREDITCARD : false;
        }
  	}
	
	if ((nCheckDigit % 10) != 0) {
		return bGetMessage ? ERR_MSG_VALIDATE_CREDITCARD : false;
	}
	return bGetMessage ? "" : true;

}

function ValidateSecurityCode(sSecurityCode, bGetMessage) {
    if(sSecurityCode.search(/^\d{3,4}$/) == -1) {
		return bGetMessage ? ERR_MSG_VALIDATE_SECURITYCODE : false;
    }
	return bGetMessage ? "" : true;
}
 
function ValidateEmail(sEmail, bGetMessage) {
	var regExpObj = /^([a-zA-Z0-9_\+\-\.\']+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/  //'
	if (sEmail.search(regExpObj) != 0) {
		return bGetMessage ? ERR_MSG_VALIDATE_EMAIL : false;
	}
	return bGetMessage ? "" : true;
}

function ValidateMultiEmail(sEmailList, bGetMessage) {
	var arrEmails
	if (sEmailList.indexOf(',') != -1) {
		arrEmails = sEmailList.split(',');
	} else if (sEmailList.indexOf(';') != -1) {
		arrEmails = sEmailList.split(';');
	} else {
		arrEmails = sEmailList.split(',');
	}
	
	for (var i=0; i<arrEmails.length; i++) {
		if (!ValidateEmail(arrEmails[i].trim())) {
			return bGetMessage ? ERR_MSG_VALIDATE_EMAIL.replace('#value#', arrEmails[i].trim()) : false;
		}
	}
	
	return bGetMessage ? "" : true;
}

function ValidateWebsite(sWeb, bGetMessage) {
	var regExpObj = /^(http\:\/\/)?(?:[a-zA-Z0-9\-]+\.){0,5}[a-zA-Z0-9\-]{2,}\.[a-zA-Z]{2,4}(\/\S*)?$/;
	if (sWeb.search(regExpObj) != 0) {
		return bGetMessage ? ERR_MSG_VALIDATE_WWW : false;
	}
	return bGetMessage ? "" : true;
}

function ValidateTextAreaLength(sStr, bGetMessage){
 	if (sStr.length > MAX_CHARS_TEXTAREA){
 		return bGetMessage ? ERR_MSG_VALIDATE_TEXTAREA : false;
	} else {
		return true;
	}
}

function ValidateLength(sStr, object_length){
	if (sStr.length == object_length){
    	return true;
	} else {
    	return false;
	}
}

function ValidateBadCharArray(sStr, arrBadChars){
	for (var i=0; i<arrBadChars.length; i++){
		if (sStr.indexOf(arrBadChars[i]) != -1) {
			return false;
		}
	}
	return true;
}

function ValidateCppDate(sStr, bGetMessage){
 	if (ValidateDate(sStr, false)) {
		//Y2K compatibility- assume "03" date is "2003"
		var arrDate = sStr.split("/");
		if (arrDate[2]) {
			if (parseInt(arrDate[2]) < 1900) {
				arrDate[2] = "20" + arrDate[2]
				sStr = arrDate.join("/");
			}
		}
		
		var dDate = new Date(sStr);
		var dMinDate = MIN_CPP_DATE;
		var dMaxDate = MAX_CPP_DATE;
		if (dDate > dMinDate && dDate < dMaxDate) {
			return bGetMessage ? "" : true;
		}
	}
	return bGetMessage ? ERR_MSG_VALIDATE_CPP_DATE : false;
}

//Original File Name: validation_query.js
//this file contains methods for validating query fields
//checks for punctuation, undesired booleans, and orgs.

var VF_URL_DOMAINS_ONLY = "Only '.com', '.org', '.net', '.ca' top level domains are searchable by using the field \"#field#\".";
var VF_NO_BOOLEAN_EXPRESSIONS = "Boolean expressions such as \"OR\" or \"AND\" are not allowed in the field \"#field#\".";
var VF_NO_COMMA_BOOL = "Commas and boolean expressions such as \"OR\" or \"AND\" are not allowed in the field \"#field#\".";
var VF_NO_DOUBLE_QUOTES = "Double quotes are not allowed in the field \"#field#\".";
var VF_NO_WILDCARDS = "Wildcard characters (*,%) are not allowed in the field \"#field#\".";
var VF_NO_WILDCARDS_TRY_BEGINSWITH = "\r\nTry selecting \"Begins with\" or another option from the \"Match\" dropdown to the left in the field.";
var VF_NO_PARENS = "Parentheses are not allowed in the field \"#field#\".";
var VF_NO_COMMA = "Commas are not allowed in the field \"#field#\".\r\n";
var VF_NO_COMMA_REMOVE = "\r\nOtherwise, please remove the comma from the field.";
var VF_INVALID_DATA = "Invalid data";
var VF_CONTINUE_MESSAGE = "Please correct this before continuing.";
var VF_NO_LEADING_HYPHEN = "Hyphens are not allowed at the beginning of the field \"#field#\".";
var VF_NO_CHEVRONS = "Chevrons (<,>) are not allowed in the field \"#field#\".";
var VF_NO_NOT_LEADING_COMPANYDESC = "\"NOT\" is not allowed at the beginning of the field \"#field#\".";
var VF_INVALID_DOMAIN_FORMAT = "\"#value#\" is not a valid website address. Please enter domain name with a valid format such as \"www.zoominfo.com\".";
var VF_NO_WWW = "\"#value#\" does not contain a subdomain (such as \"www\"), which is required. Try using \"www.#value#\".";
var VF_NO_BOOLEAN_NOT_AND = "Boolean expressions such as \"NOT\" or \"AND\" are not allowed in the field \"#field#\".";

//Call this method before submit
function ValidateAllFields() {
	var oValidator = new FormValidator(document.form);

	if (!oValidator.Validate()) {
		NewAlert(oValidator.ErrorMessage, null, MSGBOX_ICON_CRITICAL);
		oValidator.ErrorField.focus();
		return false;
	} 

	if (!oValidator.IsOneFieldFilled()) {
		NewAlert('Please fill in at least one search field.', null, MSGBOX_ICON_CRITICAL);
		return false;
	}
	
	if (document.form.elements[FIELD_FIRST_NAME]) {
		if (document.form.elements[FIELD_FIRST_NAME].value.trim() == "" && document.form.elements[FIELD_LAST_NAME].value.trim() == "") {
			NewAlert('Please enter either a first or last name.', null, MSGBOX_ICON_CRITICAL);
			return false;
		}
	}
	
	if (document.form.elements[FIELD_WEBSITE]) {
		document.form.elements[FIELD_WEBSITE].value = NormalizeURLField(document.form.elements[FIELD_WEBSITE].value); //document.form.elements[FIELD_WEBSITE].value.replace(/http\:\/\//gi, "");
	}

	if (document.form.elements[FIELD_COMPANY_URL]) {
		document.form.elements[FIELD_COMPANY_URL].value = NormalizeURLField(document.form.elements[FIELD_COMPANY_URL].value); //document.form.elements[FIELD_COMPANY_URL].value.replace(/http\:\/\//gi, "");
	}

	return true;
}

//used by an individual field
function ValidateInput() {
	var oValidator = new FormValidator(document.form);
	
	if (!document.all) {
		//return true;
	}
	
	if (document.form.elements[FIELD_WEBSITE]) {
		document.form.elements[FIELD_WEBSITE].value = document.form.elements[FIELD_WEBSITE].value.replace(/http\:\/\//gi, "");
	}

	if (document.form.elements[FIELD_COMPANY_URL]) {
		document.form.elements[FIELD_COMPANY_URL].value = document.form.elements[FIELD_COMPANY_URL].value.replace(/http\:\/\//gi, "");
	}

	if (!oValidator.Validate()) {
		NewAlert(oValidator.ErrorMessage, null, MSGBOX_ICON_CRITICAL);
		oValidator.ErrorField.focus();
		return false;
	} 
	
	return true;
}


function ValidateAllFieldsForm(oForm) {
	var oValidator = new FormValidator(oForm);

	if (!oValidator.Validate()) {
		NewAlert(oValidator.ErrorMessage, null, MSGBOX_ICON_CRITICAL);
		return false;
	} 
	
	if (!oValidator.IsOneFieldFilled()) {
		NewAlert('Please fill in at least one search field.', null, MSGBOX_ICON_CRITICAL);
		return false;
	}
	return true;
}

function ValidateInputNoMessage() {
	event.srcElement.onfocus = ValidateInput;
}

/*
this method only checks that it meets a.b.cc or a.b so that zoominfo.com or www.zoominfo.com will match.
there are too many many top level domain names to check, so it makes sure there's at least two characters.
not a catch all, but should catch some of the basic errors....

if it finds zoominfo.com in the URL, prepend www, since zoominfo.com will return any valid orgs.
*/

function ValidateDomain(sValue, bGetMessage) {

	sValue = sValue.replace('http://', '');
	
	var re = new RegExp("[\\w-]{1,}[\\.][A-z]{2,4}$");
	if (re.test(sValue)) {
		return bGetMessage ? "" : true;
	}	
	return bGetMessage ? VF_INVALID_DOMAIN_FORMAT : false;
}

function ValidateBool(sValue, bGetMessage) {
	if (sValue.toLowerCase().indexOf(" and ")>-1 || sValue.toLowerCase().indexOf(" or ")>-1  || sValue.toLowerCase().indexOf(" not " )>-1) {
		return bGetMessage ? VF_NO_BOOLEAN_EXPRESSIONS : false;
	} else if (sValue.indexOf(",") > -1) {
		return bGetMessage ? VF_NO_COMMA_BOOL : false;
	}
	return bGetMessage ? "" : true;
}

function ValidateBool2(sValue, bGetMessage) {
	if (sValue.toLowerCase().indexOf(" and ")>-1 || sValue.toLowerCase().indexOf(" not " )>-1) {
		return bGetMessage ? VF_NO_BOOLEAN_NOT_AND : false;
	}
	return bGetMessage ? "" : true;
}

function ValidateBoolName(sValue, bGetMessage) {
	if (sValue.toLowerCase().indexOf(" and ")>-1 || sValue.toLowerCase().indexOf(" or ")>-1  || sValue.toLowerCase().indexOf(" not " )>-1) {
		return bGetMessage ? VF_NO_BOOLEAN_EXPRESSIONS : false;
	}
	return bGetMessage ? "" : true;
}

function ValidateQuotes(sValue, bGetMessage) {
	if (sValue.indexOf("\"")>-1) {
		return bGetMessage ? VF_NO_DOUBLE_QUOTES : false;
	}
	return bGetMessage ? "" : true;
}

function ValidateWildcard(sValue, bGetMessage) {
	if (sValue.indexOf("*") != -1 || sValue.indexOf("%") > -1) {
		return bGetMessage ? VF_NO_WILDCARDS : false;
		/*
		if (oField.name=="firstName" || oField.name=="lastName") {
			sResolution += VF_NO_WILDCARDS_TRY_BEGINSWITH;
		}
		*/
	}
	return bGetMessage ? "" : true;
}

function ValidatePunct(sValue, bGetMessage) {
	sValue = Trim(sValue);
	if (sValue.indexOf("(") > -1 || sValue.indexOf(")") > -1 ) {
		return bGetMessage ? VF_NO_PARENS : false;
	} else if (sValue.indexOf(",") > -1) {
		//sResolution=VF_NO_COMMA + "\r\nIf you meant to search by '" + sValue.replace(",", " OR ") + " ', please use the word 'OR' instead.";
		return bGetMessage ? VF_NO_COMMA : false;
	} else if (sValue.indexOf("-") == 0) {
		return bGetMessage ? VF_NO_LEADING_HYPHEN : false;
	} else if (sValue.indexOf("<") != -1 || sValue.indexOf(">") != -1) {
		return bGetMessage ? VF_NO_CHEVRONS : false;
	}
	return bGetMessage ? "" : true;
}

function ValidateName(sValue, bGetMessage) {
	sValue = Trim(sValue);
	if (sValue.indexOf("(") > -1 || sValue.indexOf(")") > -1 ) {
		return bGetMessage ? VF_NO_PARENS : false;
	} else if (sValue.indexOf("-") == 0) {
		return bGetMessage ? VF_NO_LEADING_HYPHEN : false;
	} else if (sValue.indexOf("<") != -1 || sValue.indexOf(">") != -1) {
		return bGetMessage ? VF_NO_CHEVRONS : false;
	}
	return bGetMessage ? "" : true;
}

function ValidateUrl(sValue, bGetMessage) {
	//search punct before BOOL here so , reflects properly.
	// This can handle both delimeteres OR and '
	var URLArray;
	var i;
	var URL;
	var message, bRetCode;
	
			
	sValue = sValue.replace(/\,/g, " or ");
	
	if (!ValidateBool2(sValue))
	{
		if (bGetMessage)
			return ValidateBool2(sValue, bGetMessage);
		else 
			return false;
	}
	if (!ValidatePunct(sValue))
	{
		if (bGetMessage)
			return ValidatePunct(sValue, bGetMessage);
		else 
			return false;
	}
	if (!ValidateWildcard(sValue))
	{
		if (bGetMessage)
			return ValidateWildcard(sValue, bGetMessage);
		else 
			return false;
	}
	if (!ValidateQuotes(sValue))
	{
		if (bGetMessage)
			return ValidateQuotes(sValue, bGetMessage);
		else 
			return false;
	}
	
	URLArray = sValue.split(" ");
	// Each domain name needs to be validated separately
	for (i = 0; i  < URLArray.length; i++)
	{
		URL = Trim(URLArray[i]);

		if (URL.toLowerCase()== "or" || URL == "")
			continue;

		if (!ValidateDomain(URL))
		{
			if (bGetMessage)
			{
				message = ValidateDomain(URL, bGetMessage);
				return message.replace("#value#", URL);
			}
			else 
				return false;
		}
	}
	return true;
}

// Replace commas with or, get rid of extra spaces. Insert or is there is none between two URLs
// This takes place after the validation 
function NormalizeURLField(sValue)
{
	var URLArray;
	var i;
	var URL;
	var NewString = "";
		
	sValue = sValue.replace(/\,/g, " or ");
	sValue = sValue.replace(/http\:\/\//gi, "");

	URLArray = sValue.split(" ");

	if (URLArray.length == 1)
		return sValue;
		
	for (i = 0; i  < URLArray.length; i++)
	{
		URL = Trim(URLArray[i]);
		
		if (URL.toLowerCase() == "or" || URL == "" )
		{
			continue;
		}
		if (NewString != "")
		{
			NewString = NewString + " or ";
		}
		NewString = NewString+URL;
	}
	return NewString;
}

function ValidateCompanyDescLeadingNot(sValue, bGetMessage) {
	sValue = Trim(sValue);

	if (sValue.toLowerCase().indexOf("not ") == 0) {
		return bGetMessage ? VF_NO_NOT_LEADING_COMPANYDESC : false;
	}
	return bGetMessage ? "" : true;
}

//Original File Name: class_code_object.js
//takes an array (row) in the raw data table or an individual class code
function ClassCodeObject(oInit, arrData) { 
	//private members
	var self = this;
	var m_nIndex = null;
	var m_arrData = arrData;
	
	//constants
	var CLASSCODE_COL_CODE = 0;
	var CLASSCODE_COL_TITLE = 1;
	var CLASSCODE_COL_LEVEL = 2;
	var CLASSCODE_COL_NUM_CHILDREN = 3;
	
	//public members
	this.Code = null;
	this.Title = null;
	this.Level = null;
	this.ChildCount = null;
	
	//used to get child or parent objects- must be overriden by inheriting objects
	this.MyType = ClassCodeObject;
	
	//constructor- takes an array (row) in the raw data table or an industry code
	var Constructor = function(oInit) {
		var arrInit = null;
		
		//if an class code was passed as an argument to the constructor
		if (typeof oInit == "string") {
			m_nIndex = GetIndexByCode(oInit);
			arrInit = m_arrData[m_nIndex];
		//if an array (row in a class code data array) was passed as an argument to the constructor
		}  else if (typeof oInit == "object") {
			arrInit = oInit;
		}
		
		if (arrInit) {
			self.Code = arrInit[CLASSCODE_COL_CODE];
			self.Title = arrInit[CLASSCODE_COL_TITLE];
			self.Level = arrInit[CLASSCODE_COL_LEVEL];
			self.ChildCount = arrInit[CLASSCODE_COL_NUM_CHILDREN];
		}
	}
	
	//********************************
	//public methods
	//********************************
	
	this.GetParent = function() {
		var nIndex = GetIndex()
		
		if (this.Level > 1) {
			while (m_arrData[nIndex][CLASSCODE_COL_LEVEL] >= self.Level) {
				nIndex--;
			}
			return new this.MyType(m_arrData[nIndex]);
		} else {
			return null;
		}
	}
	
	this.GetChildren = function() {
		var nIndex = GetIndex() + 1;
		var arrTemp = new Array();
		var i = 0;
		
		if (self.ChildCount > 0) {
			while ((nIndex < m_arrData.length) && (m_arrData[nIndex][CLASSCODE_COL_LEVEL] >= (self.Level + 1))) {
				if (m_arrData[nIndex][CLASSCODE_COL_LEVEL] == (self.Level + 1)) {
					arrTemp[i] = new this.MyType(m_arrData[nIndex]);
					i++;
				}
				nIndex++;
			}
		}
		
		return arrTemp;
	}
	
	this.CompareTo = function(oObj) {
		return CompareClassCodeObjects(self, oObj);
	}
	
	this.GetFullTitle = function() {
		var oParent = this;
		var sFullTitle = this.Title;
		
		while (oParent.GetParent() != null) {
			oParent = oParent.GetParent();
			sFullTitle = oParent.Title + " > " + sFullTitle;
		}
		
		return sFullTitle;
	}
	
	//********************************
	//private methods
	//********************************
	
	var GetIndex = function() {
		if (!m_nIndex) {
			m_nIndex = GetIndexByCode(self.Code);
		}
		
		return m_nIndex;
	}
	
	var GetIndexByCode = function(sCode) {
		for (var i=0; i<m_arrData.length; i++) {
			if (m_arrData[i][0] == sCode) {
				return i;
			}
		}
		
		return -1;
	}
	
	//call the constructor after everything else is loaded
	Constructor(oInit);
}

//Compares class code objects for alphabetical order by title
function CompareClassCodeObjects(oObj1, oObj2) {
	if (oObj1.Title > oObj2.Title) {
		return 1;
	} else if (oObj1.Title < oObj2.Title) {
		return -1;
	} else {
		return 0;
	}
}

function Industry(oInit) {
	this.inheritFrom = ClassCodeObject;
	this.inheritFrom(oInit, g_arrIndustries);
	this.MyType = Industry;
}	

function TitleCategory(oInit) {
	this.inheritFrom = ClassCodeObject;
	this.inheritFrom(oInit, g_arrTitles);
	this.MyType = TitleCategory;
}	

//Original File Name: progress_bar.js
ProgressBarDelay = 10;

function ProgressBarClass() {
	this.Message = "Loading...";
	this.Small = false;
	this.ManualHide = false;
	
	this.Show = function (sMessage, bSmall, bManualHide) {
		if (typeof(sMessage) != "undefined") {
			this.Message = sMessage;
		}
		if (typeof(bSmall) != "undefined") {
			this.Small = bSmall;
		}
		if (typeof(bManualHide) != "undefined") {
			this.ManualHide = bManualHide;
		}
		
		ShowProgressBar(this.Message, this.Small, this.ManualHide);
	}
	
	this.Hide = function () {
		HideProgressBar();
	}
}

var ProgressBar = new ProgressBarClass();

document.write('<style> .fwProgressBarMessage {	font-size: 12px; font-weight: bold;	color: #124EC3; } </style>');

var g_tmrProgressBar, g_tmrProgressBarShow, g_tmrProgressBarEval;
var g_bProgressBarVisible = true;

var FW_PROGRESS_BAR_OFFSET_TOP = 400;

var FW_PROGRESS_BAR_HEIGHT = 132;
var FW_PROGRESS_BAR_HEIGHT_SMALL = 100;

var FW_PROGRESS_BAR_WIDTH = 400;
var FW_PROGRESS_BAR_WIDTH_SMALL = 230;

var FW_PROGRESS_BAR_IMAGE_WIDTH = 49;
var FW_PROGRESS_BAR_IMAGE_WIDTH_SMALL = 49;

var FW_PROGRESS_BAR_IMAGE_HEIGHT = 48;
var FW_PROGRESS_BAR_IMAGE_HEIGHT_SMALL = 48;

var FW_PROGRESS_BAR_IMAGE = "/images/zoominfo/progress.gif";
var FW_PROGRESS_BAR_IMAGE_SMALL = "/images/zoominfo/progress.gif";

//render the progress bar

document.write('<div id="progressBarLayer" style="position:absolute; left:1px; top:1px; width:99%; height:' + FW_PROGRESS_BAR_OFFSET_TOP + 'px; z-index:31; display:none; visibility:hidden;">');
document.write('	<table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0">');
document.write('	<tr>');
document.write('		<td align="center" valign="middle">');
document.write('		<table id="progressBarTableMain" width="' + FW_PROGRESS_BAR_WIDTH + '" height="' + FW_PROGRESS_BAR_HEIGHT + '" border="0" cellspacing="0" cellpadding="0">');
document.write('			<tr>');
document.write('			<td style="background-color:#CCCCCC;padding-right:2px;padding-bottom:2px;">');
document.write('				<table id="progressBarTableSub" width="100%" border="0" cellspacing="0" cellpadding="8" height="' + FW_PROGRESS_BAR_HEIGHT + '" style="border-right:1px #888888 solid; border-bottom:1px #888888 solid;">');
document.write('				<tr>');
document.write('					<td bgcolor="#FFFFFF" align="center" style="border:1px black solid;">');
document.write('					  <img name="progressBarImage" id="progressBarImage" src="' + FW_PROGRESS_BAR_IMAGE + '" width="' + FW_PROGRESS_BAR_IMAGE_WIDTH + '" height="' + FW_PROGRESS_BAR_IMAGE_HEIGHT + '" align="middle" hspace="5">');
document.write('					<br><br>');
document.write('					<span id="progressBarMessage" class="fwProgressBarMessage">Logging in...</span>');
document.write('					<br>');
document.write('					</td>');
document.write('				</tr>');
document.write('				</table>');
document.write('			</td>');
document.write('			</tr>');
document.write('		</table>');
document.write('		</td>');
document.write('	</tr>');
document.write('	</table>');
document.write('</div>');
document.write('');
document.write('<div id="blockProgressBarLayer" style="position:absolute; left:1px; top:1px; z-index:30; display:none; visibility:hidden;">');
document.write('	<table width="100%" border="0" cellspacing="0" cellpadding="0" height="100%">');
document.write('	<tr>');
document.write('		<td align="center" valign="middle">');
document.write('		<img src="/images/spacer.gif" width="100%" height="100%" galleryimg="no">');
document.write('		</td>');
document.write('	</tr>');
document.write('	</table>');
document.write('</div>');



function ShowProgressBar(messageString, bSmall, bManualHide) {
	if (!bSmall) {
		bSmall = false;
	}
	if (!bManualHide) {
		bManualHide = false;
	}
	g_tmrProgressBarShow = window.setTimeout("DoShowProgressBar('" + messageString + "', " + bSmall + "," + bManualHide + ");", ProgressBarDelay);
}

function DoShowProgressBar(messageString, bSmall, bManualHide) {
	//if this is netscape, AOL, or Mac dont use the progress bar

	var bIsAOL = (navigator.appVersion.indexOf('AOL') != -1);
	var bIsNetscape = (document.layers && !document.all);
	var bIsMac = (Browser.OS == OS_MAC && (Browser.UserAgent == BROWSER_IE || Browser.UserAgent == BROWSER_KONQUEROR));
	
	if (bIsAOL || bIsNetscape || bIsMac) {
		return;
	}

	var progressBarLayer = document.getElementById('progressBarLayer');
	var blockProgressBarLayer = document.getElementById('blockProgressBarLayer');
	var progressBarMessage = document.getElementById('progressBarMessage');
	var progressBarTableMain = document.getElementById('progressBarTableMain');
	var progressBarTableSub = document.getElementById('progressBarTableSub');
	var progressBarImage = document.getElementById('progressBarImage');
	
	if (bSmall) {
		progressBarTableMain.width = FW_PROGRESS_BAR_WIDTH_SMALL;
		progressBarTableMain.height = FW_PROGRESS_BAR_HEIGHT_SMALL;
		progressBarTableSub.height = FW_PROGRESS_BAR_HEIGHT_SMALL;
		progressBarImage.width = FW_PROGRESS_BAR_IMAGE_WIDTH_SMALL;
		progressBarImage.height = FW_PROGRESS_BAR_IMAGE_HEIGHT_SMALL;
		progressBarImage.src = FW_PROGRESS_BAR_IMAGE_SMALL;
	} else {
		progressBarTableMain.width = FW_PROGRESS_BAR_WIDTH;
		progressBarTableMain.height = FW_PROGRESS_BAR_HEIGHT;
		progressBarTableSub.height = FW_PROGRESS_BAR_HEIGHT;
		progressBarImage.width = FW_PROGRESS_BAR_IMAGE_WIDTH;
		progressBarImage.height = FW_PROGRESS_BAR_IMAGE_HEIGHT;
		progressBarImage.src = FW_PROGRESS_BAR_IMAGE;
	}

	var i=0;
	
	if (!document.all) {
		window.captureEvents(Event.STOP || Event.RESIZE || Event.SCROLL);
	}
	
	if (!bManualHide) {
		document.onstop = HideProgressBar;
	}
	window.onresize = SizeProgressBar;
	window.onscroll = SizeProgressBar;
	
	document.body.style.cursor = 'wait';
	
	progressBarMessage.innerHTML = messageString;
	
	progressBarLayer.style.display = 'block';
	blockProgressBarLayer.style.display = 'block';
	progressBarLayer.style.visibility = 'visible';
	blockProgressBarLayer.style.visibility = 'visible';

	
	try {
		document.body.focus(); //hides the cursor
	} catch (e) {
		//do nothing
	}
	
	//disable all selects in IE
	if (document.all) {
		EnableAllSelects(false);
	}
	
	SizeProgressBar();
	
	//kickstarts the gif image
	g_tmrProgressBar = setTimeout("document.getElementById('progressBarImage').src=document.getElementById('progressBarImage').src.toString();", 500);
	
	//periodically checks to see if the window is still in a "loading" state
	if (!bManualHide) {
		g_tmrProgressBarEval = setInterval('ProgressBarCheck();', 100);
	}
}
function HideProgressBar() {

	window.clearTimeout(g_tmrProgressBar);
	window.clearTimeout(g_tmrProgressBarShow);
	window.clearTimeout(g_tmrProgressBarEval);

	var progressBarLayer = document.getElementById('progressBarLayer');
	var progressBarTableMain = document.getElementById('progressBarTableMain');
	var blockProgressBarLayer = document.getElementById('blockProgressBarLayer');
	var i=0;
	
	progressBarLayer.style.display = 'none';
	blockProgressBarLayer.style.display = 'none';
	progressBarLayer.style.visibility = 'hidden';
	blockProgressBarLayer.style.visibility = 'hidden';
	
	//if this is IE, show selects that overlapped the progress bar
	ShowOverlappingSelects(progressBarTableMain);
	
	document.onstop = null;
	window.onresize = null;
	window.onscroll = null;
	document.body.style.cursor = 'auto';
	
	if (document.all) {
		EnableAllSelects(true);
	}
}

function SizeProgressBar() {
	var progressBarLayer = document.getElementById('progressBarLayer');
	var blockProgressBarLayer = document.getElementById('blockProgressBarLayer');
	var progressBarMessage = document.getElementById('progressBarMessage');
	var progressBarTable = document.getElementById('progressBarContainerTable');
	
	if (document.body.clientHeight < FW_PROGRESS_BAR_OFFSET_TOP) {
		progressBarLayer.style.height = document.body.clientHeight;
	} else {
		progressBarLayer.style.height = FW_PROGRESS_BAR_OFFSET_TOP;
	}
	
	progressBarLayer.style.top = document.body.scrollTop;
	
	if (document.body.scrollHeight > 2)
		blockProgressBarLayer.style.height = document.body.scrollHeight-2;

	//if this is IE, hide selects that overlap the progress bar
	HideOverlappingSelects(document.getElementById('progressBarTableMain'));
}

function ProgressBarCheck() {
	if (document.readyState && document.readyState == 'complete') {
		HideProgressBar();
	}
}

function EnableAllSelects(bDoEnable) {
	var arrSelects = document.getElementsByTagName('SELECT');
	for (var i=0; i<arrSelects.length; i++) {
		if (!bDoEnable) {
			if (!arrSelects[i].disabled && arrSelects[i].style.display != 'none') {
				arrSelects[i].progressBarDisabled = true;
				arrSelects[i].disabled = true;
			}
		} else {
			if (arrSelects[i].progressBarDisabled) {
				arrSelects[i].progressBarDisabled = null;
				arrSelects[i].disabled = false;
			}
		}
	}
}

//Original File Name: pngfix.js
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;
         var imgWidth = img.width;
         var imgHeight = img.height;
         
         if (imgWidth == 0 ) imgWidth = img.offsetParent.width;
         if (imgHeight == 0 ) imgHeight = img.offsetParent.height;
         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:" + imgWidth + "px; height:" + imgHeight + "px;" + imgStyle + ";"
         + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
         + "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>";
         img.outerHTML = strNewHTML;
         i = i-1;
      }
   }
}

function LocationHref() {
	this.href = document.location.href;
	this.Url = (this.href.indexOf('?')==-1)?this.href:this.href.substr(0, this.href.indexOf('?'));
	this.QueryString = (this.href.indexOf('?')==-1)?"":this.href.substr(this.href.indexOf('?')+1);
	
	this.GetQueryValue = function(key) {
		var arrQueryString = this.QueryString.split('&');
		for(i=0; i<arrQueryString.length;i++) {
			var index = arrQueryString[i].indexOf('=');
			if(index > 0 && key == arrQueryString[i].substr(0, index)) {
				return arrQueryString[i].substr(index+1)
			}
		}
		return "";
	}
	
	this.SetQueryValue = function(key, value) {
		var bSet = false;
		var arrQueryString = this.QueryString.split('&');
		for(i=0; i<arrQueryString.length;i++) {
			var index = arrQueryString[i].indexOf('=');
			if(index > 0 && key == arrQueryString[i].substr(0, index)) {
				bSet = true;
				arrQueryString[i] = key + '=' + value;
			}
		}
		if(!bSet) arrQueryString[arrQueryString.length] = key + '=' + value;
		this.QueryString = arrQueryString.join('&');
	}
}

function CheckBrowserOS(type) {
	var detect = navigator.userAgent.toUpperCase();
	return detect.indexOf(type) >= 0;
}

function SetCookie( name, value, path, expires, domain, secure) {
	var today = new Date();
	today.setTime( today.getTime() );

	if ( expires ) expires = expires * 1000 * 60 * 60 * 24;
	var expires_date = new Date( today.getTime() + (expires) );
	document.cookie = name + "=" +escape( value ) +
	( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) + 
	( ( path ) ? ";path=" + path : ";path=/" ) + 
	( ( domain ) ? ";domain=" + domain : "" ) +
	( ( secure ) ? ";secure" : "" );
}

function GetCookie(name) {
	var start = document.cookie.indexOf(name + "=");
    if (start == -1) return "";
    
    start = start + name.length + 1; 
    end = document.cookie.indexOf(";", start);
    if (end == -1) end = document.cookie.length;
    return unescape(document.cookie.substring(start, end));
}

function DeleteCookie( name, path, domain ) {
	document.cookie = name + "=" +
	( ( path ) ? ";path=" + path : ";path=/" ) + 
	( ( domain ) ? ";domain=" + domain : "" ) +
	";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}