//*****************************************************************************
// Title:		JavaScript Form Validation
// Version:		v1.0 - January 29th, 2002.
// Author:		Adam Julien ( 'Borrowed' most functions from freely 
//			available Netscape Communications' web site. Added some 
//			tweaks and additional functions )
// Last Modified:	n.a.
// Modifications:	n.a.
//
//
// Purpose:	Javascript Function Library for web form data input validation.
//		Includes prompts, alerts, and various various checks for data 
//		integrity.
//		Primary functions included:
//		checkString	- Checks for any non-whitespace characters
//		checkInteger	- Checks for integers only
//		checkLength	- Checks that length is below a specified max length
//		checkRadio	- Checks that a radio button has been selected
//		checkSelect	- Checks that a non-whitespace Select Option Value has been selected
//		checkDate	- Checks that a year, month, day forms a valid date
//		checkEmail	- Checks for a valid formed email address
//		checkPostal	- Checks for a valid alpha-numeric combination of 6 characters
//
//
// Usage:	* Sample usage of this library *
//		1. Include this javascript file using:
//		<SCRIPT language="JavaScript" src="[Path to javascript file]/formValidation.js" type="text/javascript"></SCRIPT>
//
//		2. Compose your form fields' validation functions:
//		function validateInfo(form) {
//			return (
//				checkString(form.elements["firstName"],'First Name') && 
//				checkString(form.elements["lastName"],'Last Name') && 
//				checkString(form.elements["phoneHome"],'Home Phone') && 
//				checkEmail(form.elements["emailAddress"],'Email Address') && 
//				checkLength(form.elements["comments"],'Comments',1500)
//			)
//		}
//
//		3. Execute you form validation using an onSubmit action on your form
//		<FORM .... onsubmit="return validateInfo(this);">
//
//		If you are using images as submit buttons
//		<A href="javascript:if (validateInfo(document.[Form Name])) document.[Form Name].submit();" onMouseOver="window.status='Submit';return true;" onMouseOut="window.status='';return true;"><IMG src="[Path To Button Image]" border="0"></A>
//
//		For browser status prompts use:
//		<INPUT ... onFocus="promptEntry([Field Label])'".. onBlur="window.status=''; return false;"...>
//
// Returns:	none
// Future Considerations / Enhancements:
//  - none
//******************************************************************************

function makeArray(n) {
	for (var i = 1; i <= n; i++) {
		this[i] = 0
	}
	return this
}

// Declarations
var defaultEmptyOK = false;
var whitespace = " \t\n\r";
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;

// Alert Strings
var mPrefix = "You did not enter a value into the \'"
var mSuffix = "\' field. \n\nThis is a required field. Please enter it now."
var pEntryPrompt = "Please enter your "

var iEmail = " field must be a valid email address. \n\nPlease re-enter it now."
var iPostal = " field must be a valid postal code. \n\nPlease re-enter it now."
var iInteger = " field must be a numeric value. \n\nPlease re-enter it now."
var iLength1 = " field must not exceed the character limit of "
var iLength2 = " characters. \n\nPlease re-enter it now."
var iDay = " field must be a numeric day between 1 and 31.  Please re-enter it now."
var iMonth = " field must be a valid month.  Please re-enter it now."
var iYear = " field must be a 2 or 4 digit year.  Please re-enter it now."
var iDatePrefix = "The month, day, and year for "
var iDateSuffix = " does not form a valid date.  Please re-enter them now."

// Alert Functions
function promptEntry (s) {
	if (promptEntry.arguments.length == 2) window.status = s; else window.status = pEntryPrompt + s;
}
function warnEmpty (theField, s) {
	theField.focus()
	if (isEmpty(theField.selectedIndex)) theField.select()
	alert(mPrefix + s + mSuffix)
	return false
}
function warnInvalid (theField, s, iP, iS ) {
	theField.focus()
	if (theField.type != 'select-one') theField.select();
	var numArgs; numArgs = warnInvalid.arguments.length;

	if (numArgs == 3) {
		alert("The \'"+s+"\'" + iP);
	} else {
		if (numArgs == 4) {
			alert(iP + "\'"+s+"\'" + iS);
		} else {
			alert("The \'" + s + "\'" + iP + "" + warnInvalid.arguments[4] + "" + iS)
		}
	}
	return false;
}

// Utility Functions
function isEmpty(s) {
	return ((s == null) || (s.length == 0))
}
function isWhitespace (s) {
	var i;
	if (isEmpty(s)) return true;
	for (i = 0; i < s.length; i++) {
		var c = s.charAt(i);
		if (whitespace.indexOf(c) == -1) return false;
	}
	return true;
}
function isDigit (c) {
	return (((c >= "0") && (c <= "9")) || (c == "."))
}
function isAlpha (c) {
	return (((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")))
}

function isInteger (s) {
	if (isEmpty(s))
		if (isInteger.arguments.length == 1) return defaultEmptyOK;
		else return (isInteger.arguments[1] == true);
	if (isWhitespace(s)) return false;
	var i = 0;
	var sLength = s.length;
	while (i < sLength) {
		if (!isDigit(s.charAt(i))) return false;
		i++;
	}
	return true;
}
function isIntegerInRange (s, a, b) {
	if (isEmpty(s)) 
		if (isIntegerInRange.arguments.length == 1) return defaultEmptyOK;
		else return (isIntegerInRange.arguments[1] == true);

	if (!isInteger(s, false)) return false;

	var num = parseInt (s);
	return ((num >= a) && (num <= b));
}
function isYear (s) {
	if (isEmpty(s)) 
		if (isYear.arguments.length == 1) return defaultEmptyOK;
		else return (isYear.arguments[1] == true);
	if (!isInteger(s)) return false;
	return ((s.length == 2) || (s.length == 4));
}
function isMonth (s) {
	if (isEmpty(s)) 
		if (isMonth.arguments.length == 1) {
			return defaultEmptyOK;
		} else { return (isMonth.arguments[1] == true); }
	if (isInteger(s)) 
		return isIntegerInRange (s, 1, 12);
	s = s.toLowerCase();
	if ((s=="jan") || (s=="feb") || (s=="mar") || (s=="apr") || (s=="may") || (s=="jun") || 
		(s=="jul") || (s=="aug") || (s=="sep") || (s=="oct") || (s=="nov") || (s=="dec")) {
		return true;
	}
	if ((s=="january") || (s=="february") || (s=="march") || (s=="april") || (s=="may") || 
		(s=="june") || (s=="july") || (s=="august") || (s=="september") || (s=="october") || 
		(s=="november") || (s=="december")) {
		return true;
	}
	return false;
}
function isDay (s) {
	if (isEmpty(s))
		if (isDay.arguments.length == 1) return defaultEmptyOK;
		else return (isDay.arguments[1] == true);
	return isIntegerInRange (s, 1, 31);
}
function daysInFebruary (year) {
	return ( ((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0) ) ) ? 29 : 28 );
}
function isDate (year, month, day) {
	if (! (isYear(year, false) && isMonth(month, false) && isDay(day, false))) return false;
	if (!isInteger(month)) {
		month = month.toLowerCase();
		if ((month=="january") || (month=="jan")) month=1
		if ((month=="february") || (month=="feb")) month=2
		if ((month=="march") || (month=="mar")) month=3
		if ((month=="april") || (month=="apr")) month=4
		if ((month=="may") || (month=="may")) month=5
		if ((month=="june") || (month=="jun")) month=6
		if ((month=="july") || (month=="jul")) month=7
		if ((month=="august") || (month=="aug")) month=8
		if ((month=="september") || (month=="sep")) month=9
		if ((month=="october") || (month=="oct")) month=10
		if ((month=="november") || (month=="nov")) month=11
		if ((month=="december") || (month=="dec")) month=12
		if (!isInteger(month)) return false;
	}

	var intYear = parseInt(year);
	var intMonth = parseInt(month);
	var intDay = parseInt(day);

	if (intDay > daysInMonth[intMonth]) return false;

	if ((intMonth == 2) && (intDay > daysInFebruary(intYear))) return false;

	return true;
}
function isValidPostal(s) {
	if ((s.length == 6)) {
		if (isAlpha(s.charAt(0)) && isDigit(s.charAt(1)) && 
			isAlpha(s.charAt(2)) && isDigit(s.charAt(3)) &&
			isAlpha(s.charAt(4)) && isDigit(s.charAt(5))) {
			s = s.toUpperCase();
			return true;
		}
	}
	return false;
}
function isEmail (s) {
	if (isEmpty(s))
		if (isEmail.arguments.length == 1) return defaultEmptyOK;
		else return (isEmail.arguments[1] == true);
	if (isWhitespace(s)) return false;

	// there must be >= 1 character before @, so we start
	//  looking at character position 1 (i.e. 2nd character)
	var i = 1;
	var sLength = s.length;
	// look for @
	while ((i < sLength) && (s.charAt(i) != "@")) {
		i++
	}
	if ((i >= sLength) || (s.charAt(i) != "@")) return false;
	else i += 2;
	// look for .
	while ((i < sLength) && (s.charAt(i) != ".")) {
		i++
	}
	// there must be at least one character after the .
	if ((i >= sLength - 1) || (s.charAt(i) != ".")) return false;
	else return true;
}

// Form Functions
function checkString (theField, s, emptyOK) {
	if (checkString.arguments.length == 2) emptyOK = defaultEmptyOK;
	if ((emptyOK == true) && (isEmpty(theField.value))) return true;
	if (isWhitespace(theField.value)) return warnEmpty (theField, s);
	else return true;
}
function checkInteger (theField, s, emptyOK) {
	if (checkInteger.arguments.length == 2) emptyOK = defaultEmptyOK;
	if ((emptyOK == true) && (isEmpty(theField.value))) return true;
	if (isWhitespace(theField.value)) 
		return warnEmpty (theField, s);
	else if (!isInteger(theField.value, false)) 
		return warnInvalid (theField, s, iInteger);
	else return true;
}
function checkLength(theField, s, maxSize) {
	if ((theField.value.length) < maxSize) {
		return true;
	} else {
		return warnInvalid (theField, s, iLength1, iLength2, maxSize);
	}
}
function checkRadio (theField, s) {
	for (var i = 0; i < theField.length; i++) {
		if (theField[i].checked) {
		return true
		}
	}
	alert (s + iRadio);
	return false
}
function checkSelect (theField, s) {
	if ((theField.selectedIndex) == -1 ) return warnEmpty (theField, s);
	if (isEmpty(theField.options[theField.selectedIndex].value)) {
		return warnEmpty (theField, s);
	}
	return true
}
function checkDate (monthField, dayField, yearField, s, emptyOK) {
	//month field can be a text field or a select dropdown
	if (monthField.type=='select-one') {
		if (checkSelect(monthField, 'Event End Date - month')) {
			monthFieldValue = monthField.options[monthField.selectedIndex].value;
		} else return false;
	} else monthFieldValue = monthField.value
	if (checkDate.arguments.length == 4) emptyOK = defaultEmptyOK;
	if ((emptyOK == true) && (isEmpty(monthFieldValue)) && (isEmpty(yearField.value)) && (isEmpty(dayField.value))) return true;
	if (!isMonth(monthFieldValue)) return warnInvalid (monthField, s + ' - month', iMonth);
	if (!isDay(dayField.value)) return warnInvalid (dayField, s + ' - day', iDay);
	if (!isYear(yearField.value)) return warnInvalid (yearField, s + ' - year', iYear);
	if (isDate (yearField.value, monthFieldValue, dayField.value)) return true;
	alert (iDatePrefix + s + iDateSuffix)
	return false
}
function checkEmail (theField, s, emptyOK) {
	if (checkEmail.arguments.length == 2) emptyOK = defaultEmptyOK;
	if ((emptyOK == true) && (isEmpty(theField.value))) return true;
	else if (!isEmail(theField.value, false)) 
       return warnInvalid (theField, s, iEmail);
    else return true;
}
function checkPostal (theField, s, emptyOK) {
	if (checkPostal.arguments.length == 2) emptyOK = defaultEmptyOK;
	if ((emptyOK == true) && (isEmpty(theField.value))) return true;
	else if (!isValidPostal(theField.value, false)) 
		return warnInvalid (theField, s, iPostal);
	else return true;
}

