/* Input Validation
 * 
 * These functions are used to validate web form 
 * validations during keypress and blur events on:
 *	  - text inputs
 *    - text area inputs
 *
 * Use these to make sure the user is typing in the
 * correct set of valid characters, numbers, number ranges,
 * date formats, etc.
 *
 * Usage Examples: 
 *	Number Text Fields:
 *		<input type="text" size="any appropriate number" onBlur="validate_number_blur(this, 11, 0, -2147483648, 2147483647)" onKeyPress="return validate_number_keypress(this, 11, 0, -2147483648, 2147483647, event)">
 *  Date Text Fields:
 *		<input type="text" size="12" maxlength="10" onBlur="validate_date_blur(this)" onKeyPress="return validate_date_keypress(event)">
 *  Character Text Fields:
 *      <input type="text" size="any appropriate number" onBlur="validate_chars_blur(this, 'abcdef')" onKeyPress="return validate_chars_keypress('abcdef', event)">
 *  Lowers Text Fields:
 *      <input type="text" size="any appropriate number" onBlur="validate_lowers_blur(this)" onKeyPress="return validate_lowers_keypress(event)">
 *  Uppers Text Fields:
 *      <input type="text" size="any appropriate number onBlur="validate_uppers_blur(this)" onKeyPress="return validate_uppers_keypress(event)">
 *  Text Areas:
 *		<textarea rows="10" cols="70" onBlur="textarea_limit_text(this,100000000)" onKeyUp="return textarea_limit_text(this,100000000)"/></textarea>
 */
 function enforceDisabledOptions_onChange(me) {
	switch (me.type) {
		case "select-one":
			if (me.options[me.selectedIndex].value=='-1') {
				me.selectedIndex=0;
				return false;
			} else return true;	
			break;
		case "select-multiple":
			for (var i=0; i<me.options.length; i++)
				if (me.options[i].value=='-1') 
					me.options[i].selected = false;
			break;
	}
 }
 function navigate(e,tabForward,tabBackward,left,up,right,down) {
	// usage: 
	//		For Tabing -
	//		onKeyDown="return navigate(event,document.forms[0].nextField,null,null,null,null);"
	//
	//		For Using Next Arrows (like radio button lists)
	//		onKeyDown="return navigate(event,document.forms[0].submitButton,null,document.forms[0].fieldAbove,null,document.forms[0].fieldBelow);"
	
	key = (e.which) ? e.which : e.keyCode;
	function isSelectable(me) {if (me.type == "text" || me.type == "password" || me.type == "textarea") return true;}
	switch (key) {
		case 9: // tab
			if (!e.shiftKey) {
				if (tabForward != null) {
					tabForward.focus();
					if (isSelectable(tabForward)) tabForward.select();
				} else return true;
			} else {
				if (tabBackward != null) {
					tabBackward.focus();
					if (isSelectable(tabBackward)) tabBackward.select();
				} else return true;
			}
			break;
		case 37: // left
			if (left != null) {
				left.focus();
				if (isSelectable(left)) left.select();
			} else return true;
			break;
		case 38: // up
			if (up != null) {
				up.focus();
				if (isSelectable(up)) up.select();
			} else return true;
			break;
		case 39: // right
			if (right != null) {
				right.focus();
				if (isSelectable(right)) right.select();
			} else return true;
			break;
		case 40: // down
			if (down != null) {
				down.focus();
				if (isSelectable(down)) down.select();
			} else return true;
			break;
		default:
			return true;
	}
	return false;
}
function autoMove(me, numChars, target, e) {
	return;
	try {
		if (me.type=="select") {
			target.focus();
			target.select();
		} else if (me.value.length >= numChars) {
			var key = (e.which) ? e.which : e.keyCode;
			if(key<20) return;
			target.focus();
			target.select();
		}
	} catch(er) {
		// do nothing
		// an error may occur due to the element being invisible or otherwise not "focusable"
	} 
}
function validate_chkbx(chkbx_name, min) {
	var num=0;
	var f = document.forms[0];
	for(var i=0;i<f.elements.length;i++)
		if(f.elements[i].type=="checkbox") 
			if(f.elements[i].name.indexOf(chkbx_name) >= 0)
				if(f.elements[i].checked) num++;
	if(num>=min) return true;
	else return false;
}
 function validate_number_blur(me, len, precision, lbound, ubound) {
	if(me.value=="") {return true;}
	
	numSplit=me.value.split('.');
	numVal=me.value;
	// testing only numbers
	if(isNaN(numVal)) {alert("You did not enter a number, please try again.");me.select();me.focus();return false;}
	// testing lower bounds
	if(numVal<lbound) {alert("Number is too small, please try again.");me.select();me.focus();return false;}
	// testing upper bounds
	if(numVal>ubound) {alert("Number is too big, please try again.");me.select();me.focus();return false;}
	if(numSplit.length==2)
		// testing precision
		if(numSplit[1].length>precision) {alert("Precision must be less than or equal to " + precision + " numbers long, please try again.");me.select();me.focus();return false;}
	else
		if(numSplit[0][0]=="-")
			// testing length
			if(numSplit[0].length-1>len) {alert("Number must be less than or equal to " + len + " numbers long, please try again.");me.select();me.focus();return false;}
		else
			// testing length
			if(numSplit[0].length>len) {alert("Number must be less than or equal to " + len + " numbers long, please try again.");me.select();me.focus();return false;}
	me.value=Number(me.value);
	return true;
}
function validate_number_keypress(me, len, precision, lbound, ubound, e) {
	key = (e.which) ? e.which : e.keyCode;
	if(key<20) return true;
	numVal=me.value.split('.');
	// the new number (assuming that carrot is at the end of the input)
	newNum=parseFloat(String(me.value) + String.fromCharCode(key));
	if(numVal.length==2) {  
		// testing '-'
		if(key==45 && lbound < 0 && numVal[0]=="") return true;
		// testing precision
		if(numVal[1].length>=precision) return false;
		// testing lower and upper bounds
		if(newNum<lbound || newNum>ubound) return false;
		// testing character bounds (only numbers)
		if(key>47&&key<58) return true;
		return false;
	} else {
		// testing '.'
		if(key==46 && precision>0 && me.value>=lbound && me.value<=ubound) return true;
		// testing '-'
		if(key==45 && lbound < 0 && numVal[0]=="") return true;								
		if(numVal[0][0]=="-")
			// testing length
			if(numVal[0].length-1>len) return false;
		else
			// testing length
			if(numVal[0].length>len) return false;
		// testing lower and upper bounds
		if(newNum<lbound || newNum>ubound) return false;
		// testing character bounds (only numbers)
		if(key>47&&key<58) return true;
		return false;
	}
}
function validate_chars_keypress(vals, e) {
	var charCode = (e.charCode) ? e.charCode : e.keyCode;
	for (i=0; i<vals.length; i++) {
		if (String.fromCharCode(charCode) == vals.charAt(i)) return true;
	}
	return false;		
}

function validate_uppers_keypress(e) {
	key = (e.which) ? e.which : e.keyCode;
	if (key >= 65 && key <= 90) return true;
	else if (key >= 97 && key <= 122) {e.keyCode = e.keyCode - 32; return true;}
	else return false;		
}

function validate_lowers_keypress(e) {
	key = (e.which) ? e.which : e.keyCode;
	if (key >= 97 && key <= 122) return true;
	else return false;		
}
function validate_chars_blur(me, vals) {
	for (i=0; i<me.value.length; i++) {
		var valid = false;
		for (j=0; j<vals.length; j++) if (me.value.charAt(i) == vals.charAt(j)) valid = true;
		if (!valid) {alert("Invalid input, please try again.");me.select();me.focus();return false;}
	}
	return true;
}
function validate_uppers_blur(me) {
	for (i=0; i<me.value.length; i++) {
		if (!(me.value.charCodeAt(i) >= 65 && me.value.charCodeAt(i) <= 90) && !(me.value.charCodeAt(i) >= 97 && me.value.charCodeAt(i) <= 122)) {
			alert("Invalid input, please try again.");
			me.select();
			me.focus();
			return false;
		}
	}
	me.value = me.value.toUpperCase();
	return true;
}
function validate_lowers_blur(e) {
	for (i=0; i<me.value.length; i++) {
		if (me.value.charAt(i) < 65 && me.value.charAt(i) > 90)
			{alert("Invalid input, please try again.");me.select();me.focus();return false;}
	}
	return true;	
}
function validate_date_blur(me, reformat, err_msg, operator1, date1, operator2, date2) {
	if (chkdate(me, reformat)) {
		if (me.value.length==0) {
			return true;
		} else {
			/*
			If the last 3 or 5 arguments are specified, then a further comparison on the date
			is checked based on the operator(s) and date(s) specified.
			
			The comparison is done as follows:
			
					if (me.value [operator] [date]) return true;
					else return false;
			
			Argument Explanations:
			operator - Type: String, example: any operator like of the set {"=", "<", "<=", ">", ">=", "<>"}
			date - Type: Date Object, example: new Date()
			err_msg - Type: String, example: "Start Date must be greater than or equal to today"
			*/
			if (err_msg == null		|| err_msg == 'undefined' ||
				operator1 == null	|| operator1 == 'undefined' ||
				date1 == null		|| date1 == 'undefined') {
				return true;
			} else {
				var d = new Date(me.value);
				
				// parse out only the date (leave the time out of the comparison)
				var d1 = new Date((date1.getMonth()+1) + "/" + date1.getDate() + "/" + date1.getFullYear());
				var d2 = null;
				if (date2 != null) {
					d2 = new Date((date2.getMonth()+1) + "/" + date2.getDate() + "/" + date2.getFullYear());
				}
				
				var diff = d.getTime() - d1.getTime();
				var days1 = Math.floor(diff / (1000 * 60 * 60 * 24));
				
				var days2 = null;
				if (d2 != null) {
					diff = d.getTime() - d2.getTime();
					days2 = Math.floor(diff / (1000 * 60 * 60 * 24));
				}
				
				//alert(d1 + "\n" + d2);
				
				var isValid = false;
				if (days2 != null) {
					//alert(String(days1) + operator1 + "0 && " + String(days2) + operator2 + "0");
					if (eval(String(days1) + operator1 + "0 && " + String(days2) + operator2 + "0")) isValid = true;
				} else {
					//alert(String(days1) + operator1 + "0");
					if (eval(String(days1) + operator1 + "0")) isValid = true;
				}
				
				if (!isValid) {
					alert(err_msg);
					me.select();
					me.focus();
					return false;				
				} else {
					return true;
				}
			}
		}
	} else {
		alert("Invalid Date, please try again.");
		me.select();
		me.focus();
		return false;
	}
}
function validate_date_keypress(e) {
	key = (e.which) ? e.which : e.keyCode;
    if(key>44&&key<58) return true;
	return false;		
}
function chkdate(objName, reformat) {
	var strDatestyle = "US"; //United States date style
	//var strDatestyle = "EU";  //European date style
	var strDate;
	var strDateArray;
	var strDay;
	var strMonth;
	var strYear;
	var intday;
	var intMonth;
	var intYear;
	var booFound = false;
	var datefield = objName;
	var strSeparatorArray = new Array("-"," ","/",".");
	var intElementNr;
	var err = 0;
	var strMonthArray = new Array(12);
	strMonthArray[0] = "Jan";
	strMonthArray[1] = "Feb";
	strMonthArray[2] = "Mar";
	strMonthArray[3] = "Apr";
	strMonthArray[4] = "May";
	strMonthArray[5] = "Jun";
	strMonthArray[6] = "Jul";
	strMonthArray[7] = "Aug";
	strMonthArray[8] = "Sep";
	strMonthArray[9] = "Oct";
	strMonthArray[10] = "Nov";
	strMonthArray[11] = "Dec";
	strDate = datefield.value;
	if (strDate.length < 1) {
		return true;
	}
	for (intElementNr = 0; intElementNr < strSeparatorArray.length; intElementNr++) {
		if (strDate.indexOf(strSeparatorArray[intElementNr]) != -1) {
			strDateArray = strDate.split(strSeparatorArray[intElementNr]);
			if (strDateArray.length != 3) {
				err = 1;
				return false;
			} else {				
				strDay = strDateArray[0];
				strMonth = strDateArray[1];
				strYear = strDateArray[2];
			}
			booFound = true;
		}
	}
	if (booFound == false) {
		if (strDate.length>5) {
			strDay = strDate.substr(0, 2);
			strMonth = strDate.substr(2, 2);
			strYear = strDate.substr(4);
		} else {
			err = 11;
			return false;
		}
	}
	if (strYear.length == 2) {
		strYear = '20' + strYear;
	} else if (strYear.length == 1 || strYear.length == 3 || strYear.length > 4) {
		err = 12;
		return false;
	}
	
	// US style
	if (strDatestyle == "US") {
		strTemp = strDay;
		strDay = strMonth;
		strMonth = strTemp;
	}
	intday = parseInt(strDay, 10);
	if (isNaN(intday)) {
		err = 2;
		return false;
	}
	intMonth = parseInt(strMonth, 10);
	if (isNaN(intMonth)) {
		for (i = 0;i<12;i++) {
			if (strMonth.toUpperCase() == strMonthArray[i].toUpperCase()) {
				intMonth = i+1;
				strMonth = strMonthArray[i];
				i = 12;
			}
		}
		if (isNaN(intMonth)) {
			err = 3;
			return false;
		}
	}
	intYear = parseInt(strYear, 10);
	if (isNaN(intYear)) {
		err = 4;
		return false;
	}
	if (intMonth>12 || intMonth<1) {
		err = 5;
		return false;
	}
	if ((intMonth == 1 || intMonth == 3 || intMonth == 5 || intMonth == 7 || intMonth == 8 || intMonth == 10 || intMonth == 12) && (intday > 31 || intday < 1)) {
		err = 6;
		return false;
	}
	if ((intMonth == 4 || intMonth == 6 || intMonth == 9 || intMonth == 11) && (intday > 30 || intday < 1)) {
		err = 7;
		return false;
	}
	if (intMonth == 2) {
		if (intday < 1) {
			err = 8;
			return false;
		}
		if (LeapYear(intYear) == true) {
			if (intday > 29) {
				err = 9;
				return false;
			}
		} else {
			if (intday > 28) {
				err = 10;
				return false;
			}
		}
	}
	if (reformat == true) {
		if (strDatestyle == "US") {
			// mm/dd/yyyy
			datefield.value = PadNumber(intMonth) + "/" + PadNumber(intday) + "/" + PadNumber(strYear);
			// month day year
			//datefield.value = strMonthArray[intMonth-1] + " " + intday + " " + strYear;
		} else if (strDatestyle == "EU") {
			// dd/mm/yyyy
			datefield.value = PadNumber(intMonth) + "/" + PadNumber(intday) + "/" + PadNumber(strYear);
			// day month year
			datefield.value = intday + " " + strMonthArray[intMonth-1] + " " + PadNumber(strYear);
		}
	}
	return true;
}
function LeapYear(intYear) {
	if (intYear % 100 == 0) {
		if (intYear % 400 == 0) { return true; }
	} else {
		if ((intYear % 4) == 0) { return true; }
	}
	return false;
}
function PadNumber(intNum) {
	if (intNum < 10) return "0" + String(intNum);
	else return String(intNum);
}
function textarea_limit_text(me, max_chars) {
	if (me.value.length>=max_chars) {
		me.value=me.value.substr(0,max_chars);
		return false;
	}
}

function validate_url_blur(me) {
	if (me.value.length == 0) return true;
	if (!CheckURL(me.value)) {alert("Invalid URL, please try again.");me.select();me.focus();return false;}
	return true;
}
function validate_email_blur(me) {
	if (me.value.length == 0) return true;
	if (!CheckEmail(me.value)) {alert("Invalid email, please try again.");me.select();me.focus();return false;}
	return true;
}

function CheckEmail(sEmail) {
	var at="@";
	var dot=".";
	var lat=sEmail.indexOf(at);
	var lstr=sEmail.length;
	var ldot=sEmail.indexOf(dot);
	if (sEmail.indexOf(at)==-1) return false;
	if (sEmail.indexOf(at)==-1 || sEmail.indexOf(at)==0 || sEmail.indexOf(at)==lstr) return false;
	if (sEmail.indexOf(dot)==-1 || sEmail.indexOf(dot)==0 || sEmail.indexOf(dot)==lstr) return false;
	if (sEmail.indexOf(at,(lat+1))!=-1) return false;
	if (sEmail.substring(lat-1,lat)==dot || sEmail.substring(lat+1,lat+2)==dot) return false;
	if (sEmail.indexOf(dot,(lat+2))==-1) return false;		
	if (sEmail.indexOf(" ")!=-1) return false;
 	return true;
}
function CheckURL(sURL) {
	//alert(sURL);
	//if (sURL == '') return true;
	//var oRegExp = /[^:]+:\/\/[^:\/]+(:[0-9]+)?\/?.*/;
	//if (!oRegExp.test(sURL)) return false;

	/*re = /^(file|http):\/\/\S+\.(com|net|org|edu|info|biz|ws|us|tv|cc)$/i
	if (re.test(sURL)) return true
	else return false*/
	return true;
}

function Trim(s) {
	// remove leading spaces and carriage returns
	while ((s.substring(0,1) == ' ') || (s.substring(0,1) == '\n') || (s.substring(0,1) == '\r')) {
		s = s.substring(1,s.length);
	}
	// remove trailing spaces and carriage returns
	while ((s.substring(s.length-1,s.length) == ' ') || (s.substring(s.length-1,s.length) == '\n') || (s.substring(s.length-1,s.length) == '\r')) {
		s = s.substring(0,s.length-1);
	}
	return s;
}

function DateCompare(dtStartDate, dtEndDate)
{
	if (dtStartDate.length > 0) 
	{
		var startDate = new Date(dtStartDate);
		var endDate = new Date(dtEndDate);
		var diff = startDate.getTime() - endDate.getTime();
		var days = Math.floor(diff / (1000 * 60 * 60 * 24));
		
		// Check the number of days between the date range
		if (days > 0) 
		{
			return false;
		} // if (days > 0) 
		else
		{
			return true;
		}
	} // if (dtStartDate.length > 0)
}
