var decimalPointDelimiter = "."
var defaultEmptyOK = false;
var whitespace = " \t\n\r";

function isEmpty(s)
{   return ((s == null) || (s.length == 0))
}

function isWhitespace (s)
{   var i;
	var whitespaceFound;
    // 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 true;
    }

    // All characters are whitespace.
    return false;
}

function isEmail (s)
{  
//	 if (isEmpty(s)) 
//     if (isEmail.arguments.length == 1) return defaultEmptyOK;
//     else return (isEmail.arguments[1] == true);
   
    // is s whitespace?
    if (isWhitespace(s)) return false;
    
    // there must be >= 1 character before @, so we
    // start looking at character position 1 
    // (i.e. second 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;
}

//Used by is Integer to verify that a single digit is a number
function isDigit (c)
{   return ((c >= "0") && (c <= "9"))
}
//Makes sure a string passed to it is an integer. Used By IsFloat
function isInteger (s)

{   var i;

    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);

        if (!isDigit(c)) return false;
    }

    // All characters are numbers.
    return true;
}

//Checks for ZIP codes in either 5 digit format or ZIP+4 format
function checkZIP(s) {
	var validZIP;
	var pattern = /^[0-9]{5}$/;
	var patternPlus4 = /^[0-9]{5}-[0-9]{4}$/
	validZIP = true;
	
	if ( (s.length == 5) || (s.length == 10) ) {
		if (!( (pattern.test(s)) || (patternPlus4.test(s)) )) {
			validZIP = false;
		}
	}
	else {
		validZIP = false;
	}
	
	return validZIP;
}

//Checks for valid phone numbers
function checkPhone(s) {
	var pattern = /[0-9]{3}\-[0-9]{3}\-[0-9]{4}$/;
	var pattern2 = /[0-9]{3}\-[0-9]{3}\-[0-9]{4}x[0-9]*$/;
	
	return (pattern.test(s)||pattern2.test(s));
}

//Checks for valid Social Security Numbers
function checkSSN(s) {
	var pattern = /[0-9]{3}\-[0-9]{2}\-[0-9]{4}$/;
	
	return pattern.test(s);
}

//Assumes Date in format M/D/YYYY
//Four digit year is required!
function checkDate(s) {
	var month, day, year, pattern, validDate, daysInMonth,dateArray;
	validDate = true;

	dateArray = s.split("/")
	if (dateArray.length != 3 || s.substr(0,1) == "/") {
		validDate = false;
		return validDate;
	}
	
	month = dateArray[0];
	day = dateArray[1];
	year = dateArray[2];

//Check for valid Month
	if ( isInteger(month) ) {
		if ( (month < 1) || (month > 12) ) {
			return false;
		}
	} else {
		return false;
	}
	
//Check for valid day of month
	if ( isInteger(day) ) {
		switch(month-0) {
			case 9:
			case 4:
			case 6:
			case 11:
				daysInMonth = 30;
				break;
			case 2:
				if ( (year % 4) == 0 ) {
					daysInMonth = 29;
				} else {
					daysInMonth = 28;
				}
				break;
			default:
				daysInMonth = 31;
				break;
		}
//		alert(daysInMonth+"  "+day);
		if (day > daysInMonth) {
			return false;
		}
	}
	return validDate;
}

//Makes sure a string passed is a numeric field
function isFloat (s)
{   var i;
    var seenDecimalPoint = false;

    if (s == decimalPointDelimiter) return false;

    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);

        if ((c == decimalPointDelimiter) && !seenDecimalPoint) seenDecimalPoint = true;
        else if (!isDigit(c)) return false;
    }

    // All characters are numbers.
    return true;
}
function isblank(s) {
	if (!s) return false;
	for (var i = 0; i < s.length; i++ ) {
		var c = s.charAt(i);
		if ((c != ' ') && (c != '\n') && (c != '\t')) return false;
	}
	return true;
}

//takes a form as an argument - the call in the onSubmit action in the form tag should be:
// formCheck(this)
//to pass it the form as a pointer
// this allows for multiple forms on a page to use the same code
//setting of properties should be done in the onSubmit action prior to the function call. for example:
// ... onSubmit=" this.ZIP.zipField=true; this.comments.required=false; return formcheck(this);" ...
function formCheck(f)
{
	var validForm, i, valuestring, j, errorString, requiredErrors, formatErrors, requiredOK, lblID;
	validForm = true;
	requiredErrors = "";
	formatErrors = "";
	i = 0;
//	Loop through form elements and make sure they all have values selected
	while ( i < f.length )
	{
		requiredOK=true;
		if (f.elements[i].required) {
//			alert(f.elements[i].type.toLowerCase());
			switch( f.elements[i].type.toLowerCase().substr(0,6) ) 
			{
				case 'select':
					if (f.elements[i][f.elements[i].selectedIndex].value == "" || f.elements[i].selectedIndex == 0 ) {
						requiredOK = false;
					}
					break;
				case 'checkb':
					if (!(f.elements[i].checked) ) {
						requiredOK = false;
					}
					break;
				default:
					if ( f.elements[i].value == "" || f.elements[i].value == null || f.elements[i].value == f.elements[i].initialValue ) {
						requiredOK = false;
					}
					break;
			}
			if (!requiredOK) {
				requiredErrors += "- " + f.elements[i].name + "\n";
				validForm = false;
			}
		}
		if ( !(f.elements[i].value == "" || f.elements[i].value == null ) ) {
			//Now check for formatting errors
			switch(f.elements[i].inputType) {
				case 'numeric':
					if (!(isFloat(f.elements[i].value))) {
						formatErrors += f.elements[i].name + " must be numeric.\n";
						validForm = false;
						f.elements[i].focus();
						f.elements[i].select();
					}
					break;
				case 'zip':
					f.elements[i].value=f.elements[i].value.replace(/\ */g,"");
					if ( !checkZIP(f.elements[i].value) ) {
						formatErrors += f.elements[i].name + " must be a valid ZIP code.\n";
						validForm = false;
						f.elements[i].focus();
						f.elements[i].select();
					}
					break;
				case 'SSN':
					f.elements[i].value=f.elements[i].value.replace(/\ */g,"");
					if ( !checkSSN(f.elements[i].value) ) {
						formatErrors += f.elements[i].name + " must be a valid Social Security Number in the format 123-45-6789.\n";
						validForm = false;
						f.elements[i].focus();
						f.elements[i].select();
					}
					break;
				case 'phone':
					f.elements[i].value=f.elements[i].value.replace(/\ */g,"");
					if ( !checkPhone(f.elements[i].value) ) {
						formatErrors += f.elements[i].name + " must be a valid phone number in the format 123-456-7890 or 123-456-7890x234 for numbers with an extension.\n";
						validForm = false;
						f.elements[i].focus();
						f.elements[i].select();
					}
					break;
				case 'date':
					f.elements[i].value=f.elements[i].value.replace(/\ */g,"");
					if ( !checkDate(f.elements[i].value) ) {
						formatErrors += f.elements[i].name + " must be a valid date in the format M/D/YYYY.\n";
						validForm = false;
						f.elements[i].focus();
						f.elements[i].select();
					}
					break;
				case 'email':
					if ( !isEmail(f.elements[i].value) ) {
						formatErrors += f.elements[i].name + " address must be in this format: xyz@domain.com, .net, .org, etc..\n";
						validForm = false;
						f.elements[i].focus();
						f.elements[i].select();
					}
					break;
			} //end switch
			if (!(isNaN(f.elements[i].maxLength))) {
				if ( f.elements[i].value.length > f.elements[i].maxLength ) {
					formatErrors += f.elements[i].name + " can contain no more than " + f.elements[i].maxLength + " characters.\n";
						validForm = false;
						f.elements[i].focus();
						f.elements[i].select();
				}
			}
			if (!(isNaN(f.elements[i].minLength))) {
				if ( f.elements[i].value.length < f.elements[i].minLength ) {
					formatErrors += f.elements[i].name + " can contain no less than " + f.elements[i].minLength + " characters.\n";
						validForm = false;
						f.elements[i].focus();
						f.elements[i].select();
				}
			}
		}
		i++;
	}
	if (!validForm) {
		errorString = "";
		if (requiredErrors != "") {
			errorString += "The following required fields were not filled in:\n" + requiredErrors + "\n";
		}
		if (formatErrors != "") {
			errorString += "The following format errors occurred:\n" + formatErrors + "\n";
		}
		alert(errorString);
	}
	return validForm;
}
