/*
 * @version $Revision: 1.4 $
 * @internal Log of Changes:
 *           $Log: MiscMethods.js,v $
 *           Revision 1.4  2005/08/01 20:11:55  chilt
 *           Removed debug alerts
 *
 *           Revision 1.3  2005/07/27 17:09:09  greg.guerin
 *           Added new methods to use.
 *
 *           Revision 1.2  2003/05/21 20:57:24  schohan
 *           Added Encode and Decode functions for Plus (+) sign
 *
 *           Revision 1.1.1.1  2001/12/10 21:37:38  tbarrile
 *           Clean import
 *
 *           Revision 1.11  2001/05/15 15:16:55  dmayer
 *           Correct problem with parsing of return character
 *
 *           Revision 1.10  2001/05/15 03:30:49  dmayer
 *           Added logic to escape the "\" character
 *
 *           Revision 1.9  2001/02/22 15:46:32  ldion
 *           Modified to add the applet html name to the dynamic resize call
 *
 *           Revision 1.8  2000/09/26 15:26:12  jstamper
 *           Added support for multi-line encoding for XML
 *
 *           Revision 1.7  2000/09/25 19:30:31  jstamper
 *           TCB - Added decoding function
 *
 *           Revision 1.6  2000/09/06 20:42:30  jstamper
 *           added ' HTML encoding
 *
 *           Revision 1.5  2000/09/06 15:39:41  jstamper
 *           fixed String constructor typo
 *
 *           Revision 1.4  2000/09/06 12:27:50  jstamper
 *           Add HTMLEncode function /TB
 *
 *           Revision 1.3  2000/08/25 04:44:06  ldion
 *           Added cvs revision tags
 *
 */

function setBusy(message) {
	if (message == null) {
		document.all.busyMessageBox.style.display = "none";
		document.all.busyMessage.innerHTML = '&nbsp;';
		document.body.style.cursor = "default";
		document.all.busyMessage.style.cursor = "default";
		}
	else {
		// Center busy box position
		document.all.busyMessageBox.style.pixelTop = (document.body.clientHeight - document.all.busyMessageBox.style.pixelHeight) / 2;
		document.all.busyMessageBox.style.pixelLeft = (document.body.clientWidth - document.all.busyMessageBox.style.pixelWidth) / 2;

		document.all.busyMessage.innerHTML = '<B>' + message + '</B>';
		document.all.busyMessageBox.style.display = "block";
		document.body.style.cursor = "wait";
		document.all.busyMessage.style.cursor = "wait";
		window.focus();
		}
	return true;
}
function formatStrip(aValue){
	aValue += '';
	aValue = aValue.replace(/[%,$]/g,'');
	return aValue;
}
function formatPercentage(aValue){
	aValue += '';
	aValue = aValue.replace(/[%]/g,'');
	var sReturn = formatValue(aValue);
	return "%" + sReturn;
}
function formatCurrency(aValue,aPrecision){
	aValue += '';
	aValue = aValue.replace(/[$]/g,'');
	if (aPrecision == null){
		aPrecision = 2;			//Default to two decimal places
	}
	var sReturn = formatValue(aValue,aPrecision);
	return "$" + sReturn;
}
function formatValue(aValue,aPrecision){
	//Format the value as "999,999,999.999"
	aValue += "";
	aValue = aValue.replace(/[,]/g,'');
	if (isNaN(aValue)) return ("#INVALID");
	//if ((!aPrecision) || (aPrecision == '')){
	if (aPrecision == null){
		aPrecision = 2;			//Default to two decimal places
	}
	var iLen = aValue.length;
	aValue = Math.round(aValue*Math.pow(10,aPrecision))/Math.pow(10,aPrecision);
	aValue += "";
	var iDecPos = aValue.indexOf(".");

	var sFraction = '';
	if (iDecPos == -1){
		iDecPos = aValue.length;
	}else{
		sFraction = aValue.substr(iDecPos + 1,aPrecision);
	}
	while (sFraction.length < aPrecision){
		sFraction += '0';
	}

	var sWhole = aValue.substr(0,iDecPos);
	if (sWhole.length == 0){
		sWhole = '0';
	}
	var sReturn = '';
	var iWholeLen = sWhole.length;
	for (var i=iWholeLen;i>0;i--){
		if (((iWholeLen - i) % 3) == 0){
			sReturn = "," + sReturn;
		}
		sReturn = sWhole.charAt(i-1) + sReturn;
	}
	//The following code removes the left most , if it shouldn't be there
	var bNeg = sWhole.indexOf('-') > -1;
	if (bNeg && ((iWholeLen-1) % 3) == 0){
		sReturn = sReturn.replace(/,/i,'');
	}
	sReturn = sReturn.substr(0,sReturn.length - 1);
	if (aPrecision > 0){
		sReturn += "." + sFraction;
	}
	return sReturn;
}
function HTMLEncode(str){
	var values = new String();
	values = str.toString();
	str = values.replace(/\x26/g,"&amp;");
	values = str.replace(/\x3C/g,"&lt;");
	str = values.replace(/\x3E/g,"&gt;");
	values = str.replace(/\x22/g,"&quot;");
	str=values.replace(/\x27/g,"&#39;");
	values = str.replace(/\x0A/g,"\\n");
	str = values.replace(/\x0D/g,"\\r");
	return str.toString();
}
function HTMLDecode(str){
	var values = new String();
	values = str.toString();
	values = str.replace(/\x26\x2347\x3B/g,"\\\\");
	str = values.replace(/\x26amp\x3B/g,"&");
	values = str.replace(/\x26lt\x3B/g,"<");
	str = values.replace(/\x26gt\x3B/g,">");
	values = str.replace(/\x26quot\x3B/g,"\\\"");
	str=values.replace(/\x26\x2339\x3B/g,"\\\'");
	return str.toString();

}

/*
 * This method will resize the html applet object (not the Applet class container within)
 * using the specified dimensions, on the specified applet object
 */
function resizeApplet(applet,height,width){
	document.all[applet].height = height;
	document.all[applet].width = width;
	//document.all.FolderViewApplet.height = height;
	//document.all.FolderViewApplet.width = width;
}

/**
 * Encode Plus signs (+) into the ascii symbol $#43;
 *
 * @param String String to encode.
 * @return String Encoded string.
 */
function encodePlus(strParam)  {
	var str = new String(strParam);
	if (str.indexOf('+') > -1)  {
	 	i = -1;
		while ((i = str.indexOf('+',++i)) != -1) {
			str = str.substring(0, i) + '%2B' + str.substring(i + 1);
		}
	}
   return str;
}

/**
 * Decode ascii symbol $#43; into Plus signs (+)  
 *
 * @param String String to Decode.
 * @return String Decoded string.
 */
function decodePlus(strParam)  {
	var str = new String(strParam);
	if (str.indexOf('%2B') > -1)  {
	 	i = -1;
		while ((i = str.indexOf('%2B',++i)) != -1) {
			str = str.substring(0, i) + '+' + str.substring(i + 1);
		}
	}
   return str;
}	



/* This function will return a string with removed leading and trailing spaces from a string.
Remember that this trim method doesn't change the string it's
invoked on (JavaScript doesn't allow that) but returns a trimmed copy of
it self. Therefore we need to do it like: 
str = str.trim()

The trim function is added to the String prototype, so it is available to all String objects in which this js file is included.
*/
function trim() {
  // Remove leading spaces
  var s = this.replace(/^\s+/g, "")
  // Remove trailing spaces
  s = s.replace(/\s+$/g, "")
  return s
}
String.prototype.trim = trim;

/* 
	This applies an edit check to truncate a value based on the limit.
	Typically this will be a function call on a onkeyup event, or an onchange event.
*/
function checkSize(obj, limit){
	if (!obj.value) return;
	if (obj.value.length > limit){
		alert('This field may only be ' + limit + ' characters long.');
		obj.value = obj.value.substr(0,limit);
		return false;
	}	
	return true;
}


/* 
	This will verify that the value is numeric, and will refocus the component if it is not
	If the optional second (lower limit) and third (upper limit) parameters are specified, the
	value must be between (inclusive) the values.
        Valid numeric format is (+/-)#,###,###.####
*/
function checkFormattedNumeric(obj,lower,upper){
	if (!obj.value) return true;
        var val = obj.value;
//        var re = /^(\+|\-)?(((\d{1,3},)?(\d{3},)*\d{3})|(\d{1,3}))(\.\d+)?$/; //Format as (+/-)#,###,###.####
        var re = /^(\+|\-)?(((\d{1,3},)?(\d{3},)*\d{3})|(\d{1,3}))$/; //Format as (+/-)#,###,###.####
        if (!re.test(val)){
			alert('This field must be a numeric value in the form "#,###"');
			obj.focus();
			return false;
		}
        val = formatStrip(val);
        if (!checkNumericBoundary(val,lower,upper)){
            obj.focus();
            return false;
        }
        return true;
}

/* 
	This will verify that the value is numeric, and will refocus the component if it is not
	If the optional second (lower limit) and third (upper limit) parameters are specified, the
	value must be between (inclusive) the values.
        Valid unformatted numeric format is #######.####
        This method is "deprecated" (as deprecated as you can be in js), use checkUnformattedNumeric instead
*/
function checkNumeric(obj,lower,upper){
    return checkUnformattedNumeric(obj,lower,upper);
}

/* 
	This will verify that the value is numeric, and will refocus the component if it is not
	If the optional second (lower limit) and third (upper limit) parameters are specified, the
	value must be between (inclusive) the values.
        Valid unformatted numeric format is #######.####
*/
function checkUnformattedNumeric(obj,lower,upper){
	var val = obj.value==null?obj:obj.value;
    //var re = /^(\+|\-)?\d+(\.\d+)?$/; //Format as (+/-)#######.####
    var re = /^(\+|\-)?\d+$/; //Format as (+/-)#######.####
    if (!re.test(val)){
		alert('This field must be a numeric value in the form "####".');
		return false;
	}
    return checkNumericBoundary(val,lower,upper);
}
/* 
    This function will perform the boundary checks on a number.
    The	value must be between (inclusive) the values.
    It returns true if the val parameter falls between (or on) the upper and/or lower limit.
    Either upper or lower may be excluded to enable this function to perform as a floor or ceiling function.
*/
function checkNumericBoundary(val,lower,upper){
	if (lower != null){
		if (parseFloat(val) < lower){
			alert('This field must be at least ' + lower + '.');
			return false;
		}
	}
	if (upper != null){
		if (parseFloat(val) > upper){
			alert('This field must be at most ' + upper + '.');
			return false;
		}
	}
	return true;
}

/* 
	This function will check that the number is an integer, i.e. no decimal points.
	Returns false if the number is a float, true if it is an integer.
*/
function checkInteger(val){
	return parseInt(val) == val;
}
/*
	This function will make an html element, or array of same-named elements disappear/reappear.
*/
function toggleGroup(parmName,img,display) {
    var obj, arr;
    obj = document.all[parmName];
    if (!obj.length){
    	arr = new Array();
    	arr[0] = obj;
    }else{
    	arr = obj;
    }
    for (var i=0;i<arr.length;i++){
	    display = display?display:(!arr[i].style.display?"none":(arr[i].style.display == "inline"?"none":"inline"));
	    arr[i].style.display = display;
	}
    img.src = display == "inline"?"images/minus.gif":"images/plus.gif";
    resizeEvent();
}//end toggleGroup function

/*
  Either checks all or unchecks all checkboxes that are part of the object array specified
*/
function toggleSelected(selfRef,obj) {
	if (selfRef.checked) {
		selectAll(obj,true);	
	} else {
		selectAll(obj,false);	
	}
}

/*
 Assumes the object parameter is either a toggle widget, or an array of them.
*/
function selectAll(obj,bChecked){
	var arr;
	if (!obj.length){
		arr = new Array();
		arr[0] = obj;
	}else{
		arr = obj;
	}
	for (var i=0;i<arr.length;i++){
		if (arr[i].checked == null) continue;
		if (arr[i].disabled) continue;
		arr[i].checked = bChecked;
	}
}

/*
 Assumes the object parameter is a select component that contains option elements, or an array of them.
*/
function selectAllOptions(obj,bChecked){
	for (var i=0;i<obj.length;i++){
		obj.options[i].selected = bChecked;
	}
}

/*
 Assumes the object parameter is a select component that contains option elements, or an array of them.
*/
function getSelectedOptions(obj){
	var selectedOptions = new Array();
	for (var i=0;i<obj.length;i++){
		if (obj.options[i].selected) selectedOptions[selectedOptions.length] = i;
	}
	if (selectedOptions.length == 0) selectedOptions[0] = -1;	
	return selectedOptions;
}

/*
 Assumes the object parameter is a select component that contains option elements, or an array of them.
*/
function getSelectedOptionValues(obj){
	var selectedOptions = new Array();
	for (var i=0;i<obj.length;i++){
		if (obj.options[i].selected) selectedOptions[selectedOptions.length] = obj.options[i].value;
	}
	return selectedOptions;
}


function getSelectedRadio(buttonGroup) {
   // returns the array number of the selected radio button or -1 if no button is selected
   if (buttonGroup[0]) { // if the button group is an array (one button is not an array)
      for (var i=0; i<buttonGroup.length; i++) {
         if (buttonGroup[i].checked) {
            return i;
         }
      }
   } else {
      if (buttonGroup.checked) { return 0; } // if the one button is checked, return zero
   }
   // if we get to this point, no radio button is selected
   return -1;
} // Ends the "getSelectedRadio" function

/* This function is used in BOTH radio buttons and checkboxes */
function getFormGroup(name) {
	return document.getElementsByName(name);
}

function getRadio(name) {
	elements = getFormGroup(name);
	if (elements)/* loop over all the radio buttons */
	for (i = 0; i < elements.length; i++) if (elements[i].checked)return elements[i];
	/* either no group by that name was foundor none were selected */
	return null;
}

function getRadioValue(name) {
	element = getRadio(name);
	if (element)return element.value;
	/* there must not have been a radio buttonselected */
	return '';
}


/* 
	Utilize the method to set a page to indicated it has been posted.
*/
function disablePage(message) {
	self.status = message;
	document.title = message;
	window.setTimeout("document.body.className = 'pageDimmer';",1);
}

//This method assumes there is a "headerFrame", "dataContainer" and "bottomObj" object on the page.
function adjustDataTable() {
	//Height is determined by adding the distance from the bottom button to the bottom of the screen
	if (document.all.bottomObj != null) {
		document.all.bottomObj.style.display='inline';
		var height = document.body.clientHeight - document.all.bottomObj.offsetTop;
		height += parseInt(document.all.dataContainer.style.height) - 5;
		var iOffset = 0;
		if (document.getElementById("headerFrame").style.display != 'none') {			
			iOffset = parseInt(document.getElementById("headerFrame").clientHeight);
		}
		height -= iOffset;
		document.all.dataContainer.style.height = height;
		document.all.bottomObj.style.display='none';
	}
}

/* This function opens new window. Title and contents are required parameter */
function showDesc(title, description)
{
	var w = self.open("", "", "width=300, height=200, resizable=yes");
	w.focus();
	var d = w.document;
	d.write('<HTML>');
	d.write('<HEAD>');
	d.write('<title>'+title+'</title>');
	d.write('</HEAD>');
	d.write('<H3>'+title+'</H3><p>');
	d.write(''+description+'');
	d.write('</HTML>');
}
