/*
*******************************************************************************
*  Page Name:		common.js
*  Author:			Bryan Fritchie
*  Creation Date:	06/30/2003
*					
*  Description:		Commonly used validation scripts
*					
*  Modified By:		
*  Modified Date:	
*  Reason:			
*					
'*******************************************************************************
*/
var ExpUsername		= /^[a-zA-Z][a-zA-Z_0-9]{2,11}$/i
var ExpPassword		= /^[a-zA-Z][a-zA-Z0-9]{3,14}$/i
var ExpSSN			= /^[0-9]{3}[(\-)|(\\)]?[0-9]{2}[(\-)|(\\)]?[0-9]{4}$/i
var ExpPin			= /^[0-9]{4}$/i
var ExpEmail		= /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/i
var ExpSMS			= /^[a-zA-Z_0-9\.\-]*@[a-zA-Z_0-9\.\-]+\.[a-z]{2,3}$/i
var ExpDate			= /^(0?[1-9]|1[0-2])\/(0?[1-9]|[1-2][0-9]|3[0-1])\/[1,2][0-9]{3}$/i
var ExpPhone		= /^[\(]?[1-9][0-9]{2}([\)]\s?|-|\s)[0-9]{3}-?[0-9]{4}$/i
var ExpZip			= /^([0-9]{5}$|[0-9]{5}-[0-9]{4})$/i
var ExpUrl			= /^(https?:\/\/[a-zA-Z_0-9\.\-]*\.[a-zA-Z]{2,4})$/i
var ExpUrlWithPath	= /^(https?:\/\/[a-zA-z_0-9\.\-]*\.[a-zA-Z]{2,4}([\/a-zA-Z_0-9\,\-]*\.[a-zA-Z]{2,4})?)$/i
var ExpCurrency		= /^(\$)?[0-9,]*(\.[0-9]{2}){0,1}$/
var ExpCurrency2	= /^(\$)?([0-9]*|(([0-9]{1,3}(\,)?)*[0-9]{3}))(\.[0-9]{2}){0,1}$/
var ExpNumeric		= /^[0-9]+$/

/* CAUTION: if you are going to use ExpRealNum, this will validate that it's a real number,
			however it will also allow blanks.  We will address this when time permits.
			Until then, use the isWhitespace() function, or trim and validate the length to make sure
			that something was entered.
*/
var ExpRealNum		= /^[0-9]*(\.[0-9]{1,2}){0,1}$/
var space			= /\s/
var quote			= /"/
var startspaces		= /^\s+/

var userBrowser = '';
var openXPos = 50;
var openYPos = 50;
var message			= "Unknown error.";

String.prototype.right = extract_right;
String.prototype.left = extract_left;
String.prototype.trim = trim_spaces;



//===================================================================================
// OnStartUp type of functions
//===================================================================================
function openPopUpWindow(linkURL, openWidth, openHeight, XPos, YPos) {
	var newWind=window.open(linkURL,'display','resizable,border=thin,scrollbars=yes,width='+openWidth+',height='+openHeight+',screenX='+XPos+',screenY='+YPos);
	if (newWind.opener == null) {
		newWind.opener = window;
	}
	newWind.focus();
	return false;
}

function Paging(x_intCurrentPage) {
	if(document.forms[0].hdnCurrentPage) {
		document.forms[0].hdnCurrentPage.value = x_intCurrentPage;
	}
	document.forms[0].submit();
}

// Preload "swap" images for fast veiwing
// The len is the length of the comma delimited string (strImages) with a trailing comma
// The path is the path after '../images/'
function preload(strImages, len, path) {
	var imgarr = new Array();
	var EndPos,BegPos;
	BegPos = 0;
	for (var i = 0; i < len; i++) {
		imgarr[i] = new Image();
		EndPos = strImages.indexOf(",",BegPos);
		imgarr[i].src = '../../images/' + path + strImages.substring(BegPos,EndPos);
		BegPos = EndPos + 1;
		//alert(imgarr[i].src);
	}
}

function resizeWindow(x_intXPos, x_intYPos, x_intOpenWidth, x_intOpenHeight) {
	var strBrowser = navigator.appName;
	var intBrowserVersion = parseInt(navigator.appVersion);

	if (strBrowser == "Netscape" && intBrowserVersion >= 4) {
		window.resizeTo(x_intOpenWidth, x_intOpenHeight);
	} else {
		if (strBrowser == "Microsoft Internet Explorer") {
			window.resizeTo(x_intOpenWidth, x_intOpenHeight);
		} else {
			window.resizeTo(x_intOpenWidth, x_intOpenHeight);
		}
	}

/*
	//The height and width properties of the table cannot 
	//be retrieved by Netscape, so we ignore Netscape.
	IE = document.all;
	if (IE) {
		width = IE.MainTable.offsetWidth + 30;
		height = IE.MainTable.offsetHeight + 160;
		if (height >= 400) {
			height = 400;
		}
		window.resizeTo(width, height);
	}
*/
}



//===================================================================================
// Data Checking/Manipulation
//===================================================================================
function isValid(pattern, str) {
	return pattern.test(str);
}

function stripChars(pattern, str) {
	return str.replace(pattern, "");
}

function replaceChars(pattern, str, replace) {
	return str.replace(pattern, replace);
}

function isEmpty(s) {   
	return ((s == null) || (s.length == 0));
}
					
function isWhitespace(s) {
	var i;
	var whitespace = " \t\n\r";
	// Is s empty?
	if (isEmpty(s)) return true;
	// Search through string's characters one by one
	// until we find a non-whitespace character.
	// When we do, return false; if we don't, return true.
	for (i = 0; i < s.length; i++) {
		// Check that current character isn't whitespace.
		var c = s.charAt(i);
		if (whitespace.indexOf(c) == -1) return false;
	}
	// All characters are whitespace.
	return true;
}

function isDigit(c) {   
	return ((c >= "0") && (c <= "9"));
}

function trim_spaces(from_where) {
    // Store the string in a temporary variable    
    var temp_string = this;
	
    // If no argument, then trim from both sides
    if (arguments.length == 0) {
        from_where = "BOTH";
    }
    
    // Trim spaces from the left
    if (from_where.toUpperCase() == "LEFT" || from_where == "BOTH") {
        while (temp_string.left(1) == " ") {
            temp_string = temp_string.substring(1);
        }
    }
    
    // Trim spaces from the right
    if (from_where.toUpperCase() == "RIGHT" || from_where == "BOTH") {
        while (temp_string.right(1) == " ") {
            temp_string = temp_string.substring(0, temp_string.length - 1);
        }
    }
    return temp_string;
}

function extract_left(total_chars) {
    return this.substring(0, total_chars);
}

function extract_right(total_chars) {
    return this.substring(this.length - total_chars);
}

function isspaces(fld){
	for (var i = 0; i <= fld.length; i++ ){
		if (fld.substr != ' '){
			return false;
		}
	}
	return true;
}	



//===================================================================================
// Form Fields - Select Box
//===================================================================================
function ValidateSelectBox(x_objSelectBox) {
	if (x_objSelectBox[x_objSelectBox.selectedIndex].value == -1) {
		return false;
	}
	return true;
}

function GetSelectBoxValue(x_objSelectBox) {
	return x_objSelectBox[x_objSelectBox.selectedIndex].value;
}

// Counts how many items in a select box are selected
function GetSelectedItemsCount(x_objSelectedItems) {
	var intCounter = 0;
	var intSelectedCount = 0;

	for (intCounter = 0; intCounter < x_objSelectedItems.length; intCounter++) {
		if (x_objSelectedItems[intCounter].selected) {
			intSelectedCount = intSelectedCount + 1;
		}
	}
	return intSelectedCount;
}



//===================================================================================
// Form Fields - Radio Buttons
//===================================================================================
// 
function CountRadio(x_objRadioButton) {
	var intCounter = 0;
	var intRadioCount = 0;
	if (x_objRadioButton) {
		// Check to see if we have an array, and if so, loop through it
		if (x_objRadioButton.length != undefined) {
			intRadioCount = x_objRadioButton.length;
		// If we have a single item, then we can directly change the status
		} else if (x_objRadioButton.value != undefined) {
			intRadioCount = 1;
		}
	}
	return intRadioCount;
}

// Returns the value of the selected item of a Radio Object
function GetRadioValue(x_objRadioButton) {
	var intCounter = 0;
	var intReturn = -1;
	if (x_objRadioButton) {
		// Check to see if we have an array, and if so, loop through it
		if (x_objRadioButton.length != undefined) {
			for (intCounter = 0; intCounter < x_objRadioButton.length; intCounter++) {
				if (x_objRadioButton[intCounter].checked) {
					intReturn =  x_objRadioButton[intCounter].value;
				}
			}
		// If we have a single item, then we can directly grab the value
		} else if (x_objRadioButton.value != undefined) {
			if (x_objRadioButton.checked) {
				intReturn =  x_objRadioButton.value;
			}
		}
	}
	return intReturn;
}

// Unselect all radio buttons in a group
function TurnOffRadio(x_objRadioButton) {
	var intCounter = 0;
	if (x_objRadioButton) {
		// Check to see if we have an array, and if so, loop through it
		if (x_objRadioButton.length != undefined) {
			for (intCounter = 0; intCounter < x_objRadioButton.length; intCounter++) {
				x_objRadioButton[intCounter].checked = false;
			}
		// If we have a single item, then we can directly change the status
		} else if (x_objRadioButton.value != undefined) {
			x_objRadioButton.checked = false;
		}
	}
}

// Unselect all radio buttons in a group
function TurnOffRadio(x_objRadioButton) {
	var intCounter = 0;
	if (x_objRadioButton) {
		// Check to see if we have an array, and if so, loop through it
		if (x_objRadioButton.length != undefined) {
			for (intCounter = 0; intCounter < x_objRadioButton.length; intCounter++) {
				x_objRadioButton[intCounter].checked = false;
			}
		// If we have a single item, then we can directly change the status
		} else if (x_objRadioButton.value != undefined) {
			x_objRadioButton.checked = false;
		}
	}
}



//===================================================================================
// Form Fields - Check Boxes
//===================================================================================
// Counts how many boxes are checked
function GetCheckedBoxesCount(x_objCheckBoxes) {
	var intCounter = 0;
	var intCheckedCount = 0;
	
	if (x_objCheckBoxes) {
		for (intCounter = 0; intCounter < x_objCheckBoxes.length; intCounter++) {
			if (x_objCheckBoxes[intCounter].checked) {
				intCheckedCount = intCheckedCount + 1;
			}
		}
	}
	return intCheckedCount;
}

// Turns off or on all check boxes
function SelectAllCheckBoxes(x_objCheckBoxes, x_blnChecked) {
	if (x_objCheckBoxes) {
		var intCounter = 0;
		for (intCounter = 0; intCounter < x_objCheckBoxes.length; intCounter++) {
			x_objCheckBoxes[intCounter].checked = x_blnChecked;
		}
	}
}



//===================================================================================
// Date manipulation and checking
//===================================================================================
// Added by Bryan Fritchie - 04/11/2002
function isValidDate(x_dteDate, x_blnShowError) {
	var dteMonth = GetInputMonth(x_dteDate);
	var dteDay = GetInputDay(x_dteDate);
	var dteYear = GetInputYear(x_dteDate);

	// test to make sure the date is formatted correctly
	if(!isValid(ExpDate, x_dteDate)) {
		if (x_blnShowError) {
			alert('The date you entered is not a valid format, use mm/dd/yyyy.');
		}
		return false;
	}

	// test for leap year - IsLeapYear has its own alert boxes
	if(!IsLeapYear(dteMonth, dteDay, dteYear)) {
		return false;
	}
	
	// only 30 days in April, June, September, and November - IsThirtyDay has its own alert boxes
	if(!IsThirtyDay(dteMonth, dteDay)) {
		return false;
	}
	
	return true;
}

function GetInputMonth(x_strDate) {
	var strInputMonth = new String(x_strDate);
	// return only the first part of the date (MM) of a date that's formatted MM/DD/YYYY
	return strInputMonth.substr(0, strInputMonth.indexOf("/",0));
}

function GetInputDay(x_strDate) {
	var strInputDay = new String(x_strDate);
	var intStartPosition = (strInputDay.indexOf("/",0) + 1);
			
	// return only the day (DD) of a date that's formatted MM/DD/YYYY
	return strInputDay.substr(intStartPosition, (strInputDay.indexOf("/",intStartPosition) - intStartPosition));
}

function GetInputYear(x_strDate) {
	var strInputYear = new String(x_strDate);
	var intStartPosition = (strInputYear.lastIndexOf("/",strInputYear.length) + 1);
			
	// return only the last part of the date (YYYY) of a date that's formatted MM/DD/YYYY
	return strInputYear.substr(intStartPosition, (strInputYear.length - 1));
}

function IsLeapYear(x_intMonth, x_intDay, x_intYear) {
	//test for leap year for the starting date
	if(x_intYear % 4 == 0) {
		//Is it a century.
		if(x_intYear % 100 == 0) {
			//If a century, must be evenly divisible by 400.
			if(x_intYear % 400 == 0 ) {
				//it's a leap year
				if((x_intMonth == 2) && (x_intDay > 29)) {
					alert("There are only 29 days in February.");
					return false;
				}				
			} else {
				//it's not a leap year
				if((x_intMonth == 2) && (x_intDay > 28)) {
					alert("There are only 28 days in February.");
					return false;
				}
			}
		} else {
			//it's a leap year
			if((x_intMonth == 2) && (x_intDay > 29)) {
				alert("There are only 29 days in February.");
				return false;
			}
		}
	} else {
		//it's not a leap year, test for the number of days in february
		if((x_intMonth == 2) && (x_intDay > 28)) {
			alert("There are only 28 days in February.");
			return false;
		}
	}
	return true;
}

function IsThirtyDay(x_intMonth, x_intDay) {
	//there are only 30 days in April, June, September, and November
	if(((x_intMonth == 4) || (x_intMonth == 6) || (x_intMonth == 9) || (x_intMonth == 11)) && (x_intDay > 30)) {
		alert("There are only 30 days in Month you entered.");
		return false;
	}
	return true;
}

function MakeDate(x_dteDate) {
	var dteDate = new Date(parseInt(GetInputYear(x_dteDate)), parseInt(GetInputMonth(x_dteDate)-1), parseInt(GetInputDay(x_dteDate)), 0, 0, 0);
	// return the new date object
	return dteDate;
}

function CheckStartEndDate(x_dteStart, x_dteEnd) {
	// Test that the Start Date hasen't already past the End Date
	if (x_dteStart >= x_dteEnd) {
		return true;
	}
	return false;
}


















//===================================================================================
// Generic functions
//===================================================================================
function validateEntries(x_objItem, x_intMax, x_intMin, x_strType, x_strLabelName) {
	//variable declarations
	if (x_strType != "selectbox") {
		var txtWorking = x_objItem.value;
	}
			
	//regular expressions
	var ticks = /[']{1,}/g
	var endticks = /([']{1,})$/
	var escaped = /%[A-Fa-f0-9]{2}/g
	var nonnumber = /[^0-9]/g
	var phonenumber = /([0-9]{3})-?([0-9]{4})/
	var phonenumberlong = /([0-9]{3})-?([0-9]{3})-?([0-9]{4})/
	var dash = /-/g
	var htmltags = /<[^>]*>/gi
	var leadspace = /^[ \n\r\t]+/
	var undefined;
	
	if (x_strType == "search") {								//for search strings, double the ticks, remove html tags and escaped ascii sequences, and trim the string to x_intMax characters
		txtWorking.toString();
		txtWorking = txtWorking.replace(escaped, "");
		txtWorking = txtWorking.replace(htmltags, "");
		//txtWorking = txtWorking.replace(ticks, "''");
		txtWorking = txtWorking.substr(0,x_intMax);
		x_objItem.value = txtWorking;
		return true;
	}
	
	else if (x_strType == "selectbox") {								//for select boxes
		// 10/11/2002 - Bryan Fritchie
		// Changed the code from "x_objItem.selectedIndex" to "x_objItem[x_objItem.selectedIndex].value".
		// This is needed for all browsers, and for some added functionality.
		if(x_objItem[x_objItem.selectedIndex].value <= 0) {
			message = "You did not select a value for " + x_strLabelName + ".  Please make a selection.";
			x_objItem.focus();
			return false;
		}
		else {
			return true;
		}
	}
	
	else if (x_strType == "radio") {								//for select boxes
		if (x_objItem.length == undefined) {
			if (!x_objItem.checked) {
				message = "Please select " + x_strLabelName + " by clicking the radio button next to it.";
				return false;
			}
			else {
				return true;
			}
		}
		else {
			for (var i = 0; i < x_objItem.length; i++) {
				if (x_objItem[i].checked) {
					return true;
				}
			}
		}
		message = "Please select " + x_strLabelName + " by clicking the radio button next to it.";
		return false;
	}
	
	else if (x_strType == "number") {								//for generic numbers, just remove non-number characters
		txtWorking.toString();
		txtWorking = txtWorking.replace(nonnumber, "");
		x_objItem.value = txtWorking;
		if (txtWorking.length < x_intMin) {					//make sure we have at least x_intMin characters
			message = "The " + x_strLabelName + " you typed was too short, should have " + x_intMin + " characters.";
			x_objItem.focus();
			return false;
		}
		else if (txtWorking.length > x_intMax) {					//make sure we have no more than x_intMax characters
			message = "The " + x_strLabelName + " you typed was too long, should have " + x_intMax + " characters.";
			x_objItem.focus();
			return false;
		}
		else {
			x_objItem.value = txtWorking;
			return true;
		}
	}
	
	else if (x_strType == "numbernotreq") {								//for generic numbers, just remove non-number characters
		txtWorking.toString();
		txtWorking = txtWorking.replace(nonnumber, "");
		x_objItem.value = txtWorking;
		if (txtWorking.length > 0) {					//if we have some numbers...
			if (txtWorking.length < x_intMin) {					//make sure we have at least x_intMin characters
				message = "The " + x_strLabelName + " you typed was too short, should have " + x_intMin + " (or zero) characters.";
				x_objItem.focus();
				return false;
			}
			else if (txtWorking.length > x_intMax) {					//make sure we have no more than x_intMax characters
				message = "The " + x_strLabelName + " you typed was too long, should have " + x_intMax + " characters.";
				x_objItem.focus();
				return false;
			}
			else {
				x_objItem.value = txtWorking;
				return true;
			}
		}
		else {
			x_objItem.value = txtWorking;
			return true;
		}
	}
			
	else if (x_strType == "phone") {							//for phone numbers, remove non-number characters and the dash for the length check
		txtWorking.toString();
		txtWorking = txtWorking.replace(nonnumber, "");
		txtWorking = txtWorking.replace(dash, "");
		x_objItem.value = txtWorking;
		if (txtWorking.length < x_intMin) {					//make sure we have at least 7 characters (or whatever we set x_intMin to)
			message = "The " + x_strLabelName + " you typed was too short, should have " + x_intMin + " characters (not including the dash '-' character).";
			x_objItem.focus();
			return false;
		}
		else if (txtWorking.length > x_intMax) {					//make sure we have no more than 7 characters (or whatever we set x_intMin to)
			message = "The " + x_strLabelName + " you typed was too long, should have " + x_intMax + " characters (not including the dash '-' character).";
			x_objItem.focus();
			return false;
		}
		else {											//if the length checks out, put the dash back in in the right spot
			txtWorking = txtWorking.replace(phonenumber, "$1-$2");
			x_objItem.value = txtWorking;
			return true;
		}
	}
	
		else if (x_strType == "phonelong") {							//for phone numbers, remove non-number characters and the dash for the length check
		txtWorking.toString();
		txtWorking = txtWorking.replace(nonnumber, "");
		txtWorking = txtWorking.replace(dash, "");
		x_objItem.value = txtWorking;
		if (txtWorking.length < x_intMin) {					//make sure we have at least 10 characters (or whatever we set x_intMin to)
			message = "The " + x_strLabelName + " you typed was too short, should have " + x_intMin + " characters (not including the dash '-' character).";
			x_objItem.focus();
			return false;
		}
		else if (txtWorking.length > x_intMax) {					//make sure we have no more than 10 characters (or whatever we set x_intMin to)
			message = "The " + x_strLabelName + " you typed was too long, should have " + x_intMax + " characters (not including the dash '-' character).";
			x_objItem.focus();
			return false;
		}
		else {											//if the length checks out, put the dash back in in the right spot
			txtWorking = txtWorking.replace(phonenumberlong, "$1-$2-$3");
			x_objItem.value = txtWorking;
			return true;
		}
	}
			
	else if (x_strType == "phonenotreq") {					//for non-required phone numbers, remove non-number characters and the dash, and see if the length is zero
		txtWorking.toString();
		txtWorking = txtWorking.replace(nonnumber, "");
		txtWorking = txtWorking.replace(dash, "");
		x_objItem.value = txtWorking;
		if (txtWorking.length > 0) {					//if we have some numbers...
			if (txtWorking.length < x_intMin) {				//make sure we have at least 7 characters (or whatever we set x_intMin to)
				message = "The " + x_strLabelName + " you typed was too short, should have " + x_intMin + " (or zero) characters (not including the dash '-' character).";
				x_objItem.focus();
				return false;
			}
			else if (txtWorking.length > x_intMax) {				//make sure we have no more than 7 characters (or whatever we set x_intMin to)
				message = "The " + x_strLabelName + " you typed was too long, should have " + x_intMax + " characters (not including the dash '-' character).";
				x_objItem.focus();
				return false;
			}
			else {											//if the length checks out, put the dash back in in the right spot
				txtWorking = txtWorking.replace(phonenumber, "$1-$2");
				x_objItem.value = txtWorking;
				return true;
			}
		}
		else {
			x_objItem.value = txtWorking;
			return true;
		}
	}
			
	else if (x_strType == "text") {								//for text, strip html tags, and strip ascii control character sequences
		txtWorking.toString();
		txtWorking = txtWorking.replace(escaped, "");
		txtWorking = txtWorking.replace(htmltags, "");
		x_objItem.value = txtWorking;
		if (txtWorking.length < x_intMin) {						//make sure we have no less than x_intMin characters
			message = "The " + x_strLabelName + " you typed was too short, should have " + x_intMin + " characters x_intMinimum.";
			x_objItem.focus();
			return false;
		}
		else if (txtWorking.length > x_intMax) { 				//make sure we have no more than x_intMax characters
			message = "The " + x_strLabelName + " you typed was too long, should have " + x_intMax + " characters x_intMaximum.";
			x_objItem.focus();
			return false;
		}
		else {
			x_objItem.value = txtWorking;
			return true;
		}
	}
	else {
		message = "Could not find a rule to validate an input box of type '" + x_strType + "'.";
		return false;
	}
}

