/* COMMON DHTML FUNCTIONS by Geesquare Technologies */

/****************************************
 *			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) {

    width	= (width)  ? width	: "750px";
    height	= (height) ? height	: "350px";
    name	= (name)   ? name	: "_blank";

	// 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=yes,toolbar=no,scrollbars=yes,menubar=no,location=no", bReplace);
    newWindow.moveTo(newLeft, newTop);
    newWindow.focus();
}
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; 
}

/****************************************
 *			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(floatValue, fractionDigits) : floatValue;
	return floatValue;
}
			            
function formatDouble(val) {
	
	var pattern = ",";
	var interval = 3;
	var str = (val instanceof String) ? val : new String(val);
	
	var mantissa = "";	
	var exponentLength = str.indexOf('.');
	if (exponentLength != -1) {
		mantissa = str.substring(exponentLength, str.length);
	} else {
    	exponentLength = str.length;
	}
	
	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 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 formSubmit(form, action) {

	var elements = form.elements;
	for (var i = 0; i < elements.length; i++) {
		var objElement = elements[i];
		if (objElement.type != 'hidden' && !isFormDataValid(objElement)) {
			return;
		}
    }
	form.target = (form.target) ? form.target : "_self";
	form.action	= (action) ? action : document.location;
	form.submit();
}
function isFormDataValid(objElement)  {
	
	var isValid = true;
	
	// Check for the existence of a validation function
	var callback = objElement.getAttribute("validate");
    if (callback && (callback = eval("window."+callback))) {
		if (!callback.call(objElement, objElement.value)) {
			highlightElement(objElement, true);
			var errmsg = objElement.getAttribute("errmsg");
			alert(errmsg ? errmsg : "The highlighted item contains an invalid value. Please amend it then retry.");
			isValid = false;
		} else {
			highlightElement(objElement, false);
		}
    }
	return isValid;
}

/****************************************
 *			DATA VALIDATION				*
 ****************************************/
var LEGAL_NUMBERS		= '0123456789';
var LEGAL_DECIMALS		= LEGAL_NUMBERS + '.-,';
var LEGAL_HEXADECIMALS 	= LEGAL_NUMBERS + 'ABCDEFabcdef';
var LEGAL_PRINTABLES 	= LEGAL_DECIMALS + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefefghijklmnopqrstuvwxyz';
function isValidDecimal(string) {
    return isValid(string, LEGAL_DECIMALS);
}
function isValidPrintable(string) {
	return isValid(string, LEGAL_PRINTABLES);
}
function isValidPrintableName(string) {
	return isValid(string.Trim(), LEGAL_PRINTABLES + ' ');
}
function isValidString(string) {
	return isValid(string);
}
function isValid(string, allowed) {
    if (string == null || string == undefined || (string = trimString(string)) == "") {
    	return false;
    }
    for (var i=0; allowed && i < string.length; i++) {
        if (allowed.indexOf(string.charAt(i)) == -1) {
            return false;
        }
    }
    return true;
}
function isValidDate(string, allowed) {
	var sections= string.split('-');
	var yyyy	= sections[0];
	var mm		= sections[1];
	var dd		= sections[2];

    return (yyyy && yyyy.length == 4 && isValid(yyyy, LEGAL_NUMBERS) &&
    		mm && mm.length == 2 && isValid(mm, LEGAL_NUMBERS) &&
    		dd && dd.length == 2 && isValid(dd, LEGAL_NUMBERS));
}

/****************************************
 *			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 = getXMLHTTPObject();
function getXMLHTTPObject() {
	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 getDefaultXMLHttpObject() {
	return xmlHttpObject;
}
function xmlHttpLoadData(xmlHttp, url, responseHandler, abortPendingCalls) {
	abortPendingCalls = (abortPendingCalls == null) ? true : abortPendingCalls;
	if (abortPendingCalls || !xmlCallInProgress(xmlHttp)) {
		try {
			xmlHttp.open("GET", url, true);
			xmlHttp.onreadystatechange = responseHandler;
			xmlHttp.send(null);
			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';
	}
}

/****************************************
 *				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) {
		objShow.style.display = (type != null) ? type : "inline";
	}
	if (objHide) {
		objHide.style.display = "none";
	}
}
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 replaceOption(selectList, optionValue, optionText, index) {
    addOption(selectList, optionValue, optionText, index, true, true);
}
function addOption(selectList, optionValue, optionText, index, isSelected, canReplace) {
    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 clearOptions(selectList, optionValue) {
	var opts = selectList.options;
	while (opts.length > 0) {
	    if (opts.remove) {
	    	opts.remove(0);
	    } else {
	    	opts[0]=null;
	    }
	}
}
function findOption(selectList, optionValue) {
    var index = findOptionIndex(selectList, optionValue);
    if (index != -1) {
    	return selectList.options.item(index);    
    }
    return 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 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;
    }
}
