/*
* These materials contain confidential information and 
* trade secrets of Compuware Corporation.  You shall 
* maintain the materials as confidential and shall not 
* disclose its contents to any third party except as may 
* be required by law or regulation.  Use, disclosure, 
* or reproduction is prohibited without the prior express 
* written permission of Compuware Corporation.
* 
* All Compuware products listed within the materials are 
* trademarks of Compuware Corporation.  All other company 
* or product names are trademarks of their respective owners.
* 
* Copyright (c) 2010 Compuware Corporation.  All rights reserved.
* 
*/
function inJsValidate_GetDString(Str_s, Str_r1, Str_r2, Str_r3)
{
	var ds;

    ds = Str_s.replace(unescape("%ffx%ff"), Str_r1);
    if (Str_r2 != "")
    	ds = ds.replace(unescape("%ffy%ff"), Str_r2);
    if (Str_r3 != "")
    	ds = ds.replace(unescape("%ffz1%ff"), Str_r3);    	

	return ds;
}


// encode as HTML tags.
function ConvToHTML(str)
{
	var s = String(str);
	
	if ( s == "" )
		return s;

	// Temporary change the ignore list (<br>, <b>, </b>, <i>, </i>, <strong>, </strong>)
	var re = /\<br\>/gi;				// <br>
	s = s.replace(re, "|br|");
	re = /\<b\>/gi;						// <b>
	s = s.replace(re, "|b|");
	re = /\<\/b\>/gi;					// </b>
	s = s.replace(re, "|/b|");
	re = /\<i\>/gi;						// <i>
	s = s.replace(re, "|i|");
	re = /\<\/i\>/gi;					// </i>
	s = s.replace(re, "|/i|");
	re = /\<strong\>/gi;				// <strong>
	s = s.replace(re, "|strong|");
	re = /\<\/strong\>/gi;				// </strong>
	s = s.replace(re, "|/strong|");

	// Convert to HTML
	re = /\&/g;							// &
	s = s.replace(re, "&amp;");
	re = /\"/g;							// "
	s = s.replace(re, "&quot;");
	re = /\'/g;							// '
	s = s.replace(re, "&#39;");
	re = /\</g;							// <
	s = s.replace(re, "&lt;");
	re = /\>/g;							// >
	s = s.replace(re, "&gt;");
	
	// Put back the ignore list (<br>, <b>, </b>, <i>, </i>, <strong>, </strong>)
	re = /\|br\|/g;						// |br|
	s = s.replace(re, "<br>");
	re = /\|b\|/g;						// |b|
	s = s.replace(re, "<b>");
	re = /\|\/b\|/g;					// |/b|
	s = s.replace(re, "</b>");
	re = /\|i\|/g;						// |i|
	s = s.replace(re, "<i>");
	re = /\|\/i\|/g;					// |/i|
	s = s.replace(re, "</i>");
	re = /\|strong\|/g;					// |strong|
	s = s.replace(re, "<strong>");
	re = /\|\/strong\|/g;				// |/strong|
	s = s.replace(re, "</strong>");

	// Special case: Allow brackets for GlobDString, GetDString parameters.
	re = /\|\&amp\;\|/g;				// |&amp;|
	s = s.replace(re, "&");
	re = /\|\&quot\;\|/g;				// |&quot;|
	s = s.replace(re, "\"");
	re = /\|\&\#39\;\|/g;				// |&#39;|
	s = s.replace(re, "'");
	re = /\|\&lt\;\|/g;					// |&lt;|
	s = s.replace(re, "<");
	re = /\|\&gt\;\|/g;					// |&gt;|
	s = s.replace(re, ">");
   	
	return s;
}

// encode as HTML tags, including the ignore list in ConvToHTML
function ConvToHTMLAll(str)
{
	var s = String(str);
	
	if ( s == "" )
		return s;

	// Convert to HTML
	re = /\&/g;							// &
	s = s.replace(re, "&amp;");
	re = /\"/g;							// "
	s = s.replace(re, "&quot;");
	re = /\'/g;							// '
	s = s.replace(re, "&#39;");
	re = /\</g;							// <
	s = s.replace(re, "&lt;");
	re = /\>/g;							// >
	s = s.replace(re, "&gt;");

	return s;
}

// Convert Carriage Return and Line Feed characters to <BR> HTML tag.
function ConvCRtoBR(str)
{
	var s = String(str);
	if ( s == "" )
		return s;

	var re = /\r\n/gm;					// CR/LF
	s = s.replace(re, "<br>");
	re = /\r/gm;						// CR
	s = s.replace(re, "<br>");
	re = /\n/gm;						// CR/LF
	s = s.replace(re, "<br>");
}

// Convert <BR> HTML tag to Carriage Return and Line Feed characters.
function ConvBRtoCR(str)
{
	var s = String(str);
	if ( s == "" )
		return s;

	var re = /\<br\>/gim;				// BR
	s = s.replace(re, "\r\n");
}

// encodes the string to be used for passing 
function EncodeSymbol(str)
{
	var s = String(str);

    if (s == "")
        return s;

    s = escape(s);
	return s;
}

// used for encoding string being passed in URL.  The string is encoded as UTF-8 as opposed to UCS-2.
function CP_encodeURL(str)
{
	var s = String(str);

    if (s == "")
        return s;
        
	s = encodeURI(s);

	// since encodeURI does not encode the following symbols, encode them ourselves.
	//
	var re = /\&/g;					// & (0x26)
	s = s.replace(re, "%26");
	re = /\#/g;						// # (0x23)
	s = s.replace(re, "%23");
	re = /\'/g;						// ' (0x27)
	s = s.replace(re, "%27");
	re = /\+/g;						// + (0x2B)
	s = s.replace(re, "%2B");
	re = /\~/g;						// ~ (0x7E)
	s = s.replace(re, "%7E");

	return s;
}

// used to decode previously encoded URL string.
// Use only in combination with CP_encodeURL.  Otherwise, you may get a corrupted string.
function CP_decodeURL(str)
{
	var s = String(str);

    if (s == "")
        return s;
   
	s = decodeURI(s);

	// since dncodeURI does not decode the following symbols, decode them ourselves.
	//
	var re = /\%26/g;					// & (0x26)
	s = s.replace(re, "&");
	re = /\%23/g;						// # (0x23)
	s = s.replace(re, "#");
	re = /\%27/g;						// ' (0x27)
	s = s.replace(re, "'");
	re = /\%2B/g;						// + (0x2B)
	s = s.replace(re, "+");
	re = /\%7E/g;						// ~ (0x7E)
	s = s.replace(re, "~");

	return s;
}

var constEmpty = "";
var constWhiteSpace = " \t\n\r";	// whitespace characters
var daysInMonth = makeArray(12);

daysInMonth[1] = 31;
daysInMonth[2] = 29;   // must programmatically check this
daysInMonth[3] = 31;
daysInMonth[4] = 30;
daysInMonth[5] = 31;
daysInMonth[6] = 30;
daysInMonth[7] = 31;
daysInMonth[8] = 31;
daysInMonth[9] = 30;
daysInMonth[10] = 31;
daysInMonth[11] = 30;
daysInMonth[12] = 31;

function makeArray(n) {
    var tempArray = new Array(n);

    for (var i = 1; i <= n; i++) {
      tempArray[i] = 0;
    } 
    return tempArray;
}

function stripWhiteSpace(sw1sStr)
{   
	var sw1iCnt;
	var sw1sChr
	var sw1sReturn = "";
	
	if (isEmpty(sw1sStr))
		return "";
	
    // Search through string's characters one by one.
    // If character is not whilespace, append to sw1sReutrn.
    for (sw1iCnt = 0; sw1iCnt < sw1sStr.length; sw1iCnt++)
    {   
        // Check that current character isn't whitespace.
        sw1sChr = sw1sStr.charAt(sw1iCnt);
        if (constWhiteSpace.indexOf(sw1sChr) == -1) sw1sReturn += sw1sChr;
    }

    return sw1sReturn;
}

function checkRequired(cr1oElement) 
{
	// strip all while spaces in cr1oElement and check its length.
	if (isEmpty(stripWhiteSpace(cr1oElement)))
		return false;
	else
		return true;
}

function checkRequiredId(cr1oElement) 
{
	// to check if an id filed is empty or NullId
	if (isEmpty(stripWhiteSpace(cr1oElement)) || cr1oElement == "{00000000-0000-0000-0000-000000000000}")
		return false;
	else
		return true;
}

// checkMaxLen
function checkMaxLen(cm1sStr, cm1iMax)
{
	if (isEmpty(cm1sStr)) 
	{
		if (checkMaxLen.arguments.length == 2) 
			return constEmpty;
		else 
			return (checkMaxLen.arguments[2] == true);
	}

	if (cm1sStr.length <= cm1iMax)
		return true;
	else
		return false;	
}

function isEmpty(ie1s)
{   
	return ((ie1s == null) || (ie1s.length == 0))
}

function isDigit (id1sChar)
{   
	return ((id1sChar >= "0") && (id1sChar <= "9"))
}

// isIntegerINRange (STRING ii1s [, BOOLEAN emptyOK])
// 
// Returns true if all characters in string ii1s is between is1iFrom and is1iTo.
//
// Accepts non-signed integers only.
// is1iFrom and is1iTo must be non-signed integers.
function isIntegerInRange(is1sNum, is1iFrom, is1iTo)
{   
	if (isEmpty(is1sNum)) 
	{
		if (isIntegerInRange.arguments.length == 3) 
			return constEmpty;
		else 
			return (isIntegerInRange.arguments[3] == true);
	}

	if (!isInteger(is1sNum, false)) 
		return false;

    var is1iNum = parseInt(is1sNum);

		return ((is1iNum >= is1iFrom) && (is1iNum <= is1iTo));
}

// isInteger (STRING ii1s [, BOOLEAN emptyOK])
// 
// Returns true if all characters in string ii1s are numbers.
//
// Accepts non-signed integers only
function isInteger(ii1s)
{   
	var ii1iCnt;

    if (isEmpty(ii1s)) 
		if (isInteger.arguments.length == 1) 
			return constEmpty;
		else 
			return (isInteger.arguments[1] == true);

		for (ii1iCnt = 0; ii1iCnt < ii1s.length; ii1iCnt++)
		{   
			var ii1sChar = ii1s.charAt(ii1iCnt);
			// Updated by Richard Zhang Aug-21-2001: Allow negative integer.
			if (ii1iCnt == 0)
			{
				if (ii1sChar != "-")
					if (!isDigit(ii1sChar)) return false;
			}
			else
				if (!isDigit(ii1sChar)) return false;
		}
    // All characters are numbers.
    return true;
}

// isSignedInteger (STRING if1s)
// added by Judy Zhang on Jan. 25, 2001
// Returns true if string if1s is an signed Integer. 
function isSignedInteger(if1s)
{   
	if(isInteger(if1s)) return true;
	
	if(if1s.charAt(0)=="-"){
		if1s = if1s.substr(1,if1s.length-1);
		if(isInteger(if1s)) return true;
	}

    return false;
}

// isFloat (STRING if1s [, BOOLEAN emptyOK])
// 
// Returns true if string if1s is an unsigned floating point (real) number. 
function isFloat(if1s)
{ 
    if (isEmpty(if1s)) 
		if (isFloat.arguments.length == 1) 
			return constEmpty;
		else 
			return (isFloat.arguments[1] == true);

	if(!isNaN(CP_parseLocalNumber(if1s)))
		if1s = CP_parseLocalNumber(if1s).toString(10);
	else
		return false;

    return true;
}

// isSignedFloat (STRING if1s)
// 
// Returns true if string if1s is an signed floating point (real) number. 
function isSignedFloat(if1s)
{   
	if(isFloat(if1s)) return true;
	
	if(if1s.charAt(0)=="-"){
		if1s = if1s.substr(1,if1s.length-1);
		if(isFloat(if1s)) return true;
	}

    return false;
}

function isNumber(in1s)
{   
    if (isEmpty(in1s))
        return false;
        
    //Ensures that when a guid is passed in that it fails the test.  Under certain conditions isFloat can report guid as true.
    if(in1s.toString().indexOf("-") != in1s.toString().lastIndexOf("-") )
        return false;
     
	return (isInteger(in1s) || isFloat(in1s))
}

function isFloatInRange(if1sNum, if1iFrom, if1iTo)
{   
	if (isEmpty(if1sNum)) 
	{
		if (isFloatInRange.arguments.length == 3) 
			return constEmpty;
		else 
			return (isFloatInRange.arguments[3] == true);
	}

	if (!isFloat(if1sNum, false)) 
		return false;

    var if1iNum = CP_parseLocalNumber(if1sNum);
		return ((if1iNum >= if1iFrom) && (if1iNum <= if1iTo));
}

function roundDecimal(nNumber, nDecimals) 
{
	// This function assume the nNumber is a number in North American formating
	// with "." as the decimal point symbol.

	var sInteger = "";
	var sDecimal = "";
	var nNumLen;
	var nDecLen;
	var newNumber;
	var locDecimal;
	var sTemp1;
	var nTemp1;
	var nTemp2;
	var sPad;
	var bNegative;
	var iCnt;

	if(isNaN(nNumber))
		return nNumber;

	if (nNumber < 0)
		bNegative = true;

	newNumber = String(nNumber);

	// Deal with scientific notation number...
	newNumber = newNumber.toLowerCase();
	if (newNumber.indexOf("e") > -1)
	{
		var sNum = SciNotation2NumberString( newNumber );
		if (sNum != "NaN")
			newNumber = sNum;
		else
			return nNumber;
	}

	if (nDecimals < 0)
		return nNumber;
	else
	{
		nNumLen = newNumber.length;					// Length of the number
		locDecimal = newNumber.indexOf(".");		// Location of decimal point

		if (locDecimal == -1)
			return nNumber;							// no decimal at all
		else
		{
			// if decimal point exists, separate integer and decimal substrings.
			if (locDecimal > 0)
				sInteger = newNumber.substr(0, locDecimal);

			nDecLen = nNumLen - locDecimal - 1;		// Num of decimal digits

			if (nDecLen > 0)
				sDecimal = newNumber.substr(locDecimal+1, nDecLen);		// get the decimal portion
			else
				sDecimal = "";
				
			// Check for stupid JavaScript loss of precision case, which messes up rounding.
			if (nDecLen > nDecimals)
			{
				var sJavaScriptCrap = sDecimal.substr(nDecimals, nDecLen-nDecimals);
				if (sJavaScriptCrap.substr(0,4) == "4999")
				{
					sDecimal = sDecimal.substr(0,nDecimals)+"5";
					nDecLen = sDecimal.length;
				}
			}

			// If there are more decimal digits than requested, do the rounding of the decimal part.
			if (nDecLen > nDecimals)
			{
				sTemp1 = sDecimal.substr(0,nDecimals);
				nTemp1 = parseFloat(sTemp1);
				
				// check the next decimal digit over...
				nTemp2 = parseInt(sDecimal.charAt(nDecimals));
				if (nTemp2 >= 5)
				{
					nTemp1 += 1;
					sTemp1 = SciNotation2NumberString(nTemp1);
				}
				if (nDecimals > sTemp1.length)
				{
					// pad the leading zeros back, if required.
					sPad = ""
					for (iCnt = 0; iCnt < nDecimals-sTemp1.length; iCnt++)
						sPad += "0";
					sDecimal = sPad + sTemp1;	
				}
				else if (nDecimals < sTemp1.length)
				{
					// round up the integer portion.
					var nInt;
					nInt = parseInt(sInteger);
					if (bNegative)
						sInteger = String(nInt-1);
					else
						sInteger = String(nInt+1);
					sDecimal = "0";
				}
				else
					sDecimal = sTemp1;
			}
			newNumber = sInteger + "." + sDecimal;
		}
	}
	return Number(newNumber);
}

// isYear (STRING iy1s [, BOOLEAN emptyOK])
// 
// isYear returns true if string iy1s is a valid 
// Year number.  Must be 2 or 4 digits only.
function isYear(iy1s)
{   if (isEmpty(iy1s)) 
		if (isYear.arguments.length == 1) 
			return constEmpty;
		else 
			return (isYear.arguments[1] == true);
    
    if (!isInteger(iy1s)) 
		return false;
    	
//  return ((iy1s.length == 2) || (iy1s.length == 4));
	return iy1s.length < 5;
}

// isMonth (STRING im1s [, BOOLEAN emptyOK])
// 
// isMonth returns true if string im1s is a valid 
// month number between 1 and 12.
function isMonth(im1s)
{   if (isEmpty(im1s)) 
		if (isMonth.arguments.length == 1) 
			return constEmpty;
		else 
			return (isMonth.arguments[1] == true);

	return isIntegerInRange (im1s, 1, 12);
}

// isDay (STRING id1s [, BOOLEAN emptyOK])
// 
// isDay returns true if string id1s is a valid 
// day number between 1 and 31.
function isDay(id1s)
{   if (isEmpty(id1s)) 
		if (isDay.arguments.length == 1) 
			return defaultEmptyOK;
		else 
			return (isDay.arguments[1] == true);   
		
	return isIntegerInRange (id1s, 1, 31);
}

// daysInFebruary (INTEGER year)
// 
// Given integer argument year,
// returns number of days in February of that year.
function daysInFebruary (di1iYear)
{   // February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (  ((di1iYear % 4 == 0) && ( (!(di1iYear % 100 == 0)) || (di1iYear % 400 == 0) ) ) ? 29 : 28 );
}

// isDate (STRING date)
//
// isDate returns true if string date
// form a valid date.
// 
function isDate(date)
{
    if (isEmpty(date)) 
		if (isDate.arguments.length == 1) 
			return constEmpty;
		else 
			return (isDate.arguments[1] == true);
			
	var year, month, day, iYear, iMonth, iDay, icnt, itmp, tmpdate, separator, arrDate
	
	// find out what separator is
	date = stripWhiteSpace(date)
	tmpdate = date;
	while (isDigit(tmpdate.charAt(0)))	
		tmpdate=tmpdate.substring(1,tmpdate.length);
	separator = tmpdate.charAt(0);
	
	arrDate = date.split(separator);
	
	if (arrDate.length != 3)
		return false;
		
	if (isInteger(arrDate[0],false) && isInteger(arrDate[1],false) && isInteger(arrDate[2],false)) 	
		;
	else
		return false;	
	// parse month, day and year
	// default format is MM/DD/YYYY
	month = "";
	day = "";
	year = "";	
	iMonth = 0;
	iDay = 0;	
	iYear = 0;
    for (icnt=0; icnt<3; icnt++)
    {
		// get rid of 0 in front of a number
		itmp = arrDate[icnt];
		while (itmp.charAt(0) == "0" && itmp.length > 1)
			itmp=itmp.substring(1,itmp.length);		
		
		itmp = parseInt(itmp,10);		
		if (itmp == 0)
		{
			iYear++;	
			year = itmp+"";				
		}	
		else if (itmp < 13)
		{
			iMonth++;
			if (isEmpty(month))
				month = itmp+"";
			else if (isEmpty(day))
				day = itmp+"";
			else
				year = itmp+"";					
		}	
		else if (itmp < 32)	
		{
			iDay++;
			if (isEmpty(day))
				day = itmp+"";
			else
				year = itmp+"";				
		}		
		else
		{
			iYear++;	
			year = itmp+"";				
		}	
	}	

	if (iYear > 1 || iDay > 2)
	{
		return false;
	}	

	// index 0 is year, format has to be YY/MM/DD
	if (parseInt(arrDate[0],10)==year)
	{
//		if(parseInt(arrDate[1],10)!=month)
//			return false;
		;
	}
	// format could be MM/DD/YY or DD/MM/YY
	else if (parseInt(arrDate[2],10)==year)
		;
	// else YY is in the middle, return false 		
	else 
		return false;
		
//alert("m="+month+" d="+day+" y="+year);
	// catch invalid years (not 2- or 4-digit) and invalid months and days.
    if (! (isYear(year, false) && isMonth(month, false) && isDay(day, false))) return false;

    // Explicitly change type to integer to make code work in both
    // JavaScript 1.1 and JavaScript 1.2.
    var intYear = parseInt(year,10);
    var intMonth = parseInt(month,10);
    var intDay = parseInt(day,10);

    // catch invalid days, except for February
    if (intDay > daysInMonth[intMonth]) return false; 

    if ((intMonth == 2) && (intDay > daysInFebruary(intYear))) return false;

    return true;
}

function checkDate(sDate) {
	return !isNaN(Date.parse(sDate));
}

function ValidateRequiredField(oElement, sCaption) {
    var sValue;
        
    if (oElement.value == null)
        sValue = oElement;
    else
        sValue = oElement.value;
        
	if (!checkRequired(sValue))
	{		
		alert(inJsValidate_GetDString(jvmsgRequired, sCaption, ""));
		return false;
	}
	else
		return true;
}

// if an id filed is empty, give a warning message.
function ValidateRequiredId(oElement, sCaption) {
    var sValue;
        
    if (oElement.value == null)
        sValue = oElement;
    else
        sValue = oElement.value;
        
	if (!checkRequiredId(sValue))
	{
		//alert(sCaption + " is required.");
		alert(inJsValidate_GetDString(jvmsgRequired, sCaption, ""));
		return false;
	}
	else
		return true;
}

function ValidateMaxLen(oElement, sCaption, nLen) {
    var sValue;
        
    if (oElement.value == null)
        sValue = oElement;
    else
        sValue = oElement.value;
        
	if (!checkMaxLen(sValue, nLen) && (sValue != constEmpty))
	{
		//alert(sCaption + " cannot be longer than " + nLen + " characters.");
		alert(inJsValidate_GetDString(jvmsglong,sCaption,CP_formatNumber(nLen,0)));
		return false;
	}
	else
		return true;
}

function ValidateDate(oElement, sCaption) {
    var sValue;
        
    if (oElement.value == null)
        sValue = oElement;
    else
        sValue = oElement.value;
        
	if (!CP_isLocalDate(sValue))
	{
		//alert(sCaption + " is not a valid date.");
		alert(inJsValidate_GetDString(jvmsgBadDate,sCaption,""));
		return false;
	}
	else
		return true;
}

function ValidatePosNum(oElement, sCaption){
	var ret = false;
	var sValue;
        
    if (oElement.value == null)
        sValue = oElement;
    else
        sValue = oElement.value;
	
	if (sValue.length > 0)
	{
		var num = CP_parseLocalNumber(sValue);
		if ( !isNaN(num) && num > 0 )
			ret = true;
	}
	if (!ret)
	{
		if (isNaN(num))
		{
			//alert(sCaption + " is not a valid number.");
			alert(inJsValidate_GetDString(jvmsgBadNum,sCaption,""));
			return false;
		}
		else
		{
			//alert(sCaption + " must be a positive number.");
			alert(inJsValidate_GetDString(jvmsgGTZero,sCaption,""));
			return false;
		}
	}
	else
		return true;
}

function ValidatePosNumIncl0(oElement, sCaption){
	var ret = false;
    var sValue;
        
    if (oElement.value == null)
        sValue = oElement;
    else
        sValue = oElement.value;
	
	
	if (sValue.length > 0)
	{
		var num = CP_parseLocalNumber(sValue);
		if ( !isNaN(num) && num >= 0 )
			ret = true;
	}
	if (!ret)
	{
		if (isNaN(num))
		{			
			alert(inJsValidate_GetDString(jvmsgBadNum,sCaption,""));
			return false;
		}
		else
		{		
			alert(inJsValidate_GetDString(jvmsgGEZero,sCaption,""));
			return false;
		}
	}
	else
		return true;
}

function ValidateNumber(oElement, sCaption){
	
    var sValue;
        
    if (oElement.value == null)
        sValue = oElement;
    else
        sValue = oElement.value;
        	
	if (sValue.length > 0)
	{
		var num = CP_parseLocalNumber(sValue);
		if (isNaN(num))
		{
			//alert(sCaption + " is not a valid number.");
			alert(inJsValidate_GetDString(jvmsgBadNum,sCaption,""));
			return false;
		}
		else
			return true;
	}
}

// SciNotation2NumberString( nSciNum )
//
// Converts scientific notation number to a proper number string.
//
// Note: only the properly formated scientific notation will be processed.  If not proper, function returns "NaN".
//		Scientific Notation := {mantissa}e{exponent}
//								,where {mantissa} = decimal number between 1 and 10;
//								       {exponent} = integer
//
//		Ex.: 1.234e2 = 123.4, 1.234e-2 = 0.01234
//
// This function assume the "nSciNum" is a number in North American format
// with "." as the decimal point symbol.
//
function SciNotation2NumberString(nSciNum)
{
	var sReturn = "";
	var i;
	var sTemp = String(nSciNum);
	sTemp = sTemp.toLowerCase();
	var expLoc = sTemp.indexOf("e");
	if (expLoc > -1)
	{
		var sMantissa = sTemp.substr(0,expLoc);
		var sExponent = sTemp.substr(expLoc+1);
		var nMantissa = parseFloat(sMantissa);
		var nExponent = parseInt(sExponent);
		sMantissa = String(sMantissa);
		sExponent = String(sExponent);
		
		if ( (sMantissa.length <= 0) || (isNaN(nMantissa)) )
			return "NaN";
		if ( (sExponent.length <= 0) || (isNaN(nExponent)) )
			return "NaN";

		var sSign = "";
		if (nMantissa < 0)
		{
			sSign = "-";
		}
		// normalize.
		nMantissa = Math.abs( nMantissa );
		sMantissa = String( nMantissa );

		var nMantissaDecLoc = sMantissa.indexOf(".");
		if (nMantissaDecLoc == -1)
			nMantissaDecLoc = sMantissa.length;
		
		var sMantissaInt = sMantissa.substr(0,nMantissaDecLoc);
		var sMantissaDec = sMantissa.substr(nMantissaDecLoc+1);
			
		if (nExponent == 0)
			return sMantissa;

		if (nExponent < 0)
		{
			// move decimal left...
			var nPadBefore = Math.abs(nExponent) - sMantissaInt.length;
			if (nPadBefore == 0)
				sReturn = sSign + "0." + sMantissaInt + sMantissaDec;
			else
			{
				if (nPadBefore > 0)
				{
					for (i = 0; i < nPadBefore; i++)
						sReturn = sReturn + "0";
					sReturn = sSign + "0." + sReturn + sMantissaInt + sMantissaDec;
				}
				else
				{
					nPadBefore = Math.abs(nPadBefore);
					sReturn = sSign + sMantissaInt.substr(0,nPadBefore) + "." + sMantissaInt.substr(nPadBefore) + sMantissaDec;
				}
			}
		}
		else
		{
			// move decimal right...
			var nPadAfter = nExponent - sMantissaDec.length;
			if (nPadAfter == 0)
				sReturn = sSign + sMantissaInt + sMantissaDec;
			else
			{
				if (nPadAfter > 0)
				{
					for (i = 0; i < nPadAfter; i++)
						sReturn = sReturn + "0";
					sReturn = sSign + sMantissaInt + sMantissaDec + sReturn;
				}
				else
				{
					sReturn = sSign + sMantissaInt + sMantissaDec.substr(0,nExponent) + "." + sMantissaDec.substr(nExponent);
				}
			}
		}
	}
	else
		return sTemp;
	
	return sReturn;
}

//
// CP_parseLocalNumber() and CP_formatNumber()
//
// Background:  Some countries, predominently in Europe (France, Germany, Italy, Spain, etc...) uses
//              comma "," as decimal point symbol and period "." as thousand separator.
//              In these locale, "1.000.000,50" is a proper form and "1,000,000.50" is an error
//              and meanless.   Therefore, when coding, your program must be aware of this and properly
//              handle these local user inputs.
//
//              For example,
//                    Cost = Price * nUnit;
//
//              will result in run-time error if the variable Price is coming from input field in which
//              a German user entered "100,50".
//

// Check whether char is a number.
function CP_isDigit (c)
{   return ((c >= "0") && (c <= "9"))
}

// CP_parseLocalNumber( String )
//
// Description: Similar to parseFloat method, this function converts locale specific number string into 
//              proper numeric value which can then be used in math operations.
//
// Parameters:
//	 s1:  Numeric String in localized in current browser locale setting. (Required)
//   bToStr:  Optional Boolean value.  When set, the function returns parsed number as a USA formatted number string. (Optional, default=false)
//
// Usage:
//      Cost = CP_parseLocalNumber(Price) * nUnits;		// OK
//
//   If variable Price is coming from an HTML input field and a German user inputs "1.000,50", this function
//   properly converts the value of Price to "1000.50" so that numeric operation is possible.
//
//      BadNum = CP_parseLocalNumber( "1,000.50" );		// returns 1.00050 if browser setting is in German.
//      BadNum = CP_parseLocalNumber( "1,000,000" );	// returns "NaN" if browser setting is in German.
//
// Note:
//   The function should be used only for validating and converting local user input.
//   If input string is not valid for any reason, the return value is a string "NaN".
//
//	 Due to JavaScript limitation, numeric percision is lost for number with more than 16 digits, including
//   decimal digits.  For example, try:
//      var numOK   = Number("1234567890123456");		// returns 1234567890123456
//      var numBAD1 = Number("12345678901234567");		// returns 12345678901234568	(starts "rounding")
//      var numBAD2 = Number("123456789012345678");		// returns 123456789012345680	(starts "rounding")
//
function CP_parseLocalNumber(s1, bToStr)
{
    var i;
    var seenDecimalPoint = false;
    var val = "NaN";

	var LocalID;
	try{
		LocalID = jvusrLCID;
		}
	catch(e){
			if(LocalID == null)
				LocalID = GetParentVar("jvusrLCID",5);
			}

	var s = String(s1);

	switch (LocalID)
	{
	    case 1036:		// French(Standard)
	    case 3084:		// French(Canadian)
	    case 5132:		// French(Luxembourg)
		case 1035:		// Finnish(Finland)
		case 1053:		// Swedish(Sweden)
		case 2077:		// Swedish(Finland)
		case 1044:		// Nowegian(Bokmal)
			sGroupDelimiter = String.fromCharCode(32);
			sPoint = ",";
			nGroupLen = 3;
			var re = /\xa0/g;					// 0xa0 (160) == NBSP
			s = s.replace(re, sGroupDelimiter);
			break;

	    case 4108:		// French(Swiss)
	    case 2055:		// German(Swiss)
	    case 5127:		// German(Liechtenstein)
		case 2064:		// Italian(Swiss)
			sGroupDelimiter = "'";
			sPoint = ".";
			nGroupLen = 3;
			break;

	    case 1031:		// German(Standard)
	    case 3079:		// German(Austrian)
	    case 4103:		// German(Luxembourg)
	    case 2060:		// French(Belgian)
		case 1040:		// Italian(Standard)
		case 1034:		// Spanish(Standard)
		case 11274:		// Spanish(Argentina)
		case 16394:		// Spanish(Bolivia)
		case 13322:		// Spanish(Chile)
		case 9226:		// Spanish(Columbia)
		case 5130:		// Spanish(Costa Rica)
		case 12298:		// Spanish(Ecuador)
		case 15370:		// Spanish(Paraguay)
		case 14346:		// Spanish(Uruguay)
		case 8202:		// Spanish(Venezuela)
		case 1030:		// Danish(Denmark)
		case 1043:		// Dutch(Netherland)
		case 2067:		// Dutch(Belgium)
		case 1046:		// Portuguese(Brazil)
		case 2070:		// Portuguese(Portugal)
		case 3082:      // Spanish(International)
			sGroupDelimiter = ".";
			sPoint = ",";
			nGroupLen = 3;
			break;

	    case 1033:		// English(United States) 	      
	    case 2057:		// English(United Kingdom)
	    case 3081:		// English(Australian)
	    case 4105:		// English(Canadian)
	    case 5129:		// English(New Zealand)
	    case 6153:		// English(Ireland)
	    case 7177:		// English(South Africa)
	    case 8201:		// English(Jamaica)
	    case 9225:		// English(Caribbean)
	    case 10249:		// English(Belize)
	    case 11273:		// English(Trinidad)
		case 7178:		// Spanish(Dominican Republic)
		case 17418:		// Spanish(El Salvador)
		case 4106:		// Spanish(Guatemala)
		case 2058:		// Spanish(Mexico)
		case 6154:		// Spanish(Panama)
		case 10250:		// Spanish(Peru)
			sGroupDelimiter = ",";
			sPoint = ".";
			nGroupLen = 3;
			break;

	    default:		// default to Engish
			sGroupDelimiter = ",";
			sPoint = ".";
			nGroupLen = 3;
			break;
	}
	
    if (s == sPoint || s == sGroupDelimiter) return val;

    if (CP_parseLocalNumber.arguments.length < 2)
		bToStr = false;

	// First, deal with scientific notation number...
	// If scientific notation, then we expect mantissa to be formatted according to the locale.
	// Therefore, process just the mantissa portion to see if it is valid.  Once completed, 
	// append the exponent portion to parse into a number.
	var bSciNotation = false;
	var sTemp;
	s = s.toLowerCase();
	var nExpLoc = s.indexOf("e");
	if (nExpLoc > -1)
	{
		bSciNotation = true;
		sTemp = s;					// save the number string for further operation...
		s = s.substr(0, nExpLoc);	// only use the mantissa portion.
	}

    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return "NaN"; if we don't, return the value.

	var evalString = "";
	var nDecLoc = -1;
	var nGrpLoc = -1;
	var nNeg = 0;
	var bPosSign = false;
	var c;

	if (s.charAt(0) == "+")					// strip plus sign if found.
	{
		s = s.substr(1);
		bPosSign = true;
	}

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        c = s.charAt(i);

        if ((i == 0) && (c == "-"))
        {
			if (bPosSign)					// +-123.45
				return "NaN";
				
			evalString += c;
			nNeg = 1;
			continue;
		}

        if ((c == sPoint) && !seenDecimalPoint)
        {
			seenDecimalPoint = true;
			evalString += ".";
			nDecLoc = i;

			if ( nGrpLoc > -1 )
			{
				if ( (i - nGrpLoc - 1) != nGroupLen )
					return "NaN";
			}
			nGrpLoc = i;
		}
		else if ( c == sGroupDelimiter )
		{
			if ( nGrpLoc > -1 )
			{
				// check for Group delimiter rule conformance.
				if ( (i - nGrpLoc - 1) != nGroupLen )
					return "NaN";
			}
			else
			{
				// for first Group delimiter, check if the number of digits before
				// the Group delimiter is less than group length.
				if ( (i - nNeg) > nGroupLen )
					return "NaN";
			}
			nGrpLoc = i;
		}
		else if ( !CP_isDigit(c) )
			return val;
		else
			evalString += c;
    }

	// check if group separator appears after the decimal point.	
	if ( (nDecLoc >= 0) && (nGrpLoc > nDecLoc) )
		return "NaN";

	// check the last Group delimiter.
	if ( (nGrpLoc >= 0) && (nGrpLoc != nDecLoc) )
	{
		if ( (i - nGrpLoc - 1) != nGroupLen )
			return "NaN";
	}

	if (bToStr)
	{
		var negStr = "";
		if ((nNeg == 1) && (evalString.charAt(0) == "-"))
		{
			negStr = "-";
			evalString = evalString.substr(1);
		}
		if (seenDecimalPoint)
		{
			while ((evalString.charAt(0) == "0") && (evalString.charAt(1) != "."))
				evalString = evalString.substr(1);

			while ((evalString.charAt(evalString.length-1) == "0") && (evalString.charAt(evalString.length-2) != "."))
				evalString = evalString.substr(0, evalString.length-1);
		}
		else
		{
			while ((evalString.charAt(0) == "0") && (evalString.charAt(1) != ""))
				evalString = evalString.substr(1);				
		}
			
		if ((evalString == "") || (evalString == "0") || (evalString == "0.0"))
			return "0";
		else
		{
			if (bSciNotation)
			{
				evalString += sTemp.substr(nExpLoc);
				if ((evalString = SciNotation2NumberString(evalString)) == "NaN")
					return evalString;
			}			
			return negStr + evalString;
		}
	}

	// if number was a scientific notation, append the exponent portion to the evaluating number string.
	if (bSciNotation)
		evalString += sTemp.substr(nExpLoc);

    // All characters are numbers.
	val = parseFloat(evalString);

	if (isNaN(val))
		val = "NaN";

    return val;
}


// CP_formatNumber( Expr [,DigitsAfterDecimal [,IncludeLeadingDigit [,UseParenForNegNum [,GroupDigits]]]])
//
// Description: JavaScript version of VB FormatNumber function.
//
//
// Parameters:
//	 Expr:  Expression to be formatted. (Required)
//
//   DigitsAfterDecimal:  Numeric value indicating how many places to the right of the
//		decimal are displayed. Default value is -1, which indicates that the browser's
//		regional settings are used. (Optional)
//
//   IncludeLeadingDigit:  Tristate constant that indicates whether or not a leading zero is
//		displayed for fractional values. Default value is -1. (Optional)
//
//   UseParenForNegNum:  Tristate constant that indicates whether or not to place
//		negative values within parentheses. Default value is 0. (Optional)
//
//   GroupDigits:  Tristate constant that indicates whether or not numbers are grouped using the
//		group delimiter specified in the control panel. Default value is -1. (Optional)
//
//
// The IncludeLeadingDigit, UseParenForNegNum, and GroupDigits arguments have the following settings:
//		TristateTrue		-1	True 
//		TristateFalse		 0	False 
//		TristateUseDefault	-2	Use the setting from the computer's regional settings. (not used here)
//
// Note: This function formats numeric value into locale specific string.  The function assumes that the
//       input expression (Expr) is a valid numberic value using "." as the decimal point.  If not, the
//       result will be unpredictable.
//       If error is encountered, the function returns "".
//
//		 Due to JavaScript limitation, numeric percision is lost for number with more than 16 digits, including
//       decimal digits.  For example, try:
//           var numOK   = Number("1234567890123456");		// returns 1234567890123456
//           var numBAD1 = Number("12345678901234567");		// returns 12345678901234568	(starts "rounding")
//           var numBAD2 = Number("123456789012345678");	// returns 123456789012345680	(starts "rounding")
//
function CP_formatNumber( Expr, DigitAfterDecimal, IncludeLeadingDigit, UseParenForNegNum, GroupDigits )
{
	var LocalID;
	try{
		LocalID = jvusrLCID;
		}
	catch(e){
			if(LocalID == null)
				LocalID = GetParentVar("jvusrLCID",5);
			}

	switch (LocalID)
	{
	    case 1036:		// French(Standard)
	    case 3084:		// French(Canadian)
	    case 5132:		// French(Luxembourg)
		case 1035:		// Finnish(Finland)
		case 1053:		// Swedish(Sweden)
		case 2077:		// Swedish(Finland)
		case 1044:		// Norwegian(Bokmal)
			sGroupDelimiter = String.fromCharCode(32);
			sPoint = ",";
			nGroupLen = 3;
			break;

	    case 4108:		// French(Swiss)
	    case 2055:		// German(Swiss)
	    case 5127:		// German(Liechtenstein)
		case 2064:		// Italian(Swiss)
			sGroupDelimiter = "'";
			sPoint = ".";
			nGroupLen = 3;
			break;

	    case 1031:		// German(Standard)
	    case 3079:		// German(Austrian)
	    case 4103:		// German(Luxembourg)
	    case 2060:		// French(Belgian)
		case 1040:		// Italian(Standard)
		case 1034:		// Spanish(Standard)
		case 11274:		// Spanish(Argentina)
		case 16394:		// Spanish(Bolivia)
		case 13322:		// Spanish(Chile)
		case 9226:		// Spanish(Columbia)
		case 5130:		// Spanish(Costa Rica)
		case 12298:		// Spanish(Ecuador)
		case 15370:		// Spanish(Paraguay)
		case 14346:		// Spanish(Uruguay)
		case 8202:		// Spanish(Venezuela)
		case 1030:		// Danish(Denmark)
		case 1043:		// Dutch(Netherland)
		case 2067:		// Dutch(Belgium)
		case 1046:		// Portuguese(Brazil)
		case 2070:		// Portuguese(Portugal)
		case 3082:      //Spanish(International)
			sGroupDelimiter = ".";
			sPoint = ",";
			nGroupLen = 3;
			break;

	    case 1033:		// English(United States) 	      
	    case 2057:		// English(United Kingdom)
	    case 3081:		// English(Australian)
	    case 4105:		// English(Canadian)
	    case 5129:		// English(New Zealand)
	    case 6153:		// English(Ireland)
	    case 7177:		// English(South Africa)
	    case 8201:		// English(Jamaica)
	    case 9225:		// English(Caribbean)
	    case 10249:		// English(Belize)
	    case 11273:		// English(Trinidad)
		case 7178:		// Spanish(Dominican Republic)
		case 17418:		// Spanish(El Salvador)
		case 4106:		// Spanish(Guatemala)
		case 2058:		// Spanish(Mexico)
		case 6154:		// Spanish(Panama)
		case 10250:		// Spanish(Peru)
			sGroupDelimiter = ",";
			sPoint = ".";
			nGroupLen = 3;
			break;

	    default:		// default to Engish
			sGroupDelimiter = ",";
			sPoint = ".";
			nGroupLen = 3;
			break;
	}

	var sReturn = "";

	// Parse parameter list and set default settings if not specified
    if (CP_formatNumber.arguments.length < 5)
		GroupDigits = -1;
    if (CP_formatNumber.arguments.length < 4)
		UseParenForNegNum = 0;
    if (CP_formatNumber.arguments.length < 3)
    	IncludeLeadingDigit = -1;
    if (CP_formatNumber.arguments.length < 2)
		DigitAfterDecimal = -1;

	var nNoOfGroup = 0;						// Num of groups
	var nLocationOfDelimiter = 0;			// Location of group delimiter
	var sInteger = "";						// Integer part of number
	var sDecimal = "";						// Decimal part of number
	var nIntLen = 0;						// Length of integer part of number
	var nDecLen = 0;						// Length of decimal part of number
	var bNegative = false;
	var iCnt;

	var sTemp  = "";
	sTemp = Expr.toString();
	
	var nTemp = parseFloat(sTemp);
	if ( isNaN(nTemp) )
		return "";

	if (nTemp < 0)
		bNegative = true;

	// Perform rounding first if required.
	if (DigitAfterDecimal == -1)			// take default (no truncation of decimal)
		sTemp = RoundBigNumber( sTemp );
	else
		sTemp = RoundBigNumber( sTemp, DigitAfterDecimal );

	if (sTemp == "")
		return "";

	// From this point on, assume the sTemp is a number string without any grouping and
	// with "." as the decimal point symbol.
	var nNumLen = sTemp.length;				// Length of the number
	var nDecLoc = sTemp.indexOf(".");		// Location of decimal point

	if (nDecLoc == -1)
	{
		// if decimal point is not found, number must be an integer.
		nDecLoc = nNumLen;
		nDecLen = 0;
		sInteger = sTemp;					// All integer.
	}
	else
	{
		// if decimal point exists, separate integer and decimal substrings.
		sInteger = sTemp.substr(0, nDecLoc);
		nDecLen = nNumLen - nDecLoc - 1;	// Num of decimal digits

		if (nDecLen > 0)
			sDecimal = sTemp.substr(nDecLoc+1, nDecLen);
	}

	if (DigitAfterDecimal == -1)		// take default (no truncation of decimal)
		DigitAfterDecimal = nDecLen;

	// Process Integer part
	sTemp = String(sInteger);

	nIntLen = sTemp.length;
	nNoOfGroup = parseInt((nIntLen-1)/nGroupLen);
	nLocationOfDelimiter = nIntLen - nGroupLen*nNoOfGroup - 1;				

	if (GroupDigits == 0)
		nNoOfGroup = 0;						// Do not group numbers

	if (IncludeLeadingDigit == 0)			// Do not put leading digit
	{
		if (sInteger == "0")
		{
			sReturn = "";
			nIntLen = 0;
		}
		else if (sInteger == "-0")
		{
			sReturn = "-";
			nIntLen = 0;
		}
	}
	else if (nIntLen == 0)
		sReturn = "0";

	// Process integer portion and insert group delimiter if required.	
	for (iCnt = 0; iCnt < nIntLen; iCnt++)
	{
		sChar = sTemp.charAt(iCnt);			
		if(nNoOfGroup == 0)		
			sReturn += sChar;				
		else
		{
			if(iCnt == nLocationOfDelimiter)
			{
				if (sChar != "-")
					sReturn += sChar + sGroupDelimiter;
				else
					sReturn += sChar;

				nNoOfGroup--;

				if(nNoOfGroup != 0)
					nLocationOfDelimiter += nGroupLen;
			}		
			else
			{
				sReturn += sChar;									
			}
		}
	}

	// Based on parameter, pad or truncate decimal digits.
	if (DigitAfterDecimal > 0)
	{
		sReturn += sPoint;

		for (iCnt = 0; iCnt < DigitAfterDecimal; iCnt++)
		{
			if (iCnt < sDecimal.length)
				sChar = sDecimal.charAt(iCnt);
			else
				sChar = "0";

			sReturn += sChar;
		}
	}

	// Based on parameter, add parenthesis for negative number
	if ((UseParenForNegNum == -1) && bNegative)
	{
		sTemp = sReturn.substr(1, sReturn.length-1);
		sReturn = "(" + sTemp + ")";
	}

	// Finally, check for special case...
	if (sReturn == "-0")
		return "0";

    return sReturn;
}

// Round large precision number to a given scale (digits).
// Input MUST be a US formatted number string.  "." for decimal.  
// Otherwise, the result is unpredictable.
function RoundBigNumber(strNumIn, nDigits) 
{
	var strNum, sNumArr, nCarry, test, sInt, sDec, sSign;

	strNum = String(strNumIn);

	// Deal with scientific notation number...
	strNum = strNum.toLowerCase();
	if (strNum.indexOf("e") > -1)
		strNum = SciNotation2NumberString( strNum );
	
	// remove thousand separator (,) and white space, if found.
	var re = /\,|\s/g;
	strNum = strNum.replace(re, "");
		
	test = parseFloat(strNum);		// test for NaN
	if (isNaN(test))
		return "";

	sSign = "";
	sNumArr = strNum.split(".");
	
	if ((sNumArr.length > 2)||(sNumArr.length == 0))
		return "";
	else if (sNumArr.length == 1)
	{
		if (strNum.charAt(0) == "-")
		{
			sSign = "-";
			strNum = strNum.substr(1);			// trim sign for now.
		}
		while ((strNum.charAt(0) == "0") && (strNum.charAt(1) != ""))
			strNum = strNum.substr(1);
			
		strNum = sSign + strNum;
		return strNum;
	}
	
	if (sNumArr[0].length == 0)
		sInt = "0";
	else
	{
		sInt = sNumArr[0];
		if (sInt.charAt(0) == "-")
		{
			sSign = "-";
			sInt = sInt.substr(1);			// trim sign for now.
		}
		while ((sInt.charAt(0) == "0") && (sInt.charAt(1) != ""))
			sInt = sInt.substr(1);
	}

	if (sNumArr[1].length == 0)
		sDec = "0";
	else
		sDec = sNumArr[1];
	
	nDecLen = sDec.length;

	// check for obvious case: no rounding required.	
	if ((nDecLen == nDigits) || (RoundBigNumber.arguments.length < 2))
		return sSign + sInt + "." + sDec;
		
	if (nDecLen > nDigits)
	{
		test = parseInt( sDec.charAt(nDigits), 10 );
		if (isNaN(test))
			return "";

		// Check for stupid JavaScript loss of precision case, which messes up rounding.
		var sJavaScriptCrap = sDec.substr(nDigits, nDecLen-nDigits);
		if (sJavaScriptCrap.substr(0,4) == "4999")
			test = 5;	// force rounding up.

		sDec = sDec.substr(0, nDigits);
		if (test >= 5)
		{
			var i;
			i = nDigits-1;
			carry = 1;

			while ( (i >= 0) && (carry) )
			{
				test = parseInt( sDec.charAt(i) ) + carry;
				if (isNaN(test))
					return "";
				carry = (test>9)? 1 : 0;
				test = test % 10;
				sDec = sDec.substr(0, i) + test.toString(10) + sDec.substr(i+1);
				i--;
			}

			i = sInt.length - 1;			
			while ( (i >= 0) && (carry) )
			{
				test = parseInt( sInt.charAt(i) )
				if (isNaN(test))
					return "";
				test = parseInt( sInt.charAt(i) ) + carry;
				carry = (test>9)? 1 : 0;
				test = test % 10;
				sInt = sInt.substr(0, i) + test.toString(10) + sInt.substr(i+1);
				i--;
			}
			
			if (carry)
			{
				sInt = sInt.substr(0, i+1) + "1" + sInt.substr(i+1);
			}
			return sSign + sInt + "." + sDec;
		}
		else
			return sSign + sInt + "." + sDec;
	}
	else
	{
		// pad
		var sPad = "00000000000000000000000000000000000000000000000000"
		return sSign + sInt + "." + sDec + sPad.substr(0, nDigits - nDecLen);
	}
}


// CP_parseLocalDate( String )
//
// Description: Converts local date STRING into JavaScript's Date object in (mm/dd/yy).
//
// Usage1:
//      sDate = CP_parseLocalDate( userDateStart );
//      eDate = CP_parseLocalDate( userDateEnd );
//      if ( sDate > eDate ) alert("error");			// validate
//
// Usage2:
//      good = CP_parseLocalDate( "13.3.01" );	// (in German) returns Date object (Tue Mar 13 00:00:00 EST 2001)
//
//      bad = CP_parseLocalDate( "13/34/01" );	// Error condition.  Returns "mm/dd/yy" in English-US and "tt.mm.jj" in German.
//
// Note:
//   This JavaScript function should be used only when server-side validation is not feasible.
//   Also, date STRING being passed in should respect the local custom.  That is, if the current browser
//   setting is German, this function expects to parse German date (28.03.01).  Any other formats will
//   have unpredictable results.
//
//   In an error condition, the function returns string containing expected format (ex. "mm/dd/yy" in English-US)
//
//   For additional info, please contact Spencer Park of IDG.
//
function CP_parseLocalDate(strDate)
{
	var sReturn = "";
	var sTemp = "";
	var iMonth = 0;
	var iDay = 0;
	var iYear = 0;
	var aDate;			//array which is used to contain different parts of date
	var sDateFormat;
	var sYY = "";
	var sMM = "";
	var sDD = "";
	var LangId;
	
	try{
		LangId = jvLangId;
		}
	catch(e){
			if(LangId == null)
				LangId = GetParentVar("jvLangId",5);
			}

	switch (LangId)
	{
		case "E":
			sYY = "yyyy";
			sMM = "mm";
			sDD = "dd";
			break;
		case "F":
			sYY = "aaaa";
			sMM = "mm";
			sDD = "jj";
			break;
		case "D":
			sYY = "jjjj";
			sMM = "mm";
			sDD = "tt";
			break;
	}

	var daysInMonth = new Array(12);
	daysInMonth[1]  = 31;   daysInMonth[2]  = 29;   // must programmatically check this
	daysInMonth[3]  = 31;   daysInMonth[4]  = 30;
	daysInMonth[5]  = 31;   daysInMonth[6]  = 30;
	daysInMonth[7]  = 31;   daysInMonth[8]  = 31;
	daysInMonth[9]  = 30;   daysInMonth[10] = 31;
	daysInMonth[11] = 30;   daysInMonth[12] = 31;	
	
	strDate = String(strDate);		
	
	var LocalID;
	try{
		LocalID = jvusrLCID;
		}
	catch(e){
			if(LocalID == null)
				LocalID = GetParentVar("jvusrLCID",5);
			}

	switch (LocalID)
	{
	    case 1033:		// English(United States) 	      
	    case 9225:		// English(Caribbean)
		case 6154:		// Spanish(Panama)
			sDateFormat = sMM + "/" + sDD + "/" + sYY;		// mm/dd/yyyy
			aDate = strDate.split("/");
			sMonth = aDate[0];
			sDay = aDate[1];
			sYear = aDate[2];
			break;

		case 1041:		// Japanese
		case 1028:      // Chinese(Taiwan)
		case 7177:		// English(South Africa)
			sDateFormat = sYY + "/" + sMM + "/" + sDD;		// yyyy/mm/dd
			aDate = strDate.split("/");
			sYear = aDate[0];
			sMonth = aDate[1];
			sDay = aDate[2];
			break;

		case 3084:		// French(Canadian)
		case 1053:		// Swedish(Sweden)
		case 1042:		// Korean(Korea)
		case 2052:      // Chinese(PRC)
			sDateFormat = sYY + "-" + sMM + "-" + sDD;		// yyyy-mm-dd
			aDate = strDate.split("-");
			sYear = aDate[0];
			sMonth = aDate[1];
			sDay = aDate[2];
			break;

		case 10249:		// English(Belize)
		case 4105:		// English(Canadian)
		case 6153:		// English(Ireland)
		case 8201:		// English(Jamaica)
		case 11273:		// English(Trinidad)
		case 2057:		// English(United Kingdom)
		case 1036:		// French(Standard)
		case 5132:		// French(Luxembourg)
		case 1040:		// Italian(Standard)
		case 1034:		// Spanish(Standard)
		case 11274:		// Spanish(Argentina)
		case 16394:		// Spanish(Bolivia)
		case 9226:		// Spanish(Columbia)
		case 5130:		// Spanish(Costa Rica)
		case 7178:		// Spanish(Dominican Republic)
		case 12298:		// Spanish(Ecuador)
		case 17418:		// Spanish(El Salvador)
		case 4106:		// Spanish(Guatemala)
		case 18442:		// Spanish(Honduras)
		case 2058:		// Spanish(Mexico)
		case 19466:		// Spanish(Nicaragua)
		case 15370:		// Spanish(Paraguay)
		case 10250:		// Spanish(Peru)
		case 20490:		// Spanish(Puerto Rico)
		case 14346:		// Spanish(Uruguay)
		case 8202:		// Spanish(Venezuela)
		case 2067:		// Dutch(Belgium)
		case 3081:		// English(Australian)
		case 5129:		// English(New Zealand)
		case 2060:		// French(Belgian)
		case 4100:		// Chinese(Singapore)
		case 5124:		// Chinese(Macau)
		case 3076:		// Chinese(Hong Kong)
		case 1046:		// Portuguese(Brazil)
		case 3082:      //Spanish(International)
			sDateFormat = sDD + "/" + sMM + "/" + sYY;		// dd/mm/yy
			aDate = strDate.split("/");
			sDay = aDate[0];
			sMonth = aDate[1];
			sYear = aDate[2];
			break;	

		case 4108:		// French(Swiss)
		case 1031:		// German(Standard)
		case 3079:		// German(Austrian)
		case 5127:		// German(Liechtenstein)
		case 4103:		// German(Luxembourg)
		case 2055:		// German(Swiss)
		case 2064:		// Italian(Swiss)
		case 1044:		// Norwegian(Bokmal)
		case 1035:		// Finnish(Finland)
		case 2077:		// Swedish(Finland)
			sDateFormat = sDD + "." + sMM + "." + sYY;		// dd.mm.yyyy
			aDate = strDate.split(".");
			sDay = aDate[0];
			sMonth = aDate[1];
			sYear = aDate[2];	
			break;

		case 1030:		// Danish(Denmark)
		case 13322:		// Spanish(Chile)
		case 1043:		// Dutch(Netherland)
		case 2070:		// Portuguese(Portugal)
			sDateFormat = sDD + "-" + sMM + "-" + sYY;		// dd-mm-yy
			aDate = strDate.split("-");
			sDay = aDate[0];
			sMonth = aDate[1];
			sYear = aDate[2];	
			break;

		default:		// default to Engish(US)
			sDateFormat = sMM + "/" + sDD + "/" + sYY;		// mm/dd/yy
			aDate = strDate.split("/");
			sMonth = aDate[0];
			sDay = aDate[1];
			sYear = aDate[2];
			break;
	}
	
	if ( sMonth == "" || sDay == "" || sYear == "" )
		return sDateFormat;					// error, return expected date format

	if ( sMonth == null || sDay == null || sYear == null )
		return sDateFormat;					// error, return expected date format
		
	if ( isNaN(sMonth) || isNaN(sDay) || isNaN(sYear) )
		return sDateFormat;					// error, return expected date format

	iMonth = new Number(sMonth);
	iDay = new Number(sDay);
	iYear = new Number(sYear);

	if ( iYear < 0 )
		return sDateFormat;					// error, return expected date format

	// If two digit year is supplied, unfortunately we have assume the following:  (Y2K bug)
	if ( sYear.length == 2 ) 
	{	if (iYear <= 70)
			iYear = 2000 + iYear;
		else
			iYear = 1900 + iYear;
	}

	if ( iYear < 1753 || iYear > 9999 )
		return sDateFormat;					// error, return expected date format		
	
	if ( iMonth > 12 || iMonth < 1 )
		return sDateFormat;					// error, return expected date format

    if ( iDay > daysInMonth[iMonth] || iDay < 1 )
		return sDateFormat;					// error, return expected date format

    if ( ( iMonth == 2 ) && ( iDay > daysInFebruary(iYear) ) )
		return sDateFormat;					// error, return expected date format

	sReturn = new Date(iYear, iMonth-1, iDay);
	
    return sReturn;
}

// CP_parseLocalDateTimeToMillisec( String )
//
// Description: Converts local date and time STRING into JavaScript's Date in millisec.
function CP_parseLocalDateTimeToMillisec(strDateTime)
{
	var sReturn = "";
	var sTemp = "";
	var iMonth = 0;
	var iDay = 0;
	var iYear = 0;
	var aDate;			//array which is used to contain different parts of date
	var sDateFormat;
	var sYY = "";
	var sMM = "";
	var sDD = "";
	var LangId;
	var iIdx;
	var strDate;	
	var sTime = ""; 
	
	try{
		LangId = jvLangId;
		}
	catch(e){
			if(LangId == null)
				LangId = GetParentVar("jvLangId",5);
			}
				
	iIdx = strDateTime.indexOf(" ");
	if (iIdx == -1)
		strDate = strDateTime;
	else
	{
		strDate = strDateTime.substring(0, iIdx);	
		sTime = strDateTime.substr(iIdx+1);
	}
				
	switch (LangId)
	{
		case "E":
			sYY = "yyyy";
			sMM = "mm";
			sDD = "dd";
			break;
		case "F":
			sYY = "aaaa";
			sMM = "mm";
			sDD = "jj";
			break;
		case "D":
			sYY = "jjjj";
			sMM = "mm";
			sDD = "tt";
			break;
	}

	var daysInMonth = new Array(12);
	daysInMonth[1]  = 31;   daysInMonth[2]  = 29;   // must programmatically check this
	daysInMonth[3]  = 31;   daysInMonth[4]  = 30;
	daysInMonth[5]  = 31;   daysInMonth[6]  = 30;
	daysInMonth[7]  = 31;   daysInMonth[8]  = 31;
	daysInMonth[9]  = 30;   daysInMonth[10] = 31;
	daysInMonth[11] = 30;   daysInMonth[12] = 31;	
	
	strDate = String(strDate);		
	
	var LocalID;
	try{
		LocalID = jvusrLCID;
		}
	catch(e){
			if(LocalID == null)
				LocalID = GetParentVar("jvusrLCID",5);
			}

	switch (LocalID)
	{
	    case 1033:		// English(United States) 	      
	    case 9225:		// English(Caribbean)
		case 6154:		// Spanish(Panama)
			sDateFormat = sMM + "/" + sDD + "/" + sYY;		// mm/dd/yyyy
			aDate = strDate.split("/");
			sMonth = aDate[0];
			sDay = aDate[1];
			sYear = aDate[2];
			break;

		case 1041:		// Japanese
		case 1028:      // Chinese(Taiwan)
		case 7177:		// English(South Africa)
			sDateFormat = sYY + "/" + sMM + "/" + sDD;		// yyyy/mm/dd
			aDate = strDate.split("/");
			sYear = aDate[0];
			sMonth = aDate[1];
			sDay = aDate[2];
			break;

		case 3084:		// French(Canadian)
		case 1053:		// Swedish(Sweden)
		case 1042:		// Korean(Korea)
		case 2052:      // Chinese(PRC)
			sDateFormat = sYY + "-" + sMM + "-" + sDD;		// yyyy-mm-dd
			aDate = strDate.split("-");
			sYear = aDate[0];
			sMonth = aDate[1];
			sDay = aDate[2];
			break;

		case 10249:		// English(Belize)
		case 4105:		// English(Canadian)
		case 6153:		// English(Ireland)
		case 8201:		// English(Jamaica)
		case 11273:		// English(Trinidad)
		case 2057:		// English(United Kingdom)
		case 1036:		// French(Standard)
		case 5132:		// French(Luxembourg)
		case 1040:		// Italian(Standard)
		case 1034:		// Spanish(Standard)
		case 11274:		// Spanish(Argentina)
		case 16394:		// Spanish(Bolivia)
		case 9226:		// Spanish(Columbia)
		case 5130:		// Spanish(Costa Rica)
		case 7178:		// Spanish(Dominican Republic)
		case 12298:		// Spanish(Ecuador)
		case 17418:		// Spanish(El Salvador)
		case 4106:		// Spanish(Guatemala)
		case 18442:		// Spanish(Honduras)
		case 2058:		// Spanish(Mexico)
		case 19466:		// Spanish(Nicaragua)
		case 15370:		// Spanish(Paraguay)
		case 10250:		// Spanish(Peru)
		case 20490:		// Spanish(Puerto Rico)
		case 14346:		// Spanish(Uruguay)
		case 8202:		// Spanish(Venezuela)
		case 2067:		// Dutch(Belgium)
		case 3081:		// English(Australian)
		case 5129:		// English(New Zealand)
		case 2060:		// French(Belgian)
		case 4100:		// Chinese(Singapore)
		case 5124:		// Chinese(Macau)
		case 3076:		// Chinese(Hong Kong)
		case 1046:		// Portuguese(Brazil)
		case 3082:      //Spanish(International)
			sDateFormat = sDD + "/" + sMM + "/" + sYY;		// dd/mm/yy
			aDate = strDate.split("/");
			sDay = aDate[0];
			sMonth = aDate[1];
			sYear = aDate[2];
			break;	

		case 4108:		// French(Swiss)
		case 1031:		// German(Standard)
		case 3079:		// German(Austrian)
		case 5127:		// German(Liechtenstein)
		case 4103:		// German(Luxembourg)
		case 2055:		// German(Swiss)
		case 2064:		// Italian(Swiss)
		case 1044:		// Norwegian(Bokmal)
		case 1035:		// Finnish(Finland)
		case 2077:		// Swedish(Finland)
			sDateFormat = sDD + "." + sMM + "." + sYY;		// dd.mm.yyyy
			aDate = strDate.split(".");
			sDay = aDate[0];
			sMonth = aDate[1];
			sYear = aDate[2];	
			break;

		case 1030:		// Danish(Denmark)
		case 13322:		// Spanish(Chile)
		case 1043:		// Dutch(Netherland)
		case 2070:		// Portuguese(Portugal)
			sDateFormat = sDD + "-" + sMM + "-" + sYY;		// dd-mm-yy
			aDate = strDate.split("-");
			sDay = aDate[0];
			sMonth = aDate[1];
			sYear = aDate[2];	
			break;

		default:		// default to Engish(US)
			sDateFormat = sMM + "/" + sDD + "/" + sYY;		// mm/dd/yy
			aDate = strDate.split("/");
			sMonth = aDate[0];
			sDay = aDate[1];
			sYear = aDate[2];
			break;
	}
	
	if ( sMonth == "" || sDay == "" || sYear == "" )
		return sDateFormat;					// error, return expected date format

	if ( sMonth == null || sDay == null || sYear == null )
		return sDateFormat;					// error, return expected date format
		
	if ( isNaN(sMonth) || isNaN(sDay) || isNaN(sYear) )
		return sDateFormat;					// error, return expected date format

	iMonth = new Number(sMonth);
	iDay = new Number(sDay);
	iYear = new Number(sYear);

	if ( iYear < 0 )
		return sDateFormat;					// error, return expected date format

	// If two digit year is supplied, unfortunately we have assume the following:  (Y2K bug)
	if ( sYear.length == 2 ) 
	{	if (iYear <= 70)
			iYear = 2000 + iYear;
		else
			iYear = 1900 + iYear;
	}

	if ( iYear < 1753 || iYear > 9999 )
		return sDateFormat;					// error, return expected date format		
	
	if ( iMonth > 12 || iMonth < 1 )
		return sDateFormat;					// error, return expected date format

    if ( iDay > daysInMonth[iMonth] || iDay < 1 )
		return sDateFormat;					// error, return expected date format

    if ( ( iMonth == 2 ) && ( iDay > daysInFebruary(iYear) ) )
		return sDateFormat;					// error, return expected date format

	sReturn = iMonth + "/" + iDay + "/" + iYear + " " + sTime;

    return Date.parse(sReturn);
}

function CP_isLocalDate( sDate )
{
	var oDate = CP_parseLocalDate( sDate );
	if ( isNaN( oDate.valueOf() ) )
		return false;
	else
		return true;
}

function CP_PadZero( sNumber, nfullLen )
{	
	var sPaddedNumber = "";
	var sNum = sNumber.toString();
	nNumberOfZero = nfullLen - sNum.length;
	
	for ( i=0; i < nNumberOfZero; i++ )
		sPaddedNumber += "0";	
		
	return ( sPaddedNumber + sNum );		
}

// CP_formatDate( oDate, bFullYear )
//
// Description: Converts Date object into date STRING formatted according to the browser locale setting.
//
// Parameters:
//   oDate		Date object to be formatted. (Required)
//   bFullYear	Boolean value indicating how many digits of year are displayed. (Optional, true by default)
//
// Usage1:
//      var now = new Date();				// get current date/time
//      strDate = CP_formatDate( now );		// format according to local browser setting (ex. German)
//      alert( strDate );					// output should be "13.03.01".
//
// Note:
//   This JavaScript function should be used only when server-side formatting is not feasible.
//
//   In an error condition, the function returns "" (NULL).
//
//   For additional info, please contact Sook-Hee Kim of IDG.
//
//   **** This function has been copied to popCal.asp to improve it's load performance. ****
//   **** Any changes to this function need to be replicated there.	****
function CP_formatDate( oDate, bFullYear )
{
	var orgDate;
	var sTemp = "";
	var sYear, sMonth, sDate;
	var sPadMonth, sPadDate;

	
	
	if ( isNaN(oDate.valueOf()) )			// simple check to see if the input Date is usable.	
	return "";
			
	orgDate = new Date(oDate);

	sDate = orgDate.getDate();
	sPadDate = CP_PadZero(sDate,2);
	
	sMonth = orgDate.getMonth() + 1;
	sPadMonth = CP_PadZero(sMonth,2);
	
	sYear = orgDate.getFullYear();
	
	if ( CP_formatDate.arguments.length < 2 )
		bFullYear = true;
		
	if ( !bFullYear )						// if asked for 2 digit year, then provide. (Y2K bug)
		sYear = sYear.substr(2,2);
			
	var LocalID;
	try{
		LocalID = jvusrLCID;
		}
	catch(e){
			if(LocalID == null)
				LocalID = GetParentVar("jvusrLCID",5);
			}

	switch (LocalID)
	{
	    case 1033:		// English(United States)
			// M/D/yyyy
			sTemp = sMonth + "/" + sDate + "/" + sYear;
			break;
	    case 9225:		// English(Caribbean)
		case 6154:		// Spanish(Panama)
			// mm/dd/yyyy
			sTemp = sPadMonth + "/" + sPadDate + "/" + sYear;
			break;

		case 1041:		// Japanese
		case 1028:      // Chinese(Taiwan)
		case 7177:		// English(South Africa)
			// yyyy/mm/dd
			sTemp = sYear + "/" + sPadMonth + "/" + sPadDate ;
			break;

		case 3084:		// French(Canadian)
		case 1053:		// Swedish(Sweden)
		case 1042:		// Korean(Korea)
		case 2052:      // Chinese(PRC)
			// yyyy-mm-dd
			sTemp = sYear + "-" + sPadMonth + "-" + sPadDate;
			break;
			
		case 10249:		// English(Belize)
		case 4105:		// English(Canadian)
		case 6153:		// English(Ireland)
		case 8201:		// English(Jamaica)
		case 11273:		// English(Trinidad)
		case 2057:		// English(United Kingdom)
		case 1036:		// French(Standard)
		case 5132:		// French(Luxembourg)
		case 1040:		// Italian(Standard)
		case 1034:		// Spanish(Standard)
		case 11274:		// Spanish(Argentina)
		case 16394:		// Spanish(Bolivia)
		case 9226:		// Spanish(Columbia)
		case 5130:		// Spanish(Costa Rica)
		case 7178:		// Spanish(Dominican Republic)
		case 12298:		// Spanish(Ecuador)
		case 17418:		// Spanish(El Salvador)
		case 4106:		// Spanish(Guatemala)
		case 18442:		// Spanish(Honduras)
		case 2058:		// Spanish(Mexico)
		case 19466:		// Spanish(Nicaragua)
		case 15370:		// Spanish(Paraguay)
		case 10250:		// Spanish(Peru)
		case 20490:		// Spanish(Puerto Rico)
		case 14346:		// Spanish(Uruguay)
		case 8202:		// Spanish(Venezuela)
		case 3082:      //Spanish(International)
			// dd/mm/yyyy
			sTemp = sPadDate + "/" + sPadMonth + "/" + sYear;
			break;	
		case 4100:		// Chinese(Singapore)
		case 5124:		// Chinese(Macau)
		case 3076:		// Chinese(Hong Kong)
		case 1046:		// Portuguese(Brazil)
			// D/M/yyyy
			sTemp = sDate + "/" + sMonth + "/" + sYear;
			break;	
		case 2067:		// Dutch(Belgium)
		case 3081:		// English(Australian)
		case 5129:		// English(New Zealand)
		case 2060:		// French(Belgian)
			// D/mm/yyyy
			sTemp = sDate + "/" + sPadMonth + "/" + sYear;
			break;	

		case 1030:		// Danish(Denmark)
		case 13322:		// Spanish(Chile)
		case 2070:		// Portuguese(Portugal)
			// dd-mm-yyyy
			sTemp = sPadDate + "-" + sPadMonth + "-" + sYear;
			break;
		case 1043:		// Dutch(Netherland)
			// D-M-yyyy
			sTemp = sDate + "-" + sMonth + "-" + sYear;
			break;

		case 4108:		// French(Swiss)
		case 1031:		// German(Standard)
		case 3079:		// German(Austrian)
		case 5127:		// German(Liechtenstein)
		case 4103:		// German(Luxembourg)
		case 2055:		// German(Swiss)
		case 2064:		// Italian(Swiss)
		case 1044:		// Norwegian(Bokmal)
			// dd.mm.yyyy
			sTemp = sPadDate + "." + sPadMonth + "." + sYear;
			break;
		case 1035:		// Finnish(Finland)
		case 2077:		// Swedish(Finland)
			// D.M.yyyy
			sTemp = sDate + "." + sMonth + "." + sYear;
			break;

		default:		// default to Engish(US)
			// M/D/yyyy
			sTemp = sPadMonth + "/" + sPadDate + "/" + sYear;
			break;
	}	
    return sTemp;
}

// CP_formatTime( oDate )
//
// Description: Extract Time from Date object and convert into time STRING formatted according to the browser locale setting.
//
// Parameters:
//   oDate		Date object to be formatted. (Required)
//
// Usage1:
//      var now = new Date();				// get current date/time
//      strTime = CP_formatTime( now );		// format according to local browser setting (ex. German)
//      alert( strTime );					// output should be "16:23:01".
//
// Note:
//   This JavaScript function should be used only when server-side formatting is not feasible.
//
//   In an error condition, the function returns "" (NULL).
//
//   For additional info, please contact Sook-Hee Kim of IDG.
//
//   **** This function has been copied to popCal.asp to improve it's load performance. ****
//   **** Any changes to this function need to be replicated there.	****
function CP_formatTime( oDate )
{
	var orgDate;
	var sTemp = "";
	var sHour, sMin, sSec
	
	if ( isNaN(oDate.valueOf()) )			// simple check to see if the input Date is usable.	
	return "";
			
	orgDate = new Date(oDate);
	//orgDate = new Date("");

	sHour = orgDate.getHours();
	sMin = orgDate.getMinutes();
	if (sMin < 10)
		sMin = CP_PadZero(sMin,2)	
	sSec = orgDate.getSeconds();
	if (sSec < 10)
		sSec = CP_PadZero(sSec,2);
	var LocalID;
	try{
		LocalID = jvusrLCID;
		}
	catch(e){
			if(LocalID == null)
				LocalID = GetParentVar("jvusrLCID",5);
			}	

	switch (LocalID)
	{
	    case 1033:		// English(United States)
	    case 3081:		// English(Australian)
	    case 4105:		// English(Canadian)
	    case 7177:		// English(South Africa)
	    case 8201:		// English(Jamaica)
	    case 9225:		// English(Caribbean)
	    case 10249:		// English(Belize)
	    case 11273:		// English(Trinidad)
			// h:mm:ss tt  - 12 hour format
			if (sHour < 12)
			{
				if (sHour == 0)
					sHour = sHour + 12;
				sTemp = sHour + ":" + sMin + ":" + sSec + " AM";
			}	
			else
			{
				if (sHour > 12)
					sHour = sHour - 12;
				sTemp = sHour + ":" + sMin + ":" + sSec + " PM";
			}	
			break;
		case 5129:		// English(New Zealand)			
		case 11274:		// Spanish(Argentina)
		case 16394:		// Spanish(Bolivia)
		case 9226:		// Spanish(Columbia)
		case 5130:		// Spanish(Costa Rica)
		case 7178:		// Spanish(Dominican Republic)
		case 4106:		// Spanish(Guatemala)
		case 18442:		// Spanish(Honduras)
		case 2058:		// Spanish(Mexico)
		case 19466:		// Spanish(Nicaragua)
		case 6154:		// Spanish(Panama)
		case 10250:		// Spanish(Peru)
		case 20490:		// Spanish(Puerto Rico)
		case 15370:		// Spanish(Paraguay)
		case 17418:		// Spanish(El Salvador)
		case 14346:		// Spanish(Uruguay)
		case 8202:		// Spanish(Venezuela)
			// hh:mm:ss tt  - 12 hour format
			if (sHour < 12)
			{
				if (sHour == 0)
					sHour = sHour + 12;
				sTemp = CP_PadZero(sHour,2) + ":" + sMin + ":" + sSec + " a.m.";
			}	
			else
			{
				if (sHour > 12)
					sHour = sHour - 12;
				sTemp = sHour + ":" + sMin + ":" + sSec + " p.m.";
			}				
			break;	
		case 2057:		// English(United Kingdom)
		case 6153:		// English(Ireland)
		case 1036:		// French(Standard)
		case 3084:		// French(Canadian)
		case 4108:		// French(Swiss)
		case 5132:		// French(Luxembourg)
		case 1031:		// German(Standard)
		case 2055:		// German(Swiss)
		case 3079:		// German(Austrian)
		case 4103:		// German(Luxembourg)
		case 5127:		// German(Liechtenstein)
		case 1044:		// Norwegian(Bokmal)
		case 2064:		// Italian(Swiss)
		case 1030:		// Danish(Denmark)
		case 1053:		// Swedish(Sweden)
		case 2077:		// Swedish(Finland)
		case 1046:		// Portuguese(Brazil)
			// HH:mm:ss - 24 hour format
			if (sHour < 10)
				sHour = CP_PadZero(sHour,2);
			sTemp = sHour + ":" + sMin + ":" + sSec;
			break;	
		case 2060:		// French(Belgian)		
		case 1034:		// Spanish(Standard)	
		case 13322:		// Spanish(Chile)
		case 12298:		// Spanish(Ecuador)
		case 1043:		// Dutch(Netherland)
		case 2067:		// Dutch(Belgium)
		case 1035:		// Finnish(Finland)
		case 2070:		// Portuguese(Portugal)
		case 1041:		// Japanese
		case 2052:      // Chinese(PRC)
		case 3076:		// Chinese(Hong Kong)
		case 5124:		// Chinese(Macau)			
		case 3082:      //Spanish(International)	
			// H:mm:ss - 24 hour format
			sTemp = sHour + ":" + sMin + ":" + sSec;
			break;	
		case 1040:		// Italian(Standard)	
			// H.mm.ss - 24 hour format
			sTemp = sHour + "." + sMin + "." + sSec;
			break;		
		case 4100:		// Chinese(Singapore)			
			// tt h:mm:ss - 12 hour format
			if (sHour < 12)
			{
				if (sHour == 0)
					sHour = sHour + 12;
				sTemp = "AM " + sHour + ":" + sMin + ":" + sSec;
			}	
			else
			{
				if (sHour > 12)
					sHour = sHour - 12;
				sTemp = "PM " + sHour + ":" + sMin + ":" + sSec;
			}	
			break;
		case 1028:      // Chinese(Taiwan)
			// tt hh:mm:ss - 12 hour format
			if (sHour < 12)
			{
				if (sHour == 0)
					sHour = sHour + 12;
				sTemp = "AM " + CP_PadZero(sHour,2) + ":" + sMin + ":" + sSec;
			}	
			else
			{
				if (sHour > 12)
					sHour = sHour - 12;
				sTemp = "PM " + sHour + ":" + sMin + ":" + sSec;
			}	
			break;
		case 1042:		// Korean(Korea)
			// tt h:mm:ss - 12 hour format
			if (sHour < 12)
			{
				if (sHour == 0)
					sHour = sHour + 12;
				sTemp = "AM " + sHour + ":" + sMin + ":" + sSec;
			}	
			else
			{
				if (sHour > 12)
					sHour = sHour - 12;
				sTemp = "PM " + sHour + ":" + sMin + ":" + sSec;
			}	
			break;
					
		default:		// default to Engish(US)
			// h:mm:ss tt  - 12 hour format
			if (sHour < 12)
			{
				if (sHour == 0)
					sHour = sHour + 12;
				sTemp = sHour + ":" + sMin + ":" + sSec + " AM";
			}				
			else
			{
				if (sHour > 12)
					sHour = sHour - 12;
				sTemp = sHour + ":" + sMin + ":" + sSec + " PM";
			}	
			break;
	}	
    return sTemp;
}

// CP_dateDiff( interval, date1, date2 )
//
// Description: Calculates the differnces between date1 and date2.
//
// Parameters:
//   interval	String expression.  Parameter "d" for number of and "w" for number of weeks 
//              between date1 and date2.
//   date1  	Date string.  ( Required )
//   date2		Date string.  ( Required )
//
// Usage1:
//		var result = CP_dateDiff("d",date1,date2);
//		if ( isNaN(result) )
//			alert("Invalid date!");
//		else if ( result < 0 )
//			alert("Date 1 is later than date 2!");
//		else
//			alert( result );		// output should be the number of days between date1 and date2
//
// Note:
//   This JavaScript function should be used only when server-side formatting is not feasible.
//   For additional info, please contact Sook-Hee Kim of IDG.
//
function CP_dateDiff( interval, date1, date2 )
{
	var oDate1, oDate2;
	oDate1 = CP_parseLocalDate( date1 );
	if ( isNaN( oDate1.valueOf() ) )
		return oDate1;                
	else
	{	
		oDate2 = CP_parseLocalDate( date2 );
		if ( isNaN( oDate2.valueOf() ) )
			return oDate2;            
		else
		{
			dateDiffInMilliSec = oDate2.valueOf() - oDate1.valueOf();
			// if reminder is more than half day, then add one 
			numberOfDays = parseInt(dateDiffInMilliSec/86400000) + 
				parseInt((dateDiffInMilliSec%86400000)/43200001);
			numberOfWeeks = parseInt( numberOfDays/7 );
			
			if ( interval == "d" )
				return numberOfDays;				
			else if ( interval == "w" )
				return numberOfWeeks;
			else
				return numberOfDays;				
		}			
	}
}

//***************************************************************
// Convert SQL date into a javascript format
// copy from format.js rename to sqlDateToJs for avoiding duplicate
//***************************************************************
function sqlDateToJs(sTime)
{
	var aTmp, iPos, iYear, iMonth, iDate, iHour, iMin, iSec, sTmpTime, dTmpDate;

	//ignore if no date
	if (sTime == null ||sTime == "")
		return "";
 	
 	try
 	{	
		aTmp = sTime.split("-");
		iYear = aTmp[0];
		iMonth = aTmp[1];
		iPos = aTmp[2].indexOf("T");
		sTmpTime = "";
		if (iPos != -1)
		{
			iDate = aTmp[2].substring(0,iPos);			
			sTmpTime = aTmp[2].substring(iPos+1, aTmp[2].length);	
		}	
		else
			iDate = aTmp[2];	
			
		iHour = 0;
		iMin = 0;
		iSec = 0;
		
		if (sqlDateToJs.arguments.length == 1) 	
		{
			aTmp = sTmpTime.split(":")
			iHour = aTmp[0];
			iMin = aTmp[1];
			iSec = aTmp[2];
		}	
		else if (sqlDateToJs.arguments.length == 4) 	
		{
			iHour = sqlDateToJs.arguments[1];
			iMin = sqlDateToJs.arguments[2];
			iSec = sqlDateToJs.arguments[3];
		}	 	
	}
	catch(e)
	{
		return "";
	}	

	//alert("'" + iYear + "' '" + (iMonth-1) + "' '" + iDate + "' '" + iHour + "' '" + iMin + "' '" + iSec + "'");		
	dTmpDate = new Date(iYear, iMonth-1, iDate, iHour, iMin, roundDecimal(parseFloat(iSec),0));
	try
	{
		if (dTmpDate.getTime())
			return dTmpDate;
	}
	catch(e)
	{
		return "";
	}	
}

//***************************************************************
// Format SQL DateTime string into date STRING formatted according to the browser locale setting.
// Base on the function sqlDateToJs and CP_formatDate -- Richard Zhang
//***************************************************************
function CP_formatSQLDate(sDateTime)
{
	var dTempDate;
	
	dTempDate = sqlDateToJs(sDateTime);
	return CP_formatDate(dTempDate,true);
}

//***************************************************************
//Check if the string contains invalid character which will cause a mess in tree view
//***************************************************************
function IsValidateString(sStr)
{
	var s = String(sStr);
	if (isEmpty(s))
		return true;

	// Check for restricted characters
	var re = /\|/g;					// |
	if ( re.test(s) )
		return false;

	return true;
}

//***************************************************************
//Check if the string contains invalid character for Password
//***************************************************************
function validatePassword(p1)
{

	var x=0;
	var y=0;
	var p;
	var p2;
	var symbols;
	var loc;
	p2 = p1.toUpperCase();
	y = p1.length;
	symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	
	for (x=0; x<=y; x++)
	{
		p = p2.charAt(x)
		loc = symbols.indexOf(p);
		if ( loc == -1)
		{
			return false;  //If not in Range
		}	
	}
	
	return true;	
}
//***************************************************************
//Check if the number exceeds maximum amount
//***************************************************************
function checkNumeric(val, num1, num2, str) {
	var sTot = String(val);
	
	if (sTot.indexOf("-") == 0){
		sTot = sTot.substring(1, sTot.length);
	}
	
	if (sTot.substring(0,sTot.indexOf(".")).length>num1 || (sTot.indexOf(".")==-1 && sTot.length>num1)) {
		if (str.length>0)	alert(str);
		return false;
	}
	else {
		return true;
	}
}

//***************************************************************
//Check if the number exceeds maximum amount
//***************************************************************

function checkNumericmax(val, num1, num2,num3, str) {
	var sTot = String(val);
	
	if (sTot.indexOf("-") == 0){
		sTot = sTot.substring(1, sTot.length);
	}
	
	if (sTot.substring(0,sTot.indexOf(".")).length>num1 || (sTot.indexOf(".")==-1 && sTot.length>num1) || (val > num3)) {
		alert(str);
		return false;
	}
	else {
		return true;
	}
}

//***************************************************************
//Check if the string contains invalid character 
//***************************************************************
function ValidateReservedChar(sTmp)
{
	var s = String(sTmp);
	if (isEmpty(s))
		return true;

	// Check for restricted characters
	var re = /\|/g;					// |
	if ( re.test(s) )
		return false;

	return true;
}

//***************************************************************
//Check if the string contains invalid character 
//***************************************************************
function ValidateReservedCharWithAlert(oField, sFieldName)
{
	if ((oField == undefined) || (oField.value == undefined))
		return true;
		
	var s = String(oField.value);
	if (isEmpty(s))
		return true;

	// Check for restricted characters
	var re = /\|/g;					// |
	if ( re.test(s) )
	{
		//alert("The field ÿxÿ cannot contain any of the following character(s): |");
		alert(inJsValidate_GetDString(jvmsginvalstr, sFieldName, ""));
		try {
			oField.focus();
		}
		catch(e) {}
		return false;
	}

	return true;
}

//***************************************************************
//Get parent variable
//sVariable: variable name is looked for.
//iLoopsCnt: Optional. Total loops for recursion. Default is 1.
//iLoops: Reserved by itself.
//e.g.:	LocalID = GetParentVar("jvusrLCID",5);
//***************************************************************
function GetParentVar(sVariable,iLoopsCnt,iLoops)
{
	var LoopsCnt = 0;
	var myLoop = 1;
		
	if(GetParentVar.arguments.length > 1)
		LoopsCnt = iLoopsCnt;
	if(GetParentVar.arguments.length > 2)
		myLoop = iLoops + 1;
	var pStr = "parent." + sVariable;
	var pVar = eval(pStr);
	if((pVar != null)||(myLoop > LoopsCnt))
		return pVar;
	else
		return GetParentVar(pStr,LoopsCnt,myLoop);
}

function ValidateURL(sUrl, sServerName)
{
	if (sUrl.charAt(0) == "/" || sUrl.charAt(0) == "\\")
	{
		sUrl = sServerName + sUrl;
	}
	else if (sUrl.indexOf("://") == -1 && sUrl.indexOf(":\\\\") == -1)
	{
		sUrl = "http://" + sUrl;
	}
	var re = /(http|https):\/\/[\w]+(.[\w]+)([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/	
	if (sUrl.match(re))	
		return true;
	else
		return false;
}

// function:    check string for correct GUID formatting
// sStr:	    string to check
function ValidateGuid(sStr)
{
	var s = String(sStr);
	
	// checks for GUIDs (case-insensitive, with or w/o brackets)
	var regEx = new RegExp(/^\{?[a-fA-F\d]{8}-([a-fA-F\d]{4}-){3}[a-fA-F\d]{12}\}?$/);	
	
	if (s.match(regEx))	
	    return true;
	else
	    return false;				
}

//function to append starting and ending curly braces to id if required
function appendBracesToId(sId)
{
	var sTarget;

	sTarget = sId;
	if (sTarget.length > 0){
		if (sId.indexOf("{") == -1) 
			sTarget = "{" + sTarget;
		if (sId.indexOf("}") == -1)  
			sTarget = sTarget + "}";
		sTarget = sTarget.toUpperCase();
	}
	return sTarget;
}
//function to remove starting and ending curly braces to id if required
 function RemoveBracesFromId(sID)
{
	var sTarget = new String(sID);
	sTarget = sTarget.replace("{","");
	sTarget = sTarget.replace("}","");
	return sTarget;
}

/**********************************************
  Convert javascript data into a SQL format
	
	iFormatTime
	0 - 00:00:00
	1 - time in dDate
	2 - current time
	3 - specify hr, min, sec by passing 3 more parameters ( hr, min, sec)
***********************************************/	
function ConvJsDateToSql(dDate, iFormatTime)
{		
	if (!dDate.getYear())
		return "";

	var sYear = dDate.getFullYear();
	var sMonth = dDate.getMonth()+1;
	var sDate = dDate.getDate();
	var sHour, sMin, sSec;
	var dTmpDate;
	
	sHour = 0; 
	sMin = 0;
	sSec = 0;
	
	switch (iFormatTime)
	{
		case 0:
			sHour = 0;
			sMin = 0;
			sSec = 0;
			break;
		case 1:
			sHour = dDate.getHours();
			sMin = dDate.getMinutes();
			sSec = dDate.getSeconds();
			break;
		case 2:
			dTmpDate = new Date();				
			sHour = dTmpDate.getHours();
			sMin = dTmpDate.getMinutes();
			sSec = dTmpDate.getSeconds();
			break;
		case 3:
			sHour = parseInt(ConvJsDateToSql.arguments[2]);
			sMin = parseInt(ConvJsDateToSql.arguments[3]);
			sSec = parseInt(ConvJsDateToSql.arguments[4]);
	}
	
	if (sMonth < 10) sMonth = "0" + sMonth;
	if (sDate < 10) sDate = "0" + sDate;
	if (sHour < 10) sHour = "0" + sHour;
	if (sMin < 10) sMin = "0" + sMin;
	if (sSec < 10) sSec = "0" + sSec;
	
	return sYear + "-" + sMonth + "-" + sDate + "T" + sHour + ":" + sMin + ":" + sSec;
}

function trim(varIn)
{
   var varOut = "" 
   var begin = 0

    if(!varIn)
     {
      // string is null, so nothing to do
     }
    else // string has at least one character
     {
      for(intI=0; intI < varIn.length; intI++)
       {
        if(varIn.charAt(intI) != " ")
         {
          //first non-space char found so return
          //string from this character forward
          //varOut = varIn.substring(intI)
          begin=intI
          break
         }
       }
	
      for(intI=varIn.length; intI >0 ; intI--)
       {
         if(varIn.charAt(intI-1) != " ")
          {
           varOut = varIn.substring(begin,intI)
           break
          }
       }
		
     }
     return varOut
}

function GetDString(Str_s, Str_r1, Str_r2, Str_r3, Str_r4, Str_r5)
{
    var ds;
    if(Str_s.indexOf(unescape("%ffx%ff")) != -1 || Str_s.indexOf(unescape("%ffy%ff")) != -1)
	{
	    ds = Str_s.replace(unescape("%ffx%ff"), Str_r1);
	    if (Str_r2 != "")
		    ds = ds.replace(unescape("%ffy%ff"), Str_r2);

	    // do z1, z2, z3
	    if (GetDString.arguments.length > 3)
	    {
		    ds = ds.replace(unescape("%ffz1%ff"), Str_r3);

		    if (GetDString.arguments.length > 4)
		    {
			    ds = ds.replace(unescape("%ffz2%ff"), Str_r4);

			    if (GetDString.arguments.length > 5)
				    ds = ds.replace(unescape("%ffz3%ff"), Str_r5);
		    }
	    }
	 }
	 else
	 {
	    ds = Str_s.replace(unescape("%ffz1%ff"), Str_r1);
	    if (Str_r2 != "")
    	    ds = ds.replace(unescape("%ffz2%ff"), Str_r2);
        if (Str_r3 != "")
    	    ds = ds.replace(unescape("%ffz3%ff"), Str_r3);	 
	 }

	return tRepBracket(ds);
}

function tRepBracket( strIn ){
	var strOut = strIn;
	var re;

	if ( strIn.indexOf("<a ") > -1 || strIn.indexOf("<A ") > -1 || strIn.indexOf("</a>") > -1 || strIn.indexOf("</A>") > -1 )
	{
		re = /\<[aA]/g;			// <a 
		strOut = strOut.replace(re, "|<|a");
		re = /\<\/[aA]/g;			// </a
		strOut = strOut.replace(re, "|<|/a");
		re = /\>/g;			// >
		strOut = strOut.replace(re, "|>|");
		re = /\&/g;		// &
		strOut = strOut.replace(re, "|&|");
		re = /\"/g;			// "
		strOut = strOut.replace(re, "|\"|");
		re = /\'/g;			// '
		strOut = strOut.replace(re, "|'|");
		re = /\<\/.*?/g;			// </
		strOut = strOut.replace(re, "|</|");
	}
	
	return strOut;
}

