var QuantityError = "Please enter a valid quantity.";
var PriceError = "Please enter a valid price.";
var DateError = "Please enter the current date or greater.";

var debug = false;

var setFocus = false;

/// This checks the string passed in as a domain name and requires that it
///   either end in one of the '.com' style endings or ends with '.cc' where the
///   'cc' represents two alphabetic characters of a country code domain.
///   I don't actually check for a valid country code, only for the proper form.
/// This function needs JS1.2 and does not work in Opera3.5.
function  isStandardDomain( domainIn )  {

	/// The value to return, start out assuming invalid domain.
	var  isStandardReturn = false;

	/// Holds the top level domain
	var domain = domainIn.split(".");
	var tld = domain[domain.length-1];


	/// Holds the last 3 characters of domain name.
	var  last3chars  =  domainIn.substring( domainIn.length-3, domainIn.length );

	/// Uppercase it for comparison purposes.
	tld = tld.toUpperCase();


	/// A regular expression pattern to match country code domains.
	///  In otherwords a Dot character followed by two alphabetic characters.
	/// NOTE:  This line doesn't work at all in Opera3.5 and prevents the
	///  entire script from running!!!  BUMMER!!!
	///  It also seems to not work in Opera4.02 but only prevents
	///  the 2 letter codes from working but doesn't crash the script.
	var  countryCodePattern = /\.[a-zA-Z][a-zA-Z]/;


	if      ( tld == "COM" ) isStandardReturn = true;
	else if ( tld == "EDU" ) isStandardReturn = true;
	else if ( tld == "GOV" ) isStandardReturn = true;
	else if ( tld == "NET" ) isStandardReturn = true;
	else if ( tld == "MIL" ) isStandardReturn = true;
	else if ( tld == "ORG" ) isStandardReturn = true;
	else if ( tld == "AERO" ) isStandardReturn = true;
	else if ( tld == "BIZ" ) isStandardReturn = true;
	else if ( tld == "COOP" ) isStandardReturn = true;
	else if ( tld == "INFO" ) isStandardReturn = true;
	else if ( tld == "MUSEUM" ) isStandardReturn = true;
	else if ( tld == "NAME" ) isStandardReturn = true;
	else if ( tld == "PRO" ) isStandardReturn = true;
	else if ( tld == "INT" ) isStandardReturn = true;

	else if ( last3chars.search( countryCodePattern )   !=  -1 )
		isStandardReturn = true;

	return  isStandardReturn;

} // Ends isStandardDomain( domainIn ).


/// Checks basic validity of an email address that's passed in.
///  Requires proper configuration of the '@' character lack of Spaces
///  and calls function "isStandardDomain()" to check on the form of the
///  domain name part.
/// Used an alert box to display it's answer.
/// This function needs JS1.2 [because isStandardDomain() does] and does not work in Opera3.5.
function  isValidEmail(emailIn)  {

	/// Number of '@' chars present in input string.
	var  numAtChars;

	/// The part of input address before the '@' character.
	var  userNameIn;

	/// The part of input address after the '@' character.
	var  domainNameIn;

	/// Holds the fields of the entered address, delimitted by '@' chars.
	var  addressFields = new Array();

	// Concatenate all alert output to here.
	var  alertString = "";


	/// Divide the input email address into fields.
	///  Note that the array "addressFields" will have one more element
	///  than the number of '@' signs in the input string.
	/// IE4 handles this OK with '@' as last character but NS4,4.5 and Opera 3.5 don't.
	addressFields = emailIn.split( '@' );

	numAtChars = addressFields.length - 1;

	if ( emailIn == "" ) {
		return true;
	} else if ( numAtChars  ==  0 ) {
		return true;
	} else if ( numAtChars  >  1 ) {
		return true;
	} else if ( addressFields[0] == "" ) {
		return true;
	} else if ( addressFields[1] == "" ) {
		return true;
	} else
		{
		userNameIn   = addressFields[0];
		domainNameIn = addressFields[1];

		if ( userNameIn.indexOf( " " ) != -1 )
			return true;
		else if ( domainNameIn.indexOf( " " ) != -1 )
			return true;
		else if ( isStandardDomain( domainNameIn ) == false )
			return true;
		else
			return false;
		} // Ends else from outer string of if-then-else's.
} // Ends isValidEmail().

/// Checks basic validity of an time (hh:mm) that's passed in.
/// Uses an alert box to display its answer.
function  isValidTime(timeIn)  {

	/// Number of ':' chars present in input string.
	var  numColonChars;
	/// The part of input time before the ':' character.
	var  hourIn;
	/// The part of input time after the ':' character.
	var  minuteIn;
	/// Holds the fields of the entered time, delimited by ':' chars.
	var  timeFields = new Array();
	// Concatenate all alert output to here.
	var  alertString = "";

	/// Divide the input time into fields.
	///  Note that the array "timeFields" will have one more element
	///  than the number of ':' signs in the input string.
	/// IE4 handles this OK with ':' as last character but NS4,4.5 and Opera 3.5 don't.
	timeFields = timeIn.split( ':' );

	numColonChars = timeFields.length - 1;

	if ( timeIn == "" ) {
		return true;
	} else if ( numColonChars  ==  0 ) {
		return true;
	} else if ( numColonChars  >  1 ) {
		return true;
	} else if ( timeFields[0] == "" ) {
		return true;
	} else if ( timeFields[1] == "" ) {
		return true;
	} else {
		hourIn   = timeFields[0];
		minuteIn = timeFields[1];

		if ( !isNumber(hourIn)) {
			return true;
	    }
	    else if ( hourIn > 12 ) {
	        return true;
	    }
		else if ( !isNumber(minuteIn) ) {
			return true;
		}
		else if ( minuteIn > 59 ) {
	        return true;
	    }
		else {
			return false;
		}
	} // Ends else from outer string of if-then-else's.
} // Ends isValidTime().


function endOfMonth(month, year) {
	var day;
    if (month==4 || month==6 || month==9 || month==11) {
    	day = 30;
	}
    if (month==2) {
    	if (year%4 == 0) { // if a leap year, divisible by 4
        	day = 29;
		}
        if (year%4 != 0) { // not a leap year
        	day = 28;
       	}
	}
  	if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
	    day = 31;
	}
   	return day;
}

function updateDayOptions(month1, day1,year1) {
        var tempOption;
        var oldLength = day1.length;
        var newLength = endOfMonth(month1.selectedIndex+1, year1.options[year1.selectedIndex].value);
        var i;
        var k;
        var flag=35;
        if (oldLength == newLength)
                return;
        if (day1.options[day1.selectedIndex].value > newLength){
          flag=newLength-1;
        }
        else{
          flag=(day1.options[day1.selectedIndex].value)-1;
        }
        for (i = 28; i < newLength; i++)
        {
                tempOption = new Option((i+1) + "", (i+1));
                day1.options[i] = tempOption;
        }
        for (k = oldLength; k >= newLength; k--)
        {
                day1.options[k] = null;
        }
        if (flag !=35){
           day1.selectedIndex=flag;
        }
}


// determines if the string passed is a space, new line character or tab
function isBlank(s)
{
	for(var i=0; i < s.length; i++) {
		var c = s.charAt(i);
		if ((c != ' ') && (c != '\n') && (c != '\t')) {
			return false;
		}
	}
	return true;
}

// determines if the string passed contains a space, new line character or tab
function containsBlank(s)
{
	if (s.length > 0) {
		for(var i=0; i < s.length; i++) {
			var c = s.charAt(i);
			if ((c == ' ') || (c == '\n') || (c == '\t')) {
				return true;
			}
		}
	}
	return false;
}

// checks to see if the commas in the number passed are formatted properly
function validateComma(itemValue) {

	itemValue = new String(itemValue);
	if (itemValue.search(/\,/) != -1) {
		if (itemValue.search(/\./) != -1) {
			itemValue = itemValue.substring(0,itemValue.lastIndexOf("."));  	//remove the decimal portion
		}
		items = itemValue.split(",");
		if ((items[0].length >= 1) && (items[0].length <= 3)) {  // check for the first comma block having 1-3 characters
			for (var i = 1; i < items.length; i++) {
				if (items[i].length != 3) {			// check for all remaining comma blocks having 3 characters
					return false;
				}
			}
			return true;
		} else {
			return false;
		}
	} else {
		return true;
	}
}

// Determines if the value passed in is a number.
// This function is necessary because the isNaN considers +50 or -50 valid numbers,
// and the plus or minus signs cause an error when they get to the java side.
function isNumber(num) {
	if (num.length > 0) {
		for (var i = 0; i < num.length; i++) {
			if (isNaN(num.charAt(i)) && (num.charAt(i) != ".") && (num.charAt(i) != ",")) {
				return false;
			}
		}
		return validateComma(num);
	} else {
		return false;
	}
}

/*
isTextValid: determines if a value passed in meets the requirements specified in the switches.
note:  the conditions in the code are failure conditions.

switches:
	p - validate for a positive number
	v - validate for length <> 0
	m - validate for for Java integer range (-2147483647 to 2147483647)
	n - validate for a number
	d - validate for a decimal
	i - validate for no decimal
	t - validate for 1 or 2 digits after the decimal if there is a decimal
	f - validate for 1 to 3 digits after the decimal if there is a decimal
	z - validate for non zero
	e - validate for a valid e-mail
	u - validate for a valid url (validates for no @ symbol)
	s - validate for not a space, line break or tab
	b - validate for not containing a space, line break or tab
	c - validate for correct comma formatting
	h - validate for correct time formatting (hh:mm)
		note: using c means that it will strip all commas out of the string	if they are correctly formatted.
			(for validation only - contents of the textbox will remain unchanged)

switch examples:
	dollar values 		- tpvnzs
	positive integer 	- pviznms
	any valid input 	- vs

the order of the switches is irrelevant.

*/
function isTextValid(item,switches) {
	if (item.type != "hidden") {
		conditionArray = new Array();
		itemValue = new String(item.value);
		var count = 0;

        itemValue = trim(itemValue);

		if (switches.search(/c/) != -1) {
			if (validateComma(itemValue)) {
				itemValue = itemValue.replace(/\,/,"");
			} else {
				return itemMsg+"\n";
			}
		}
		if (switches.search(/t/) != -1) {
			if (itemValue.indexOf(".") != -1) {
				conditionArray[count] = "!((itemValue.length == (itemValue.indexOf(\".\")+2) || (itemValue.length == (itemValue.indexOf(\".\")+3))))";
				count++;
			}
		}
		if (switches.search(/f/) != -1) {
			if (itemValue.indexOf(".") != -1) {
				conditionArray[count] = "!((itemValue.length == (itemValue.indexOf(\".\")+2) || (itemValue.length == (itemValue.indexOf(\".\")+3)) || (itemValue.length == (itemValue.indexOf(\".\")+4))))";
				count++;
			}
		}
		if (switches.search(/p/) != -1) {
			conditionArray[count] = "(itemValue < 0)";
			count++;
		}
		if (switches.search(/z/) != -1) {
			conditionArray[count] = "(itemValue == 0)";
			count++;
		}
		if (switches.search(/v/) != -1) {
			conditionArray[count] = "(itemValue.length == 0)";
			count++;
		}
		if (switches.search(/n/) != -1) {
			conditionArray[count] = "(!isNumber(itemValue))";
			count++;
		}
		if (switches.search(/d/) != -1) {
			conditionArray[count] = "(itemValue.indexOf(\".\") == -1)";
			count++;
		}
		if (switches.search(/i/) != -1) {
			conditionArray[count] = "(itemValue.indexOf(\".\") != -1)";
			count++;
		}
		if (switches.search(/s/) != -1) {
			conditionArray[count] = "(isBlank(itemValue))";
			count++;
		}
		if (switches.search(/b/) != -1) {
			conditionArray[count] = "(containsBlank(itemValue))";
			count++;
		}
		if (switches.search(/e/) != -1) {
			conditionArray[count] = "(isValidEmail(itemValue))";
			count++;
		}
		if (switches.search(/h/) != -1) {
			conditionArray[count] = "(isValidTime(itemValue))";
			count++;
		}
		if (switches.search(/m/) != -1) {
			conditionArray[count] = "((itemValue < -2147483647) || (itemValue > 2147483647))";
			count++;
		}
		if (switches.search(/u/) != -1) {
			conditionArray[count] = "(itemValue.indexOf(\"@\") != -1)";
			count++;
		}
		var conditionString = "";
		for (var j = 0; j < conditionArray.length; j++) {
			if (j == 0) {
				conditionString += "(" + conditionArray[j];
			} else {
				conditionString += " || " + conditionArray[j];
			}
		}
		conditionString += ")";
		return !eval(conditionString);
	} else {
		return true
	}
}

function trim(item){
    var newItem = new String(item);
    if(newItem.length > 0){
        while(newItem.charAt(0) == ' '
                || newItem.charAt(0) == '\n'
                || newItem.charAt(0) == '\t'){
            if(newItem.length > 1){
                newItem = newItem.substring(1, newItem.length);
            } else {
                return newItem;
            }
        }

        while(newItem.charAt(newItem.length -1 ) == ' '
                || newItem.charAt(newItem.length -1 ) == '\n'
                || newItem.charAt(newItem.length -1 ) == '\t'){
            if(newItem.length > 1){
                newItem = newItem.substring(0, newItem.length - 1);
            } else {
                return newItem;
            }
        }
    }
    return newItem;
}

function validateText(item,switches,itemMsg) {
	var errorMsg = "";
	if (!isTextValid(item,switches)) {
		errorMsg += itemMsg + "\n"
		if (setFocus) {
			item.focus();
			setFocus = false;
		}
	}
	return errorMsg;
}


// validates to see if a date in a select box is greater than today's date.
// this should not be used because the select box date picker is not being used anymore.
// use validateDateText instead (date-validation.js)
function validateDate(selMonth,selDay,selYear,itemMsg) {
	var errorMsg = "";
	selectedDate = new Date(selYear.options[selYear.selectedIndex].value,selMonth.options[selMonth.selectedIndex].value-1,selDay.options[selDay.selectedIndex].value)
	todayDate = new Date();
	if (selectedDate < todayDate) {
		errorMsg += itemMsg + "\n";
	}
	return errorMsg;
}


// verifies that the user has checked a box from a set of checkboxes with the same name
// numToCheckMin and numToCheckMax determine the minmum and maximum the user can select
function verifySingleCheckbox(box,numToCheckMin,numToCheckMax,itemMsg) {
	var errorMsg = "";

	if (!isSingleCheckboxChecked(box,numToCheckMin,numToCheckMax)) {
		errorMsg += itemMsg + "\n";
	}
	return errorMsg;
}

// verifies that the user has checked a box from a set of checkboxes with the same name
// numToCheckMin and numToCheckMax determine the minmum and maximum the user can select
function verifySingleCheckboxBool(box,numToCheckMin,numToCheckMax) {
	if (!isSingleCheckboxChecked(box,numToCheckMin,numToCheckMax)) {
		// false indicates failure
		return false;
	}
	return true;
}

function isSingleCheckboxChecked(box,numToCheckMin,numToCheckMax) {
	var totalChecked = 0;
	var isOneItem = false;
	// this is to check to see if the check box has multiple items -
	// if so, the box.type should be undefined because it's an array
	if (box.type == "checkbox") {
		isOneItem = true;
	}

	if (numToCheckMax == "") {
		if (isOneItem) {
			numToCheckMax = 1;
		} else {
			numToCheckMax = box.length;
		}
	}
	if (!isOneItem) {
		for (var j = 0; j < box.length; j++) {
			if (box[j].checked) {
				totalChecked++;
			}
		}
	} else if (box.checked) {
		totalChecked = 1;
	}
	return ((totalChecked >= numToCheckMin) && (totalChecked <= numToCheckMax));
}


// verifies that the user has checked a box from all the checkboxes in a form
// numToCheckMin and numToCheckMax determine the minmum and maximum the user can select
function verifyAllCheckbox(formRef,numToCheckMin,numToCheckMax,itemMsg) {
	var errorMsg = "";
	var totalBoxes = 0;
	var totalChecked = 0;
	for (j = 0; j < formRef.elements.length; j++) {
		if (formRef.elements[j].type == "checkbox") {
			totalBoxes++;
			if (formRef.elements[j].checked) {
				totalChecked++;
			}
		}
	}
	if (numToCheckMax == "") {
		numToCheckMax = totalBoxes;
	}
	if (!((totalChecked >= numToCheckMin) && (totalChecked <= numToCheckMax))) {
		errorMsg += itemMsg + "\n";
	}
	return errorMsg;
}


// verifies that a radio from a set of radio buttons has been selected
// if it fails, it return the error message specified in errorMsg.
function verifyRadio(radio,itemMsg) {
	var errorMsg = "";
	var isChecked = false;

	if (!radio.checked) {
		for (var j = 0; j < radio.length; j++) {
			if (radio[j].checked) {
				isChecked = true;
			}
		}
		if (!isChecked) {
			errorMsg += itemMsg + "\n";
		}
	}
	isChecked = false;
	return errorMsg;

}




// verifies that the user has selected something other than the default option, specified in defaultValue.
// if it fails, it return the error message specified in errorMsg.
function verifySelectBox(fieldRef,defaultValue,errorMsg) {
	if (fieldRef.type != "hidden") {
		if (fieldRef[fieldRef.selectedIndex].value == defaultValue && !fieldRef.disabled) {
			return errorMsg+"\n";
		} else {
			return "";
		}
	} else {
		return "";
	}
}

// checks to see if the user has checked a specific radio button within a set of radio buttons,
function isSpecificRadioChecked(radio,checkedValue) {
	var undefined;
	isChecked = false;

	if (checkedValue == 0) {
	    // if no radiobutton was selected originally
	    var notChecked = true;
	    for (var j = 0; j < radio.length; j++) {
	        if (radio[j].checked) {
	            notChecked = false;
	        }
	    }
	    if(notChecked == true) {
	        // although no radio button is checked, there was none originally
	        isChecked = true;
	    }
	}

	if (radio.length != undefined) {
		for (var j = 0; j < radio.length; j++) {
			if (radio[j].checked && radio[j].value==checkedValue) {
				isChecked = true;
			}
		}
	}
    else {
		isChecked = radio.checked;
	}

	return isChecked;
}

// checks to see if the user has checked a specific checkbox within a set of checkboxes
function isSpecificCheckboxChecked(checkbox,checkedValue) {
	var undefined;
	var isChecked = false;

	if (checkbox.length != undefined) {
		for (var j = 0; j < checkbox.length; j++) {
			if (checkbox[j].checked && checkbox[j].value==checkedValue) {
				isChecked = true;
			}
		}
	} else {
		isChecked = checkbox.checked;
	}
	return isChecked;
}

// checks to see if a specific option is selected from a select box
function isOptionSelected(selectRef,optionValue) {
	if (selectRef.type == "select-one") {
		return (selectRef[selectRef.selectedIndex].value == optionValue);
	} else {
		return (selectRef.value == optionValue);
	}
}


// returns the value of the selected option
function getSelectedValue(selectRef) {
	if (selectRef.type == "hidden") {
		return selectRef.value;
	} else {
		return selectRef[selectRef.selectedIndex].value;
	}
}

// returns the value selected in a group of radio buttons
function getSelectedRadioValue(radioRef) {
	var undefined;
	if (radioRef.length == undefined) {
		if (radioRef.checked) {
			return radioRef.value;
		}
	} else {
		for (var i = 0; i < radioRef.length; i++) {
			if (radioRef[i].checked) {
				return radioRef[i].value;
			}
		}
	}
	return -1;
}

function getJSObject(fieldRef) {
	return eval(fieldRef.name+"JS");
}

// this duplicates the containsElement function in generalFunctions.js
// it's here so we don't have to require that generalFunctions is also included when this file is.
function hasElement(array1,element) {
	for (var i = 0; i < array1.length; i++) {
		if (array1[i] == element) {
			return true;
		}
	}
	return false;
}

// determines if two arrays are equal (does not compare order, only values)
function areArraysEqual(arr1,arr2) {
	for (var i = 0; i < arr1.length; i++) {
		if (!hasElement(arr2,arr1[i])) {
			return false;
		}
	}
	for (var j = 0; j < arr2.length; j++) {
		if (!hasElement(arr1,arr2[j])) {
			return false;
		}
	}
	return true;
}

// returns an array of the values that are checked in a group of checkboxes
function getCheckedValues(fieldRef) {
	var undefined;
	var values = new Array();
	var count = -1;
	if (fieldRef.length == undefined) {
		if (fieldRef.checked) {
			values[0] = fieldRef.value;
		}
	} else {
		for (var i = 0; i < fieldRef.length; i++) {
			if (fieldRef[i].checked) {
				values[++count] = fieldRef[i].value;
			}
		}
	}
	return values;
}

// returns the number of checkboxes that are selected in a group of checkboxes
function getNumChecked(fieldRef) {
	var count = 0;
	for (var i = 0; i < fieldRef.length; i++) {
		if (fieldRef[i].checked) {
			count++;
		}
	}
	return count;
}

// determines if any of the fields in the page have been changed since page load.
// note: this requires that all fields defined have equivalent formFieldObjects declared.
// does not check for hidden, submits, or buttons.
function isFormChanged(formRef) {
	var info = new String();
	var undefined;
	var field;
	for (var i = 0; i < formRef.elements.length; i++) {
		field = formRef.elements[i];
		if (field.type != "hidden" && field.type != "submit" && field.type != "button" && field.id != "noCheck") {
			if (eval(field.name+"JS.isChanged()")) {
				if (debug) {
					alert(field.name);
				}
				return true;
			}
		}
	}
	return false;
}


function areTextFieldsEqual(field1,field2) {
	return (field1.value == field2.value);
}

function validateEqualTextFields(field1,field2,errMsg) {
	if (areTextFieldsEqual(field1,field2)) {
		return "";
	} else {
		return errMsg;
	}
}


function validatePrice(fieldRef,errMsg) {
	return validateText(fieldRef,"tpvnzsc",errMsg);
}

function validatePositiveInteger(fieldRef,errMsg) {
	return validateText(fieldRef,"pviznms",errMsg);
}

// verifies that file is of specified type
function checkFileExtension(filename, extension) {
	if(isBlank(filename.value)) {
		return false;
	}
	if (filename.value.lastIndexOf('.') !=-1) {
		var firstpos = filename.value.lastIndexOf('.')+1;
		var lastpos = filename.value.length;
		var fileExt = filename.value.substring(firstpos,lastpos);

		var lower = extension.toLowerCase();
		var upper = extension.toUpperCase();

        if(fileExt != lower && fileExt != upper) {
            return false;
        }
	}
    return true;
}

/*
//filename cannot contain space
function checkFileName(filename, itemMsg) {
	var errorMsg = "";
	if(isBlank(fileName)) {
		return errorMsg;
	}
	if (fileName.lastIndexOf('.') !=-1) {
		var firstpos = 0;
		var lastpos = fileName.lastIndexOf('.')-1;
		var name = fileName.substring(firstpos,lastpos);

		if (!isTextValid(name,"b")) {
			errorMsg += itemMsg + "\n";
		}
	}
    return errorMsg;
}
*/

