function trim(value) {
	startposn = 0;
	while ((value.charAt(startposn) == " ") && (startposn < value.length)) {
		startposn++;
	}
	if (startposn == value.length) {
		value="";
	} else {
		value = value.substring(startposn,value.length);
		endposn = (value.length) - 1;
		while (value.charAt(endposn) == " ") {
			endposn--;
		}
		value = value.substring(0, endposn + 1);
	}
	return (value);
}

function empty(string) {
	return (trim(string).length == 0);
}

function jsleft(string, len) {
	return string.substr(0,len);
}

function jsright(string, len) {
	pos = string.length - len;
	return string.substr(pos);
}

function setSelect(oSelect, cValue) {
	for (nXYZ = 0; nXYZ < oSelect.length; nXYZ++) {
		cOption = oSelect.item(nXYZ).value;
		if (cOption == cValue) 
			oSelect.selectedIndex = nXYZ;
	}
}

function formatNumber(nNum, nDec, lLeading, lAllowBlank, lBlankZero) {
	cRet = ""
	cPre = "0"
	cPost = ""
	
	cNum = nNum.toString();
	if (cNum.indexOf(".") == -1) {
		cPre = cNum;
	} else {
		cPre = cNum.substr(0, cNum.indexOf("."));
		cPost = cNum.substr(cNum.indexOf(".") + 1);
	}
	
	if (!lBlankZero){
		if (cPre.valueOf() == "") {
			if (lLeading)
				cRet = "0";
			else
				cRet = "";
		} else {
			cRet = cPre;
		}		
	}
	else {
		if (cPre.valueOf() == 0) {
			if (lLeading)
				cRet = "0";
			else
				cRet = "";
		} else {
			cRet = cPre;
		}
		}

	if (cPost.length > nDec)
		cPost = cPost.substr(cPost, nDec);

	if (!(lAllowBlank && cRet.valueOf() == "" && cPost.valueOf() == ""))
		 {		
		for (i = cPost.length; i < nDec; i++)
			cPost = cPost + "0";

		if (nDec > 0)
			cRet = cRet + "." + cPost;
		}
	
	return cRet;
}


function formatPercentage(nNum, nDec, lLeading) {
	cRet = ""
	cPre = "0"
	cPost = ""
		
	cZero = "."
		
	for (i = 0; i < nDec; i++)
		cZero = cZero + "0";
			
	cNum = nNum.toString();
		
	while (cNum.substr(0,1) == "0")
	{
		cNum = cNum.substr(1);
	}
		
	if (cNum.indexOf(".") == -1) {
		cNum = cNum + cZero.substr(0, nDec + 1);
	} 
	nIndex = cNum.indexOf(".")
	if (nNum > 1 && nNum < 10) {
		cPost = "0" + cNum.substr(0,1) + cNum.substr(nIndex + 1,nDec - 2);
	}
	else {
		if (nNum >= 10 && nNum < 100) {
			cPost = cNum.substr(0,2) + cNum.substr(nIndex + 1, nDec - 2);
		}
		else {
			if (nNum == 100) {
				cPre = "1"
				cPost =  cZero.substr(1, nDec); 
			}
			else {
				cPre = cNum.substr(0, nIndex);
				cPost = cNum.substr(nIndex + 1, nDec);
			}
		}
	}
		
	if (cPre.valueOf() == 0) {
		if (lLeading)
			cRet = "0";
		else
			cRet = "";
	} else {
		cRet = cPre;
	}
	
	if (cPost.length > nDec)
		cPost = cPost.substr(cPost, nDec);
	
	for (i = cPost.length; i < nDec; i++)
		cPost = cPost + "0";

	if (nDec > 0)
		cRet = cRet + "." + cPost;
	
	return cRet;
}

function vUCaseKey(oField) {
	cChar = String.fromCharCode(event.keyCode);
	if (cChar == cChar.toLowerCase()) {
		cChar = cChar.toUpperCase();
		event.keyCode = cChar.charCodeAt(0);
	}
}

function vICapBlur(oField) {
	oField.value = oField.value.charAt(0).toUpperCase() + oField.value.substr(1);
}

function vICapKey(oField) {
	cText = oField.value;
	if (cText.length == 0) {
		event.keyCode = String.fromCharCode(event.keyCode).toUpperCase().charCodeAt(0);
	}
}

function stripZero(cString) {
	//while (cString.substr(0,1) == "0")
	while (jsleft(cString,1) == "0")
		cString = cString.substr(1);
	return cString;
}
	
function FebDays(nYear) {
	if (nYear % 4 != 0)
		return 28;
	if (nYear % 400 == 0)
		return 29;
	if (nYear % 100 == 0)
		return 28;
	else
		return 29;
}

function isDate(cMonth, cDay, cYear) {
	var aMonths = new Array();
		aMonths[1] = 31;
		aMonths[2] = 28;
		aMonths[3] = 31;
		aMonths[4] = 30;
		aMonths[5] = 31;
		aMonths[6] = 30;
		aMonths[7] = 31;
		aMonths[8] = 31;
		aMonths[9] = 30;
		aMonths[10] = 31;
		aMonths[11] = 30;
		aMonths[12] = 31;
		
	nMonth = parseInt(stripZero(cMonth),10);
	nDay   = parseInt(stripZero(cDay),10);
	nYear  = parseInt(stripZero(cYear),10);
	
	// verify all are valid #s	
	if (isNaN(nMonth) || isNaN(nDay) || isNaN(nYear))
		return false;
	;
	// verify month in range		
	if (nMonth < 1 || nMonth > 12)
		return false;
		
	// verify year in range	
	if (nYear < 1000 || nYear > 9999)
		return false;

	// verify days in range for month	
	if (nMonth == 2) {
		if (nDay < 1 || nDay > FebDays(nYear))
			return false;
	} else {
		if (nDay < 1 || nDay > aMonths[nMonth])
			return false;
	}
				
	return true;	
}

function vDateBlur(oField) {
	lOK = true;
		
	// check for empty input
	if (empty(oField.value))
		return true;

	// break date down and validate
	aDate = oField.value.split("/");
	switch(aDate.length) {
		case 1:
			// no slashes entered, so we infer their location
			switch(aDate[0].length) {
				case 4:
					aDate[2] = new Date().getFullYear().toString();
					aDate[1] = jsright(aDate[0],2);
					aDate[0] = jsleft(aDate[0],2);
					lOK = isDate(aDate[0],aDate[1],aDate[2]);
					break;
				case 6:
					nYear = parseInt(jsright(aDate[0],2),10);
					if (nYear >= 0 && nYear < 50) {
						nYear += 2000;
					} else {
						if (nYear < 100)
							nYear += 1900;
					}
					aDate[2] = nYear.toString();
					aDate[1] = aDate[0].substr(2,2);
					aDate[0] = jsleft(aDate[0],2);
					lOK = isDate(aDate[0],aDate[1],aDate[2]);

					break;
				case 8:
					aDate[2] = jsright(aDate[0],4);
					aDate[1] = aDate[0].substr(2,2);
					aDate[0] = jsleft(aDate[0],2);
					lOK = isDate(aDate[0],aDate[1],aDate[2]);
					break;
				default:
					lOK = false;
			}
			break;
		case 2:
			// only month and day entered, infer year
			aDate[2] = new Date().getFullYear().toString();
			lOK = isDate(aDate[0],aDate[1],aDate[2]);
			break;
		case 3:	
			// full date entered
			nYear = parseInt(aDate[2],10);
			
			if (nYear >= 0 && nYear < 50) {
				nYear += 2000;
			} else {
				if (nYear < 100)
					nYear += 1900;
			}
			aDate[2] = nYear.toString();
			lOK = isDate(aDate[0],aDate[1],aDate[2]);
			break;
		default:
			lOK = false;
	}

	// handle valid or invalid
	if (lOK) {
		oField.value = jsright("00" + aDate[0],2) + "/" + jsright("00" + aDate[1],2) + "/" + aDate[2];
	} else {
		alert("Invalid Date");
		oField.focus();
	}
}
	
function vDateKey(oField) {
	var cValid = "0123456789/";
	cChar = String.fromCharCode(event.keyCode);
	if (cValid.indexOf(cChar) == -1)
		event.returnValue = false;
}

function vCommrateBlur(oField, nWidth, nDec) {
	if (oField.value == "(Infinity)")
		return true;

	if (nDec == 0)
		cBefore = nWidth.toString();
	else
		cBefore = (nWidth - (nDec + 1)).toString();
			
	cDec    = nDec.toString();
	cMask   = "^(-)?\\d{0," + cBefore + "}(\\.\\d{0," + cDec + "})?$"
	oRegExp = new RegExp(cMask);
	if (!oRegExp.test(oField.value)) {
		alert("Invalid format: Use " + nWidth.toString() + " digits with " + 
			                              nDec.toString() + " decimal places");
		oField.focus();
	} else {
		oField.value = formatNumber(oField.value, nDec, true, false, true);
	}
}

function vCommrateKey(oField) {
	var cValid = "0123456789";
	cChar = String.fromCharCode(event.keyCode);
	if (cValid.indexOf(cChar) == -1)
		event.returnValue = false;
}

function vDurBlur(oField) {
	cTime = oField.value;
		
	if (empty(cTime))
		return;
		
	nColon = cTime.indexOf(":");
	if (nColon == -1) {
		nHour = parseInt(cTime, 10);
		nMinute = 0;
		// change "15" to "00:15", etc
		if (nHour >= 5) {
			nNewHour = Math.floor(nHour / 100);
			nMinute = nHour % 100;
			nHour = nNewHour;
				
			if (nMinute > 59) {
				nHour = nHour + Math.floor(nMinute / 60);
				nMinute = nMinute % 60;
			}
		}
	} else {
		nHour = parseInt(jsleft(cTime, nColon),10);
		nMinute = parseInt(cTime.substr(nColon+1),10);

		if (isNaN(nHour)) { 
			nHour = 0
		}
		if (isNaN(nMinute)) { 
			nMinute = 0
		}
			
		if (nMinute > 59) {
			nHour = nHour + Math.floor(nMinute / 60);
			nMinute = nMinute % 60;
		}
	}
	if (nHour < 0 || nMinute < 0 || nMinute > 59) {
		alert("Invalid Duration");
		oField.focus();
	} else {
		oField.value = jsright("00" + nHour,2) + ":" + jsright("00" + nMinute,2);
	}
}

function vDurKey(oField) {
	var cValid = "0123456789:";
	cChar = String.fromCharCode(event.keyCode);
	if (cValid.indexOf(cChar) == -1)
		event.returnValue = false;
}

function vIPAddressBlur(oField) {
	cValue = oField.value;

	if (empty(cValue))
		return;

	cArray = cValue.split(".");
		
	nArrayLength = cArray.length;
		
	lTooBig = false;
		
	for (i = 0; i < nArrayLength; i++)
		{
		if (cArray[i].length == 0)
			{
			cArray[i] = "0";
			}
				
		if (parseInt(cArray[i],10) < 0 || parseInt(cArray[i],10) > 255)
			lTooBig = true;
		}
		
	if (nArrayLength != 4 || lTooBig) {
		alert("Please enter a valid IP address (XXX.XXX.XXX.XXX)");
		oField.focus();
	} else {
		oField.value = cArray.join(".");
	}
}
	
function vIPAddressKey(oField) {
	var cValid = "0123456789.";
	cChar = String.fromCharCode(event.keyCode);
	if (cValid.indexOf(cChar) == -1)
		event.returnValue = false;
}

function vNumBlur(oField, nWidth, nDec, lLead, lNegative, lAllowBlank, lBlankZero) {
	if (nDec == 0)
		cBefore = nWidth.toString();
	else
		cBefore = (nWidth - (nDec + 1)).toString();
			
	cDec    = nDec.toString();
	if (lNegative)
		cMask   = "^(-)?\\d{0," + cBefore + "}(\\.\\d{0," + cDec + "})?$";
	else
		cMask   = "^\\d{0," + cBefore + "}(\\.\\d{0," + cDec + "})?$";
		
	oRegExp = new RegExp(cMask);
	if (!oRegExp.test(oField.value)) {
		alert("Invalid format: Use " + nWidth.toString() + " digits with " + 
		                               nDec.toString() + " decimal places");
		oField.focus();
	} else {
		oField.value = formatNumber(oField.value, nDec, lLead, lAllowBlank, lBlankZero);
	}
}

function vSMSNumBlur(oField, nWidth, nDec, lLead, lNegative, lAllowBlank, lBlankZero) {
	cValue = oField.value;

	if (cValue == "NR")
		return;

	if (nDec == 0)
		cBefore = nWidth.toString();
	else
		cBefore = (nWidth - (nDec + 1)).toString();
			
	cDec    = nDec.toString();
	if (lNegative)
		cMask   = "^(-)?\\d{0," + cBefore + "}(\\.\\d{0," + cDec + "})?$";
	else
		cMask   = "^\\d{0," + cBefore + "}(\\.\\d{0," + cDec + "})?$";
		
	oRegExp = new RegExp(cMask);
	if (!oRegExp.test(oField.value)) {
		alert("Invalid format: Use " + nWidth.toString() + " digits with " + 
		                               nDec.toString() + " decimal places");
		oField.focus();
	} else {
		oField.value = formatNumber(oField.value, nDec, lLead, lAllowBlank, lBlankZero);
	}
}

function vNumKey(oField, cNegative) {
	if (cNegative == "1")
		cValid = "0123456789.-";
	else
		cValid = "0123456789."
		
	cChar = String.fromCharCode(event.keyCode);
	if (cValid.indexOf(cChar) == -1)
		event.returnValue = false;
}

function vOrderNumListKey(oField) {
	cValid = "0123456789,";
		
	cChar = String.fromCharCode(event.keyCode);
	nChar = event.keyCode;
	
	if (cValid.indexOf(cChar) == -1 && nChar != 13)
		event.returnValue = false;
}

function vPercentageBlur(oField, nDec) {
	nNum = oField.value;
	cNum = nNum.toString();
		
	if (nNum > 100 || (cNum.indexOf(".") != cNum.lastIndexOf("."))) {
		alert("Invalid format: Enter XX percent as XX or .XX");
		oField.focus();		
	}
	else {
		oField.value = formatPercentage(nNum, nDec, true);
	}
}

function vPercentageKey(oField) {
	var cValid = "0123456789.";
	cChar = String.fromCharCode(event.keyCode);
	if (cValid.indexOf(cChar) == -1)
		event.returnValue = false;
}

function vPhoneFocus(oField, cAreaCode) {
	if (empty(oField.value) && !empty(cAreaCode) && cAreaCode != "0")
		{
		oField.value = cAreaCode + "-";
		cTextRange = oField.createTextRange();
		cTextRange.collapse(false);
		cTextRange.select();
		}
}

function vPhoneBlur(oField, cAreaCode) {
	cValue = oField.value;

	if (cValue == cAreaCode + '-') {
		oField.value = "";
		return;
	}

	if (empty(cValue))
		return;

	cDigits = "";
	for (i = 0; i < cValue.length; i++)
		if (cValue.charAt(i) != "-")
			cDigits += cValue.charAt(i);
		
	if (cDigits.length != 10) {
		alert("Please enter a full phone number (XXX-XXX-XXXX)");
		oField.focus();
	} else {
		oField.value = jsleft(cDigits,3) + "-" + cDigits.substr(3, 3) + "-" + jsright(cDigits,4);
	}
}
	
function vPhoneKey(oField) {
	cValid = "0123456789-";
	
	cChar = String.fromCharCode(event.keyCode);
	if (cValid.indexOf(cChar) == -1)
		event.returnValue = false;
}

function vTimeBlur(oField, cAmPm) {
	cTime = oField.value;
	if (empty(cTime))
		return;
		
	nColon = cTime.indexOf(":");
	if (nColon == -1) {
		if (cTime.length == 4) {
			nHour = jsleft(cTime,2);
			nMinute = cTime.substr(2);
		} 
		
		if (cTime.length == 3) {
			nHour = jsleft(cTime,1);
			nMinute = cTime.substr(1);
		}
			
		if (cTime.length == 1 || cTime.length == 2 || cTime.length == 5) {
			nHour = parseInt(cTime,10);
			nMinute = 0;
			}
	} else {
		nHour = jsleft(cTime, nColon);
		nMinute = cTime.substr(nColon+1);
	}
	if (nHour < 1 || nHour > 12 || nMinute < 0 || nMinute > 59) {
		alert("Invalid Time");
		oField.focus();
	} else {
		oField.value = jsright("00" + nHour,2) + ":" + jsright("00" + nMinute,2);
		if (!empty(cAmPm)) {
			oAmPm = document.all(cAmPm);
			if (nHour == 12 || nHour < 7) {
				setSelect(oAmPm, "PM");
			} else {
				setSelect(oAmPm, "AM");
			}
		}
	}
}

function vTimeKey(oField) {
	var cValid = "0123456789:";
	cChar = String.fromCharCode(event.keyCode);
	if (cValid.indexOf(cChar) == -1)
		event.returnValue = false;
}

function vTimesheetBlur(oField, nWidth, nDec) {
	if (nDec == 0)
		cBefore = nWidth.toString();
	else
		cBefore = (nWidth - (nDec + 1)).toString();
			
	cDec    = nDec.toString();
	cMask   = "^\\d{0," + cBefore + "}(\\.\\d{0," + cDec + "})?$"
	oRegExp = new RegExp(cMask);
	if (!oRegExp.test(oField.value)) {
		alert("Invalid format: Use " + nWidth.toString() + " digits with " + 
		                               nDec.toString() + " decimal places");
		oField.focus();
	} else {
		if (oField.value == 0) {
			oField.value = "";
		} else {
			oField.value = formatNumber(oField.value, nDec, true, false, true);
		}
	}
}

function vTimesheetKey(oField) {
	var cValid = "0123456789.";
	cChar = String.fromCharCode(event.keyCode);
	if (cValid.indexOf(cChar) == -1)
		event.returnValue = false;
}

function vYearBlur(oField) {
	lOK = true;
		
	// check for empty input
	if (empty(oField.value))
		lOK = false;
		
	else {
	// validate year
	  nYear = parseInt(oField.value, 10);
	if (nYear >= 0 && nYear < 50) {
		nYear += 2000;
	} else {
		 if (nYear < 100)
			nYear += 1900;
	}
	lOK = (nYear > 1000 && nYear < 9999);
			 
	}

	// handle valid or invalid
	if (lOK) {
		oField.value = nYear;
	} else {
		alert("Invalid Year");
		oField.focus();
	}
}
	
function vYearKey(oField) {
	var cValid = "0123456789";
	cChar = String.fromCharCode(event.keyCode);
	if (cValid.indexOf(cChar) == -1)
		event.returnValue = false;
}

function vTextareaKey(oField, MaxLength) {
	nLen = oField.value.length;
	if (nLen >= MaxLength)
		event.returnValue = false;
}

function vTextareaBlur(oField, nMaxLength, nLines) {
	oField.value = jsleft(oField.value, nMaxLength);
}
	
function vTextareaKeyDown(oField, nMaxLength, nLines) {
	if (event.keyCode == 13) {
		var cStr = oField.value;
		aStr = cStr.split('\r');
		if (aStr.length > (nLines - 1)) {
			event.returnValue = false;
		}
	}
}

function vTaxIDBlur(oField) {
	cValue = oField.value;
	cTaxID = false;
	cSS = false;

	if (empty(cValue))
		return;

	cDigits = "";
	for (i = 0; i < cValue.length; i++){
		if (cValue.charAt(i) != "-")
			cDigits += cValue.charAt(i);
			
		if ((i == 2) && (cValue.charAt(i) == "-"))
			cTaxID = true;
		
		if ((i == 3) && (cValue.charAt(i) == "-"))
			cSS = true;
	}
		
	if (cDigits.length != 9) {
		alert("Invalid Tax ID");
		oField.focus();
	} 
	
	else {
		if (cTaxID)
			oField.value = jsleft(cDigits,2) + "-" + jsright(cDigits,7);
		else if (cSS)
			oField.value = jsleft(cDigits,3) + "-" + cDigits.substr(4, 2) + "-" + jsright(cDigits,4);
		else {
			alert("Invalid Tax ID");
			oField.focus();
		}
	}
}
	
function vTaxIDKey(oField) {
	var cValid = "0123456789-";
	cChar = String.fromCharCode(event.keyCode);
	if (cValid.indexOf(cChar) == -1)
		event.returnValue = false;
}

function v1099TypeKey(oField) {
	var cValid = "IMim";
	cChar = String.fromCharCode(event.keyCode);

	if (cValid.indexOf(cChar) == -1)
		event.returnValue = false;

	if (cChar == cChar.toLowerCase()) {
		cChar = cChar.toUpperCase();
		event.keyCode = cChar.charCodeAt(0);
	}
}

function vYesNoKey(oField) {
	var cValid = "YyNn";
	cChar = String.fromCharCode(event.keyCode);

	if (cValid.indexOf(cChar) == -1)
		event.returnValue = false;

	if (cChar == cChar.toLowerCase()) {
		cChar = cChar.toUpperCase();
		event.keyCode = cChar.charCodeAt(0);
	}
}


function vSharePercentageBlur(oField, nDec) {
	nNum = oField.value;
	cNum = nNum.toString();
		
	if (nNum > 100 || (cNum.indexOf(".") != cNum.lastIndexOf("."))) {
		alert("Invalid format: Enter XX percent as XX or .XX");
		oField.focus();		
	}
	else {
		oField.value = formatSharePercentage(nNum, nDec, true);
	}
}

function formatSharePercentage(nNum, nDec, lLeading) {
	cRet = ""
	cPre = "0"
	cPost = ""
	
	cZero = "."
		
	for (i = 0; i < nDec; i++)
		cZero = cZero + "0";
			
	cNum = nNum.toString();
		
	while (cNum.substr(0,1) == "0")
	{
		cNum = cNum.substr(1);
	}
		
	if (cNum.indexOf(".") == -1) {
		cNum = cNum + cZero.substr(0, nDec + 1);
	} 
	nIndex = cNum.indexOf(".")

	if (nNum >= 10 && nNum < 100) {
		cPost = cNum.substr(0,2) + cNum.substr(nIndex + 1, nDec - 2);
	}
	else {
		if (nNum == 100) {
			cPre = "1"
			cPost =  cZero.substr(1, nDec); 
		}
		else {
			cPre = cNum.substr(0, nIndex);
			cPost = cNum.substr(nIndex + 1, nDec);
		}
	}
		
	if (cPre.valueOf() == 0) {
		if (lLeading)
			cRet = "0";
		else
			cRet = "";
	} else {
		cRet = cPre;
	}
	
	if (cPost.length > nDec)
		cPost = cPost.substr(cPost, nDec);
	
	for (i = cPost.length; i < nDec; i++)
		cPost = cPost + "0";

	if (nDec > 0)
		cRet = cRet + "." + cPost;
	
	return cRet;
}