/* COMMON DHTML FUNCTIONS */

/****************************************
 *			EVENT MANAGEMENT			*
 ****************************************/
 
/**
 * X-browser event handler attachment and detachment
 * TH: Switched first true to false per http://www.onlinetools.org/articles/unobtrusivejavascript/chapter4.html
 * @argument evType - name of the event - DONT ADD "on", pass only "mouseover", etc
 */
function addEvent(obj, evType, fn){
	if (obj.addEventListener){
    	obj.addEventListener(evType, fn, false);
	    return true;
	} else if (obj.attachEvent){
		return obj.attachEvent("on"+evType, fn);
	}
	return false;
}
function removeEvent(obj, evType, fn, useCapture){
	if (obj.removeEventListener){
    	obj.removeEventListener(evType, fn, useCapture);
		return true;
	} else if (obj.detachEvent){
    	return obj.detachEvent("on"+evType, fn);
	}
	alert("Handler could not be removed");
}

/****************************************
 *			WINDOW MANAGEMENT			*
 ****************************************/

function showWindow(url, name, width, height, bReplace, bResizable) {

    width	= (width)  ? width	: "750px";
    height	= (height) ? height	: "350px";
    name	= (name)   ? name	: "_blank";
    bResizable = (bResizable) ? bResizable : "yes";

	// Calculate the center coordinates    
	var fullHeight	= getViewportHeight();
	var fullWidth	= getViewportWidth();
	var viewTop		= (window.screenTop)  ? window.screenTop  : window.screenY + 200;
	var viewLeft	= (window.screenLeft) ? window.screenLeft : window.screenX;
	var newLeft		= viewLeft + (fullWidth - parseInt(width, 10)) / 2;
	var newTop		= viewTop + (fullHeight - parseInt(height, 10)) / 2;

    var newWindow = window.open(url, name, "width="+width+",height="+height+",status=no,resizable="+bResizable+",toolbar=no,scrollbars=yes,menubar=no,location=no", bReplace);
    newWindow.moveTo(newLeft, newTop);
    newWindow.focus();
    
    return newWindow;
}
function urlNav(url, target) {
	document.location=url;
}
/**
 * Code below taken from - http://www.evolt.org/article/document_body_doctype_switching_and_more/17/30655/
 * Modified 4/22/04 to work with Opera/Moz (by webmaster at subimage dot com)
 * Gets the full width/height because it's different for most browsers.
 */
function getViewportHeight() {
	if (window.innerHeight!=window.undefined) return window.innerHeight;
	if (document.compatMode=='CSS1Compat') return document.documentElement.clientHeight;
	if (document.body) return document.body.clientHeight; 
	return window.undefined; 
}
function getViewportWidth() {
	if (window.innerWidth!=window.undefined) return window.innerWidth; 
	if (document.compatMode=='CSS1Compat') return document.documentElement.clientWidth; 
	if (document.body) return document.body.clientWidth; 
	return window.undefined; 
}
/**
 * Gets the real scroll top
 */
function getScrollTop() {
	if (self.pageYOffset) { // all except Explorer
		return self.pageYOffset;
	} else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
		return document.documentElement.scrollTop;
	} else if (document.body) { // all other Explorers
		return document.body.scrollTop;
	}
}
function getScrollLeft() {
	if (self.pageXOffset) { // all except Explorer
		return self.pageXOffset;
	} else if (document.documentElement && document.documentElement.scrollLeft) { // Explorer 6 Strict
		return document.documentElement.scrollLeft;
	} else if (document.body) { // all other Explorers
		return document.body.scrollLeft;
	}
}
/****************************************
 *			FORMAT MANAGEMENT			*
 ****************************************/

function rightTrim() {
    return this.replace(/\s+$/gi, "");
}
function leftTrim() {
    return this.replace(/^\s*/gi, "");
}
function rightPad(str, padChar, length) {
	while (str.length < length) {
		str = str + padChar;
	}
	return str;
}
function leftPad(str, padChar, length) {
	while (str.length < length) {
		str = padChar + str;
	}
	return str;
}
function Trim() {
    return this.rightTrim().leftTrim();	
}
function trimString(str) {
	str = new String(str).replace(/\s+$/gi, "");
	return str.replace(/^\s*/gi, "");
}
String.prototype.rightTrim = rightTrim;
String.prototype.leftTrim = leftTrim;
String.prototype.Trim = Trim;

function stripAll(str, pattern) {
	var result = "";
    var sections = str.split(pattern);
    for (var i = 0; i < sections.length; i++) {
        result+=sections[i];
	}
    return result;
}
function expandDouble(val, fractionDigits) {

	var str = (val instanceof String) ? val : new String(val);
	str = stripAll(str, ",");
	// Expand abbreviated values e.g. 1B, 45.67M etc
	var length = str.length;
	var floatValue = parseFloat(str.substring(0, length));
	var lastChar = str.charAt(length - 1);
	if (lastChar == 'B' || lastChar == 'b') {
		floatValue *= 1000000000;
	} else if (lastChar == 'M' || lastChar == 'm') {
		floatValue *= 1000000;
	} else if (lastChar == 'K' || lastChar == 'k') {
		floatValue *= 1000;
	}
	floatValue = (fractionDigits != undefined) ? new Number(new Number(floatValue).toFixed(fractionDigits)) : floatValue;
	return floatValue;
}
			            
function formatDouble(val, fractionDigits) {
	
	var pattern = ",";
	var interval = 3;
	var str = (val instanceof String) ? val : new String(val);
	
	if (fractionDigits != undefined && fractionDigits >= 0) {
		str = new Number(expandDouble(str, fractionDigits)).toString();
	}

	var sign = "";
	if (str.length > 2) {
		if (str.charAt(0) == '-') {
			str = str.substring(1, str.length);
			sign = "-";
		} else if (str.charAt(0) == "+") {
			str = str.substring(1, str.length);
			sign = "+";
		}
	}	
	var mantissa = "";	
	var exponentLength = str.indexOf('.');
	if (exponentLength != -1) {
		mantissa = str.substring(exponentLength, str.length);
		if (fractionDigits != undefined){
			if (fractionDigits > 0) {
				if (mantissa.length > fractionDigits) {
					mantissa = mantissa.substring(0, fractionDigits + 1);
				} else {
					for (var i = mantissa.length; i <= fractionDigits; i++) {
						mantissa += "0";
					}
				}
			} else {
				mantissa = "";
			}
		}
	} else {
    	exponentLength = str.length;
		if (fractionDigits != undefined && fractionDigits > 0) {
			mantissa += ".";
			for (var i = mantissa.length; i <= fractionDigits; i++) {
				mantissa += "0";
			}
		}
	}
	
	var sections = str.split("");
	var count = 1;               	
	var result = "";               	
	for (var i = exponentLength - 1; i >= 0; i--) {
	    if (count > interval) {
	    	result = sections[i] + pattern + result;
	    	count = 1;
	    } else {
		    result = sections[i] + result;
	    }
	    count++;
	}
	return sign + result + mantissa;
}
function escapeString(str) {
	if (!str || str.length < 0) {
		return str;
	}
	// Reference: http://www.cs.sfu.ca/~ggbaker/reference/characters/#other
	var escaped = str;
	escaped = escaped.replace("&(?!#)", "&#x0026;");
	escaped = escaped.replace("<", 		"&#x003C;");
	escaped = escaped.replace(">", 		"&#x003E;");
	escaped = escaped.replace("\"", 	"&#x0022;");
	escaped = escaped.replace("'", 		"&#x0027;");
	escaped = escaped.replace("`", 		"&#x0060;");
	escaped = escaped.replace("�", 		"&#x2018;");
	escaped = escaped.replace("�", 		"&#x2019;");
	escaped = escaped.replace("�", 		"&#x201C;");
	escaped = escaped.replace("�", 		"&#x201D;");
	escaped = escaped.replace(/\u2022/, "&#x2022;");//� (bullet)
	escaped = escaped.replace(/\u00B0/, "&#x00B0;");//� (degree)
	escaped = escaped.replace(/\u00B0/, "&#x00B0;");//� (interpunct)
	escaped = escaped.replace(/\u00AB/, "&#x00AB;");//� (guillemet left)
	escaped = escaped.replace(/\u00BB/, "&#x00BB;");//� (guillemet right)
	escaped = escaped.replace(/\u0024/, "&#x0024;");//� (cent)
	escaped = escaped.replace(/\u00A2/, "&#x00A2;");//$ (dollar)
	escaped = escaped.replace(/\u20AC/, "&#x20AC;");//� (Euro)
	escaped = escaped.replace(/\u00A3/, "&#x00A3;");//� (Pound)
	escaped = escaped.replace(/\u00A5/, "&#x00A5;");//� (Yen)
	escaped = escaped.replace(/\u20A6/, "&#x20A6;");//? (Naira)
		 
	escaped = escaped.replace(/\u2032/, "&#x2032;");
	escaped = escaped.replace(/\u2033/, "&#x2033;");
	escaped = escaped.replace(/\u3003/, "&#x3003;");
	return escaped;
}

/****************************************
 *			FORM DATA MANAGEMENT		*
 ****************************************/
function formClear(form) {
	var elements = form.elements;
	for (var i = 0; i < elements.length; i++) {
    	var objElement = elements[i];
		if (objElement.tagName == "INPUT" || objElement.tagName == "SELECT" || objElement.tagName == "TEXTAREA") {    
			if (objElement.type != "submit" && objElement.type != "reset") {
				if (objElement.type == "radio" || objElement.type == "checkbox" ) {
					objElement.checked = false;
				} else {
					objElement.value = "";	
				}
			}
		}
	}
}
function showLoadIcon(loaderID, loadMessage) {
	var loadingElement = null;
	if (loaderID && (loadingElement = getObject(loaderID))) {
		var childNodes = loadingElement.getElementsByTagName('*');
		for (var i = 0; i < childNodes.length; i++) { childNodes[i].style.display = "none"; }
		
		var obj_DIV = document.createElement("DIV");
		loadMessage = (loadMessage != undefined) ? loadMessage : "Processing. Please wait.";
		obj_DIV.className = "loading";
		obj_DIV.innerHTML = "<em class='soft'> " + loadMessage + "</em>";
		obj_DIV.style.margin = "auto";
		obj_DIV.style.display = "inline";
		
		var obj_Loading = document.createElement("IMG");
		obj_Loading.src = window.getCDN() + "/images/icons/loading.gif";
		obj_Loading.setAttribute("align", "absmiddle");
		obj_Loading.style.margin = "0px 10px 0px 10px";
		
		loadingElement.appendChild(obj_DIV);
		loadingElement.appendChild(obj_Loading);
	}
	//alert('loaderID=' + loaderID + ', loadingElement=' + loadingElement);
}
function formSubmit(form, action, loaderID) {
	if (isFormValid(form)) {
		loadDefaults(form);
		form.target = (form.target) ? form.target : "_self";
		form.action	= (action) ? action : document.location;
		loaderID = (loaderID) ? loaderID : "formsubmitcontainer";
		showLoadIcon(loaderID);
		form.submit();
	}
}
function formSubmitAsync(xmlHttp, form, action, responseHandler, loaderID) {
	xmlHttp = (xmlHttp) ? xmlHttp : getDefaultXMLHttpObject();
	var elements = form.elements;
	var parameters = "?";

	for (var i = 0; i < elements.length; i++) {
		var objElement = elements[i];
		//alert("elements["+i+"].name="+elements[i].name+", className="+elements[i].className+", className="+elements[i].tagName);
		if (objElement.type != 'hidden' && !objElement.disabled && !isFormDataValid(objElement)) {
			return;
		}
		var name	= (objElement.name) ? objElement.name.Trim() : "";
		var tagName = (objElement.tagName) ? objElement.tagName.Trim().toLowerCase() : "";
		var type 	= (objElement.type) ? objElement.type.Trim().toLowerCase() : "";
		var value	= (tagName == "select") ? getSelectValue(objElement) : objElement.value;
		if ((tagName == "input" || tagName == "select" || tagName == "textarea") && 
				name.length > 0 && !objElement.disabled && 
				((type != "checkbox" && type != "radio") || objElement.checked)) {
			parameters += "&"+name+"="+encodeURIComponent(value);
		}
    }
	loadDefaults(form);
	//alert(parameters);
	loaderID = (loaderID) ? loaderID : "formsubmitcontainer";
	showLoadIcon(loaderID);
	var formAction = (action) ? action : document.location;
	xmlHttpPostData(xmlHttp, formAction, parameters, responseHandler);
    return;
//	form.target = (form.target) ? form.target : "_self";
//	form.action	= (action) ? action : document.location;
//	form.submit();
}
function isFormValid(form) {
	var elements = form.elements;
	for (var i = 0; i < elements.length; i++) {
		var objElement = elements[i];
		if (objElement.type != 'hidden' && !objElement.disabled && !isFormDataValid(objElement)) {
			return false;
		}
    }
    return true;
}
function loadDefaults(form) {
	var elements = form.elements;
	for (var i = 0; i < elements.length; i++) {
		var defaultValue = elements[i].getAttribute("default");
		if (elements[i].value == '' && (defaultValue != null && defaultValue != undefined)) {
			elements[i].value = defaultValue;
		}
    }
}
var FORM_ERROR_MESSAGE = null;
function isFormDataValid(objElement)  {
	
	var wasValidated = true;
	var errorMsg = "";
	// Check for the existence of a validation function
	var callback = objElement.getAttribute("validate");
    if (callback && (callback = eval("window."+callback))) {
    	var minChars = objElement.getAttribute("minchars");
    	var maxChars = objElement.getAttribute("maxchars");
    	var minNum	 = objElement.getAttribute("minnum");
    	var maxNum	 = objElement.getAttribute("maxnum");
    	
		FORM_ERROR_MESSAGE = null;
		wasValidated = (!minChars || isValid(objElement.value, null, minChars)) &&
					(!maxChars || isValid(objElement.value, null, null, maxChars)) &&
					(!minNum || isValidDecimal(objElement.value, minNum, null)) &&
					(!maxNum || isValidDecimal(objElement.value, null, maxNum));
					
    	if (!wasValidated || !callback.call(objElement, objElement.value)) {
    		var defaultValue = objElement.getAttribute("default");
			if (defaultValue != null && defaultValue != undefined) {
    			objElement.value = ""; // Will be set to default at final submit
    		} else {
				highlightElement(objElement, true);
				//errorMsg = errorMsg ? errorMsg : objElement.getAttribute("errmsg");
				FORM_ERROR_MESSAGE = (FORM_ERROR_MESSAGE) ? FORM_ERROR_MESSAGE : "One of the required inputs is invalid";
				FORM_ERROR_MESSAGE += "\n\nPlease amend the highlighted item and retry.";
				alert(FORM_ERROR_MESSAGE);
				//alert(errorMsg ? errorMsg : "The highlighted item contains an invalid value. Please amend it then retry.");
				FORM_ERROR_MESSAGE = null;
				wasValidated = false;
			}
		} else {
			highlightElement(objElement, false);
		}
    }
	return wasValidated;
}

/****************************************
 *			DATA VALIDATION				*
 ****************************************/
var LEGAL_NUMBERS		= '0123456789';
var LEGAL_DECIMALS		= LEGAL_NUMBERS + '.-+,';
var LEGAL_HEXADECIMALS 	= LEGAL_NUMBERS + 'ABCDEFabcdef';
var LEGAL_CHARACTERS	= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefefghijklmnopqrstuvwxyz';
var LEGAL_PRINTABLES 	= LEGAL_DECIMALS + LEGAL_CHARACTERS;
function isValidDecimal(string, minNum, maxNum) {
	//alert("string="+string+",minNum="+minNum+",maxNum="+maxNum);
    if (!isValid(string, LEGAL_DECIMALS)) {
    	//FORM_ERROR_MESSAGE = "The value is not an acceptable number min="+minNum+", max="+maxNum;
    	return false;
    }
    var value = parseFloat(stripAll(string, ","));
    minNum = (minNum) ? parseFloat(stripAll(minNum, ",")) : -Number.MAX_VALUE;
    if (minNum && value < minNum) {
    	FORM_ERROR_MESSAGE = "The value should be greater than or equal to " + minNum;
    	return false;
    }
    maxNum = (maxNum) ? parseFloat(stripAll(maxNum, ",")) : Number.MAX_VALUE;
    if (maxNum && value > maxNum) {
    	FORM_ERROR_MESSAGE = "The value should be less than or equal to " + maxNum;
    	return false;
    }
    return true;
}
function isValidPrintable(string, minChars, maxChars) {
	return isValid(string, LEGAL_PRINTABLES, minChars, maxChars);
}
function isValidAlphaNumeric(string, minChars, maxChars) {
	return isValid(string.Trim(), LEGAL_NUMBERS + LEGAL_CHARACTERS, minChars, maxChars);
}
function isValidName(string, minChars, maxChars) {
	return isValid(string.Trim(), LEGAL_NUMBERS + LEGAL_CHARACTERS + '.-+/' + ' ', minChars, maxChars);
}
function isValidString(string, minChars, maxChars) {
	return isValid(string, null, minChars, maxChars);
}
function isValid(string, allowed, minChars, maxChars) {
    if (string == null || string == undefined || (string = trimString(string)) == "") {
    	FORM_ERROR_MESSAGE = "The value is empty";
    	return false;
    }
    if (minChars && string.length < minChars) {
    	FORM_ERROR_MESSAGE = "The length of the value is should be greater than or equal to " + minChars;
    	return false;
    }
    if (maxChars && string.length > maxChars) {
    	FORM_ERROR_MESSAGE = "The length of the value is should be less than or equal to " + maxChars;
    	return false;
    }
    for (var i=0; allowed && i < string.length; i++) {
        if (allowed.indexOf(string.charAt(i)) == -1) {
        	FORM_ERROR_MESSAGE = "The value contains an illegal character : " + string.charAt(i);
            return false;
        }
    }
    return true;
}
var DEFAULT_EMAIL_ERROR_MESSAGE = "The email address is improperly formatted";
function isValidEmail(string) {
	
	var LEGAL_EMAIL_CHARACTERS = LEGAL_NUMBERS + LEGAL_CHARACTERS;
	if (!isValid(string, LEGAL_EMAIL_CHARACTERS + '._-@', 6)) {
		FORM_ERROR_MESSAGE = DEFAULT_EMAIL_ERROR_MESSAGE + ". (Error Code 1)";
		return false;
	}
	if (LEGAL_EMAIL_CHARACTERS.indexOf(string.charAt(0)) == -1 || 
			LEGAL_CHARACTERS.indexOf(string.charAt(string.length - 1)) == -1) {
		FORM_ERROR_MESSAGE = DEFAULT_EMAIL_ERROR_MESSAGE + ". (Error Code 2)";
		return false;
	}
	var at1 = string.indexOf('@');
	var at2 = string.lastIndexOf('@');
	var dot1 = string.lastIndexOf('.');
	if (at1 == -1 || at1 != at2 || dot1 == -1 || at1 > dot1) {
		FORM_ERROR_MESSAGE = DEFAULT_EMAIL_ERROR_MESSAGE + ". (Error Code 3)";
		return false;
	}
	var hy1 = string.indexOf('-');
	if (hy1 == 0 || hy1 == (string.length - 1) ||
			LEGAL_EMAIL_CHARACTERS.indexOf(string.charAt(hy1 - 1)) == -1 ||
			LEGAL_EMAIL_CHARACTERS.indexOf(string.charAt(hy1 + 1)) == -1) {
		FORM_ERROR_MESSAGE = DEFAULT_EMAIL_ERROR_MESSAGE + ". (Error Code 4)";
		return false;
	}
	FORM_ERROR_MESSAGE = null;
	return true;
}
function isValidDate(string, allowed) {
	var sections= string.split('-');
	var yyyy	= sections[0];
	var mm		= sections[1];
	var dd		= sections[2];

    if (!isValid(yyyy, LEGAL_NUMBERS, 4, 4) ||
    		!isValid(mm, LEGAL_NUMBERS, 2, 2) || !isValid(dd, LEGAL_NUMBERS, 2, 2)) {
	    FORM_ERROR_MESSAGE += "\nThe date is improperly formatted";
	    return false;
    }
    FORM_ERROR_MESSAGE = null;
    return true;
}
/* Added by NG */
var MONTH_NAMES=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
function parseDateYYYYMMDD(dateString) {
	var sections= dateString.split('-');
	var yyyy	= sections[0];
	var mm		= sections[1];
	var dd		= sections[2];
	return new Date(MONTH_NAMES[mm - 1] + ', ' + dd + ' ' + yyyy);
}

/****************************************
 *			PARAMETER MANAGEMENT		*
 ****************************************/

function createParameters(quantity) {
	//alert('createParameters('+quantity+')');
    document.paramArray = new Array(quantity);    
    for (var i = 0; i < document.paramArray.length; i++) {
        document.paramArray[i] = new Array(4);
    	document.paramArray[i][0] = null; // label
    	document.paramArray[i][1] = null; // value
    	document.paramArray[i][2] = null; // type
    	document.paramArray[i][3] = null; // class name
    	document.paramArray[i][4] = null; // onchange
    	document.paramArray[i][5] = null; // validation callback
    	document.paramArray[i][6] = null; // style
    }
}
function setParameter(index, label, value, type, className, onchange, validate, style) {
    //alert('setParameter('+index+','+label+','+value+')');
    if (document.paramArray && index < document.paramArray.length) {
    	if (value != null) {
    	    document.paramArray[index][0] = label;
    	    document.paramArray[index][1] = (value) ? value : "";
    	    document.paramArray[index][2] = (type) ? type : "text";
    	    document.paramArray[index][3] = (className) ? className : "text";
    	    document.paramArray[index][4] = (onchange) ? onchange : "";
    	    document.paramArray[index][5] = (validate) ? validate: "";
    	    document.paramArray[index][6] = (style) ? style : "";
        } else {
    	    document.paramArray[index][0] = null;
    	    document.paramArray[index][1] = null;
    	    document.paramArray[index][2] = null;
    	    document.paramArray[index][3] = null;
    	    document.paramArray[index][4] = null;
    	    document.paramArray[index][5] = null;
    	    document.paramArray[index][6] = null;
        }
    }
}
function showParameterDialog(url, callback, width, height) {
    var i = 0;    
    for (; document.paramArray && i < document.paramArray.length; i++) {	
    	if (document.paramArray[i][0] == null) {
    	    break;
    	}
    }    
	width 	= (width) 	? width   : "320px";
	height	= (height) 	? height  : "200px";
	url		= (url)		? url	  : (getBase()+"/jsp/tools/parameters.jsp?numparams="+i);

	document.paramCallback = (callback) ? callback : objectCallback;
	showWindow(url, "paramdialog", width, height);
}
function objectCallback(values) {
	var objOBJECT = document.documentElement.getElementsByTagName('OBJECT')[0]; 
	//alert(objOBJECT.innerHTML);
    for (i = 0; i < values.length; i++) {                
    	document.paramArray[i][1] = values[i];
        objOBJECT.handleCallback('setParameterValue'+i, values[i]);
	}
}

/****************************************
 *			XML DATA MANAGEMENT			*
 ****************************************/

var xmlHttpObject = createXMLHTTPObject();
function createXMLHTTPObject() {
	var xmlHttp;	
	/*@cc_on
	@if(@_jscript_version >= 5)
		try {
			xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
		} catch(e) {
			try {
				xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(exception) {
				xmlHttp = false;
			}			  
		}
	@else
		xmlHttp = false;
	@end @*/
	if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
		try {
			xmlHttp = new XMLHttpRequest();
		} catch(e) {
			xmlHttp = false;
		}
	}		
	return xmlHttp;		
}
function createXMLHTTPObjectALTERNATIVE(url) {
  var xhr;
  try {
    xhr = new XMLHttpRequest();
  } catch (e) {
    var a = ['MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0',
      'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'MICROSOFT.XMLHTTP.1.0',
      'MICROSOFT.XMLHTTP.1', 'MICROSOFT.XMLHTTP'];
    for (var i = 0; i < a.length; i++) {
      try {
        xhr = new ActiveXObject(a[i]);
        break;
      } catch (e) {
      }
    }
  }
  if (xhr) {
    xhr.open("POST", url, true);
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    var data = '&js=' + encodeURIComponent(top.js.document.body.innerHTML);
    xhr.send(data);
  }
}
function getDefaultXMLHttpObject() {
	return xmlHttpObject;
}
function xmlHttpLoadData(xmlHttp, url, responseHandler, loaderID, abortPendingCalls, canLoadFromCache) {
	abortPendingCalls = (abortPendingCalls == null) ? true : abortPendingCalls;
	if (abortPendingCalls || !xmlCallInProgress(xmlHttp)) {
		try {
			if (!canLoadFromCache) {
				var rand = ".rand="+Math.random();
				url += (url.indexOf('?') != -1) ? ("&" + rand) : ("?" + rand);
			}
			//alert(url);
			showLoadIcon(loaderID);
			xmlHttp.open("GET", url, true);
			xmlHttp.onreadystatechange = responseHandler;
			xmlHttp.send(null);
			return true;
		} catch (e) {
		}
	}
	return false;
}
function xmlHttpPostData(xmlHttp, url, parameters, responseHandler, loaderID) {
	if (!xmlCallInProgress(xmlHttp)) {
		try {
			//var rand = ".rand="+Math.random();
			//url += (url.indexOf('?') != -1) ? ("&" + rand) : ("?" + rand);
			//alert("Posting to "+url+", params="+parameters);
			showLoadIcon(loaderID);
			xmlHttp.open("POST", url, true);
			xmlHttp.onreadystatechange = responseHandler;
			xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			xmlHttp.setRequestHeader("Content-length", parameters.length);
			xmlHttp.setRequestHeader("Connection", "close");
			xmlHttp.send(parameters);
			return true;
		} catch (e) {
		}
	}
	return false;
}
function xmlCallInProgress(xmlHttp) {
	switch (xmlHttp.readyState) {
	case 1: case 2: case 3:
		return true;
	// Case 4 and 0
	default:
		return false;
	}
}

/****************************************
 *				NAVIGATION 				*
 ****************************************/

function pageNav(pageID, showPrevious) {
	var nextTable = getObject(pageID);
	if (nextTable) {
		if (window.activePage != null) {
			window.activePage.style.zindex = 0;
			window.activePage.style.display = showPrevious ? "block" : "none";
		}
        window.activePage = nextTable;
        window.activePage.style.zindex = 1;
        window.activePage.style.display = "block";
        activatePageLink(pageID + "Link");	
	}	
}
function activatePageLink(pageLinkID) {
	var newActivePageLink = getObject(pageLinkID);
	if (newActivePageLink) {
		if (window.activePageLink) {
			window.activePageLink.className = 'navlink';
		}
	 	window.activePageLink = newActivePageLink;
	 	window.activePageLink.className = 'activenavlink';
	}
}
function isControlPage(pageText) {
	var isControl = false;
	if (pageText.indexOf("<!--TRAFFICSPACES_LOGIN-->") != -1) {
		//alert("Found Login Page");
		document.location = getBase() + "/platform/";
		isControl = true;
	} else if (pageText.indexOf("<!--TRAFFICSPACES_ERROR-->") != -1) {
		//alert(pageText);
	}
	return isControl;
}
/****************************************
 *				MISCELLANEOUS 			*
 ****************************************/

function getBase() {
	return window.getRoot ? window.getRoot() : "";	
}	
function getObject(id, parentElement) {
	if (id) {
		if (parentElement == document || !parentElement || parentElement == "") {
			return document.getElementById(id);
		} else {
			var childNodes = parentElement.elements;
			for (var i = 0; i < childNodes.length; i++) {
				var node = childNodes[i];
				if (node.getAttribute("id") == id || node.getAttribute("name") == id) {
					return node;
				}
			}
		}
	}
	return null;
}
function toggleObjects(showID, hideID, type, parent) {
	var objShow = getObject(showID, parent);
	var objHide = getObject(hideID, parent);
	if (objShow == objHide) {
		if (objHide) {
			objHide.style.display = (objHide.style.display == "none") ? ((type != null) ? type : "inline") : "none";
		}
	} else {
		if (objShow) {
			objShow.style.display = (type != null) ? type : "inline";
		}
		if (objHide) {
			objHide.style.display = "none";
		}
	}
}
function togglePageHelp(helpID, displayMode) {
	var childNodes = document.getElementsByTagName('DIV');
	for (var i = 0; i < childNodes.length; i++) {
		var node = childNodes[i];
		if (node.className == "pagehelp" || node.className == "pagehelpheader") {
			if (helpID == null || node.getAttribute("id") == helpID) {
				node.style.display = (displayMode != null) ? displayMode : ((node.style.display == "" || !node.style.display || node.style.display == "none") ? "block" : "none");
			}
		}
	}
}
function toggleClass(objectID, classA, classB, parent) {
	var object = getObject(objectID, parent);
	object.className = (object.className == classA) ? classB : classA;
}
function highlightElement(objElement, canHighlight) {
	var offset = objElement.className.indexOf("-highlight");
	if (canHighlight) {
		objElement.className = (offset != -1) ? objElement.className : objElement.className + "-highlight";
	} else {
		objElement.className = (offset != -1) ? objElement.className.substring(0, offset) : objElement.className;
	}
}
/****************************************
 *		  SELECT LIST MANAGEMENT		*
 ****************************************/

function getSelectedOption(selectList) {
    var col_Opts = selectList.options;
    var i;
    for (i = 0; i < col_Opts.length; i++) {
		var opt = col_Opts[i];
		if (opt.selected) {
		    return opt;
		}
    }
    return null;
}
function getSelectValue(selectList) {
    var col_Opts = selectList.options;
    var i;
    var value = "";
    for (i = 0; i < col_Opts.length; i++) {
		var opt = col_Opts[i];
		if (opt.selected) {
		    value += (value.length != 0) ? (","+opt.value) : opt.value;
		}
    }
    return value;
}
function replaceOption(selectList, optionValue, optionText, index) {
    addOption(selectList, optionValue, optionText ? optionText : optionValue, index, true, true);
}
function addOption(selectList, optionValue, optionText, index, isSelected, canReplace) {
	if (!selectList || optionValue == null || optionText == null || (optionText = optionText.Trim()) == '') { 
		return;
	}
    if (canReplace) {
        removeOption(selectList, optionValue);
    }    
    var obj_Opt = document.createElement("OPTION");
    if (index != null && index != undefined && index >= 0 && index < selectList.options.length) {
        selectList.options.add(obj_Opt, index);
    } else {
        selectList.options.add(obj_Opt);
        //selectList.options.appendChild(obj_Opt);
    }
    obj_Opt.value 		= optionValue;
    obj_Opt.innerHTML 	= optionText;
    obj_Opt.selected 	= isSelected == true;    
    //alert("Adding option value="+optionValue+", text="+optionText+", position="+index);
    //alert("Final selectList.innerHTML="+selectList.innerHTML);        
    return obj_Opt;
}
function findOptionIndex(selectList, optionValue) {
    var col_Opts = selectList.options;       
    for (var i = 0; i < col_Opts.length; i++) {
        var opt = col_Opts[i];        
        if (opt.value == optionValue) {
            return i;
        }        
    }
    return -1;
}
function findOption(selectList, optionValue) {
    var index = findOptionIndex(selectList, optionValue);
    if (index != -1) {
    	return selectList.options.item(index);    
    }
    return null;
}
function clearOptions(selectList) {
	selectList.innerHTML = "";
	var opts = selectList.options;
	while (opts.length > 0) {
	    if (opts.remove) {
	    	opts.remove(0);
	    } else {
	    	opts[0]=null;
	    }
	}
}
function removeSelectedOptions(selectList) {
	var opts = selectList.options;
    for (var i = 0; i < opts.length; i++) {
		var opt = opts[i];
		if (opt.selected) {
			if (opts.remove) {
			    opts.remove(i--);
			} else {
				opts[i] = null;
			}
		}
    }
}
function removeOption(selectList, optionValue) {
    var index = findOptionIndex(selectList, optionValue);
    if (index != -1) {
	    if (selectList.options.remove) {
	    	selectList.options.remove(index);
	    } else {
	    	selectList.options[index]=null;
	    }
    }    
}
function moveOption(selectList, optionValue, distance) {
    if (distance == null || distance == undefined) {
    	distance = 0;
    }
    var index = findOptionIndex(selectList, optionValue);
    if (index != -1) {
    	var optval = selectList.options.item(index).value;
    	var opttxt = selectList.options.item(index).innerHTML;

    	selectList.options.remove(index);
    	
    	var nextpos = index + distance;
    	addOption(selectList, optval, opttxt, (nextpos >= 0) ? nextpos : 0);
    }
}
function populateSelect(selectList, optionsText) {
	//alert("populateSelect: select=" + selectList + ", opts=" + optionsText);
	clearOptions(selectList);
	var rootElement = Xparse(optionsText);
	for (var i = 0; i < rootElement.contents.length; i++) {
		var childNode = rootElement.contents[i];
		if (childNode.type == "element" && childNode.name.toLowerCase() == "option") {
			
			var optValue = childNode.attributes["value"];
			optValue = (optValue != null && optValue != undefined) ? optValue : "";
			
			var optSelected = childNode.attributes["selected"];
			//alert(optValue + "="+optSelected+"="+childNode.attributes["activevalue"]);
			var optText = null;
			for (var j = 0; j < childNode.contents.length; j++) {
				if (childNode.contents[j].type == "chardata") {
					optText = childNode.contents[j].value;
					break;
				}
			}
			if (optValue != null) {
				addOption(selectList, optValue, optText, null, (optSelected == "true"));
			}
		}
	}
}
function exportSelectValues(selectList) {
	var data = "";
    var col_Opts = selectList.options;       
    for (var i = 0; i < col_Opts.length; i++) {
        var opt = col_Opts[i];        
        if (opt.selected) {
        	data += data.length != 0 ? "," : "";
        	data += opt.value;
        }        
    }
    return data;
}
function exportSelect(selectList) {
	var data = "";
    var col_Opts = selectList.options;       
    for (var i = 0; i < col_Opts.length; i++) {
        var opt = col_Opts[i];        
        if (opt.selected) {
        	var escapedOptValue = opt.value.replace(/\s+/gi,'\\ ').replace(/:/gi,'\\:');
        	data += data.length != 0 ? "\n" : "";
        	data += escapedOptValue + "\t" + opt.innerHTML;
        }        
    }
    return data;
}
function selectAll(selectList) {
	toggleSelectAll(selectList, true);
}
function deselectAll(selectList) {
	toggleSelectAll(selectList, false);
}
function toggleSelectAll(selectList, canSelect) {
    var col_Opts = selectList.options;
    var i;
    for (i = 0; i < col_Opts.length; i++) {
		col_Opts[i].selected = canSelect;
    }
}
function exportCheckboxesValues(name, parentElement, minNum, maxNum, separator) {
	return exportInputValues(name, parentElement, minNum, maxNum, "checkbox", separator);
}
function exportInputValues(name, parentElement, minNum, maxNum, inputType, separator) {
	parentElement = (parentElement) ? parentElement : document;
	separator = (separator) ? separator : ",";
	var data = "";
	var childNodes = parentElement.elements;
	var count = 0;
	for (var i = 0; i < childNodes.length; i++) {
		var node = childNodes[i];
		if (node.tagName == "INPUT" && (!inputType || node.getAttribute("type") == inputType) && 
				node.getAttribute("name") == name && (!inputType || (inputType == "checkbox" && node.checked))) {
			if (maxNum && count == maxNum) {
				highlightElement(node, true);
				return false;
			} else {
				highlightElement(node, false);
			}
			data += data.length != 0 ? separator : "";
        	data += node.value;
        	count++;
		}
	}
	if (minNum && count < minNum) {
		return false;
	}	
    return data;
}
function toggleSelectAllCheckboxes(name, parentElement, canCheck) {
	parentElement = (parentElement) ? parentElement : document;
	var data = "";
	//alert(parentElement);
	var childNodes = parentElement.elements;
	//alert(childNodes);
	//alert(childNodes.length);
	for (var i = 0; i < childNodes.length; i++) {
		var node = childNodes[i];
		//alert(node.tagName + ", " + node.getAttribute("type") + ", " + node.getAttribute("name"));
		if (!node.disabled && node.tagName == "INPUT" && node.getAttribute("type") == "checkbox" && node.getAttribute("name") == name) {
			node.checked = canCheck;
		}
	}
    return data;
}
function showHide(objectName, showClass, hideClass) {
	showClass = (showClass) ? showClass : "down_arrow_link";
	hideClass = (hideClass) ? hideClass : "arrow_link";
	if (getObject(objectName+'_link')) { toggleClass(objectName+'_link', hideClass, showClass); }
	if (getObject(objectName+'_data')) { toggleObjects(objectName+'_data', objectName+'_data', 'block'); }
}
function mouseOverLink(link) {
	if (!link) { return; }
	var defaultLinkClass = link.getAttribute("defaultclass");
	if (defaultLinkClass == "headerlink" || defaultLinkClass == "menuitem") { link.className = "active" + defaultLinkClass; }
}
function mouseOutLink(link) {
	if (!link) { return; }
	var defaultLinkClass = link.getAttribute("defaultclass");
	if (defaultLinkClass == "headerlink" || defaultLinkClass == "menuitem") { link.className = defaultLinkClass; }
}
function navBlockShowHide(objectName, additionalHeight) {
	showHide(objectName);
	var navBlockContainer = getObject('navblockcontainer');
	additionalHeight = (additionalHeight) ? additionalHeight : 200;
	additionalHeight = (getObject(objectName+'_data').style.display == 'none') ? -additionalHeight : additionalHeight;
	navBlockContainer.style.height = parseInt(navBlockContainer.style.height) + additionalHeight + "px";
}
function setStateType(stateType, stateRequired) {
	var stateINPUT = getObject('usstate');
	if (stateINPUT) {
		stateINPUT.style.display = "none";
		stateINPUT.setAttribute("validate", "");
	}
	stateINPUT = getObject('castate');
	if (stateINPUT) {
		stateINPUT.style.display = "none";
		stateINPUT.setAttribute("validate", "");
	}
	stateINPUT = getObject('otstate');
	if (stateINPUT) {
		stateINPUT.style.display = "none";
		stateINPUT.setAttribute("validate", "");
	}
	stateINPUT = getObject(stateType+'state');
	if (stateINPUT) {
		stateINPUT.style.display = "inline";
		stateINPUT.setAttribute("validate", stateRequired ? "isValid" : "");
		getObject('state').value = stateINPUT.value;
	}
	if (getObject('cc')) {	
		getObject('cc').value= (stateType != 'ot') ? stateType : "";
	}
	if (getObject('country')) {	
		getObject('country').value= (stateType != 'ot') ? stateType : "";
	}
}// Ver .91 Feb 21 1998
//////////////////////////////////////////////////////////////
//
//	Copyright 1998 Jeremie
//	Free for public non-commercial use and modification
//	as long as this header is kept intact and unmodified.
//	Please see http://www.jeremie.com for more information
//	or email jer@jeremie.com with questions/suggestions.
//
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
////////// Simple XML Processing Library //////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
////   Fully complies to the XML 1.0 spec 
////   as a well-formed processor, with the
////   exception of full error reporting and
////   the document type declaration(and it's
////   related features, internal entities, etc).
///////////////////////////////////////////////////////////////


/////////////////////////
//// the object constructors for the hybrid DOM

function _element()
{
	this.type = "element";
	this.name = new String();
	this.attributes = new Array();
	this.contents = new Array();
	this.uid = _Xparse_count++;
	_Xparse_index[this.uid]=this;
}

function _chardata()
{
	this.type = "chardata";
	this.value = new String();
}

function _pi()
{
	this.type = "pi";
	this.value = new String();
}

function _comment()
{
	this.type = "comment";
	this.value = new String();
}

// an internal fragment that is passed between functions
function _frag()
{
	this.str = new String();
	this.ary = new Array();
	this.end = new String();
}

/////////////////////////


// global vars to track element UID's for the index
var _Xparse_count = 0;
var _Xparse_index = new Array();


/////////////////////////
//// Main public function that is called to 
//// parse the XML string and return a root element object

function Xparse(src)
{
	var frag = new _frag();

	// remove bad \r characters and the prolog
	frag.str = _prolog(src);

	// create a root element to contain the document
	var root = new _element();
	root.name="ROOT";

	// main recursive function to process the xml
	frag = _compile(frag);

	// all done, lets return the root element + index + document
	root.contents = frag.ary;
	root.index = _Xparse_index;
	_Xparse_index = new Array();
	return root;
}

/////////////////////////


/////////////////////////
//// transforms raw text input into a multilevel array
function _compile(frag)
{
	// keep circling and eating the str
	while(1)
	{
		// when the str is empty, return the fragment
		if(frag.str.length == 0)
		{
			return frag;
		}

		var TagStart = frag.str.indexOf("<");

		if(TagStart != 0)
		{
			// theres a chunk of characters here, store it and go on
			var thisary = frag.ary.length;
			frag.ary[thisary] = new _chardata();
			if(TagStart == -1)
			{
				frag.ary[thisary].value = _entity(frag.str);
				frag.str = "";
			}
			else
			{
				frag.ary[thisary].value = _entity(frag.str.substring(0,TagStart));
				frag.str = frag.str.substring(TagStart,frag.str.length);
			}
		}
		else
		{
			// determine what the next section is, and process it
			if(frag.str.substring(1,2) == "?")
			{
				frag = _tag_pi(frag);
			}
			else
			{
				if(frag.str.substring(1,4) == "!--")
				{
					frag = _tag_comment(frag);
				}
				else
				{
					if(frag.str.substring(1,9) == "![CDATA[")
					{
						frag = _tag_cdata(frag);
					}
					else
					{
						if(frag.str.substring(1,frag.end.length + 3) == "/" + frag.end + ">" || _strip(frag.str.substring(1,frag.end.length + 3)) == "/" + frag.end)
						{
							// found the end of the current tag, end the recursive process and return
							frag.str = frag.str.substring(frag.end.length + 3,frag.str.length);
							frag.end = "";
							return frag;
						}
						else
						{
							frag = _tag_element(frag);
						}
					}
				}
			}

		}
	}
	return "";
}
///////////////////////


///////////////////////
//// functions to process different tags

function _tag_element(frag)
{
	// initialize some temporary variables for manipulating the tag
	var close = frag.str.indexOf(">");
	var empty = (frag.str.substring(close - 1,close) == "/");
	if(empty)
	{
		close -= 1;
	}

	// split up the name and attributes
	var starttag = _normalize(frag.str.substring(1,close));
	var nextspace = starttag.indexOf(" ");
	var attribs = new String();
	var name = new String();
	if(nextspace != -1)
	{
		name = starttag.substring(0,nextspace);
		attribs = starttag.substring(nextspace + 1,starttag.length);
	}
	else
	{
		name = starttag;
	}

	var thisary = frag.ary.length;
	frag.ary[thisary] = new _element();
	frag.ary[thisary].name = _strip(name);
	if(attribs.length > 0)
	{
		frag.ary[thisary].attributes = _attribution(attribs);
	}
	if(!empty)
	{
		// !!!! important, 
		// take the contents of the tag and parse them
		var contents = new _frag();
		contents.str = frag.str.substring(close + 1,frag.str.length);
		contents.end = name;
		contents = _compile(contents);
		frag.ary[thisary].contents = contents.ary;
		frag.str = contents.str;
	}
	else
	{
		frag.str = frag.str.substring(close + 2,frag.str.length);
	}
	return frag;
}

function _tag_pi(frag)
{
	var close = frag.str.indexOf("?>");
	var val = frag.str.substring(2,close);
	var thisary = frag.ary.length;
	frag.ary[thisary] = new _pi();
	frag.ary[thisary].value = val;
	frag.str = frag.str.substring(close + 2,frag.str.length);
	return frag;
}

function _tag_comment(frag)
{
	var close = frag.str.indexOf("-->");
	var val = frag.str.substring(4,close);
	var thisary = frag.ary.length;
	frag.ary[thisary] = new _comment();
	frag.ary[thisary].value = val;
	frag.str = frag.str.substring(close + 3,frag.str.length);
	return frag;
}

function _tag_cdata(frag)
{
	var close = frag.str.indexOf("]]>");
	var val = frag.str.substring(9,close);
	var thisary = frag.ary.length;
	frag.ary[thisary] = new _chardata();
	frag.ary[thisary].value = val;
	frag.str = frag.str.substring(close + 3,frag.str.length);
	return frag;
}

/////////////////////////


//////////////////
//// util for element attribute parsing
//// returns an array of all of the keys = values
function _attribution(str)
{
	var all = new Array();
	while(1)
	{
		var eq = str.indexOf("=");
		if(str.length == 0 || eq == -1)
		{
			return all;
		}

		var id1 = str.indexOf("\'");
		var id2 = str.indexOf("\"");
		var ids = new Number();
		var id = new String();
		if((id1 < id2 && id1 != -1) || id2 == -1)
		{
			ids = id1;
			id = "\'";
		}
		if((id2 < id1 || id1 == -1) && id2 != -1)
		{
			ids = id2;
			id = "\"";
		}
		var nextid = str.indexOf(id,ids + 1);
		var val = str.substring(ids + 1,nextid);

		var name = _strip(str.substring(0,eq));
		all[name] = _entity(val);
		str = str.substring(nextid + 1,str.length);
	}
	return "";
}
////////////////////


//////////////////////
//// util to remove \r characters from input string
//// and return xml string without a prolog
function _prolog(str)
{
	var A = new Array();

	A = str.split("\r\n");
	str = A.join("\n");
	A = str.split("\r");
	str = A.join("\n");

	var start = str.indexOf("<");
	var hdrPrefix  = str.substring(start,start + 3);
	var xmlPrefixA = "<" + "?" + "x";
	var xmlPrefixB = "<" + "?" + "X";
	if (hdrPrefix == xmlPrefixA || hdrPrefix == xmlPrefixB) {
		var close = str.indexOf("?>");
		str = str.substring(close + 2,str.length);
	}
	var start = str.indexOf("<!DOCTYPE");
	if(start != -1)
	{
		var close = str.indexOf(">",start) + 1;
		var dp = str.indexOf("[",start);
		if(dp < close && dp != -1)
		{
			close = str.indexOf("]>",start) + 2;
		}
		str = str.substring(close,str.length);
	}
	return str;
}
//////////////////


//////////////////////
//// util to remove white characters from input string
function _strip(str)
{
	var A = new Array();

	A = str.split("\n");
	str = A.join("");
	A = str.split(" ");
	str = A.join("");
	A = str.split("\t");
	str = A.join("");

	return str;
}
//////////////////


//////////////////////
//// util to replace white characters in input string
function _normalize(str)
{
	var A = new Array();

	A = str.split("\n");
	str = A.join(" ");
	A = str.split("\t");
	str = A.join(" ");

	return str;
}
//////////////////


//////////////////////
//// util to replace internal entities in input string
function _entity(str)
{
	var A = new Array();

	A = str.split("&lt;");
	str = A.join("<");
	A = str.split("&gt;");
	str = A.join(">");
	A = str.split("&quot;");
	str = A.join("\"");
	A = str.split("&apos;");
	str = A.join("\'");
	A = str.split("&amp;");
	str = A.join("&");

	return str;
}
//////////////////
