/*
File:  validate.js
=============================================
When        Who   	What
---------------------------------------------
2000-01-11  jtc   	new/revised file
2000-03-31	jtc		improved version. Called it
					validate2 in the olan mills project
					for the time being. This version allows for
					extended error messages coming out of the
					validate functions.
=============================================

Notes:

	Validation functions.
	The validateForm() function processes a structure
	like the example included here and validates
	the form accordingly. 
*/

function isBlank( str ) {
     var isValid = false;
     if ( isNull(str) || isUndef(str) || (str+"" == "") ) {
          isValid = true;
	}
     return isValid;
}  // end IsBlank

function isText(str /*, maxlen*/)
{
	var maxlen = 0;
	with (isText) {
		if (arguments.length >= 2) {
			maxlen = new Number(arguments[1]);
		}
	}

	if (maxlen && str.length > maxlen) {
		return "Only " + maxlen + " characters allowed.";
	}

	var isValid = "";
    if ( isNull(str) || isUndef(str) || (str+"" == "") ) {
		isValid = "Empty entries are not allowed.";
	}
	return isValid;
}
	
function isAllDigits(s)
{
    var str = "" + s;
    for (var k = 0; k < str.length; k++) {
		if (! (str.charAt(k) >= "0" && str.charAt(k) <= "9")) {
            return "Only numbers (0 - 9) are allowed.";
        }
    }
    return "";
}

function isAlpha(str /*, maxlen*/) 
{
     // Return immediately if an invalid value was passed in
    if (str+"" == "undefined" || str+"" == "null" || str+"" == "") {
		return "Empty entries are not allowed.";
	}

	var maxlen = 0;
	with (isAlpha) {
		if (arguments.length >= 2) {
			maxlen = new Number(arguments[1]);
		}
	}

	if (maxlen && str.length > maxlen) {
		return "Only " + maxlen + " letters allowed.";
	}
	
    var isValid = "";
    str += "";
	// convert to a string for performing string comparisons.

    // Loop through string one character at time,  breaking out of for
    // loop when an non Alpha character is found.
	for (i = 0; i < str.length; i++) {
        // Alpha must be between "A"-"Z", or "a"-"z"
        if ( !( ((str.charAt(i) >= "a") && (str.charAt(i) <= "z")) ||
        		((str.charAt(i) >= "A") && (str.charAt(i) <= "Z")) ) )
		{
        	isValid = "Only letters (A - Z) are allowed.";
            break;
        }
   } // end for loop

   return isValid;
}  // end IsAlpha

function isNull( val ) {
     var isValid = false;

     if (val+"" == "null")
          isValid = true;

     return isValid;
}  // end IsNull

function isUndef( val ) {
     var isValid = false;

     if (val+"" == "undefined")
          isValid = true;

     return isValid;
}  // end IsUndef


function isValidTime(str){
	if (str+"" == "undefined" || str+"" == "null" || str+"" == "")
          return "Empty entries are not allowed.";
		  
	var isValid = "";
	
	str += "";
	
	hstr = str.substring(0, str.indexOf(":"));
	mstr = str.substring(str.indexOf(":")+1, str.length);
	tstr = str.substring(str.length-1, str.length)
	
	if (isBlank(str) || (hstr.length == 0) ||
			(mstr.length == 0) ||
			(tstr.length != ("am" || "pm")))
		isValid = "Please enter something like '9:00' or '10:00 pm'";
		
	return isValid;	
}	
	
// New function that validates the email in the form
function isValidEmail (str /*, maxlen */) {
     // Return immediately if an invalid value was passed in
    if (str+"" == "undefined" || str+"" == "null" || str+"" == "") {
          return "Empty entries are not allowed.";
	}

  	var maxlen = 0;
	with (isValidEmail) {
		if (arguments.length >= 2) {
			maxlen = new Number(arguments[1]);
		}
	}

	if (maxlen && str.length > maxlen) {
		return "Only " + maxlen + " characters allowed.";
	}

     var isValid = "";

     str += "";

     namestr = str.substring(0, str.indexOf("@"));
	 // everything before the '@'
     domainstr = str.substring(str.indexOf("@")+1, str.length);
	 // everything after the '@'

     // Rules: namestr cannot be empty, or that would indicate no
	 // characters before the '@',
     // domainstr must contain a period that is not the first character
	 // (i.e. right after
     // the '@').  The last character must be an alpha.
     if ((namestr.length == 0) ||
               (domainstr.indexOf(".") <= 0) ||
               (domainstr.indexOf("@") != -1) ||
               isAlpha(str.charAt(str.length-1)) != "")
	{
//		alert(isAlpha(str.charAt(str.length-1)));
    	isValid = "Please enter a valid email address like 'user@domain.org'.";
	}

     return isValid;
} // end IsValidEmail

function isUSState(str) 
{
	str = str.toUpperCase();
	
  	if ( (str == "AK") || (str == "AL") || (str == "AR") || (str == "AZ") || (str == "CA") || (str == "CO") || (str == "CT") || (str == "DC") || (str == "DE") || (str == "FL") || (str == "GA") || (str == "HI") || (str == "IA") || (str == "ID") || (str == "IL") || (str == "IN") || (str == "KS") || (str == "KY") || (str == "LA") || (str == "MA") || (str == "MD") || (str == "ME") || (str == "MI") || (str == "MN") || (str == "MO") || (str == "MS") || (str == "MT") || (str == "NE") || (str == "NC") || (str == "ND") || (str == "NH") || (str == "NJ") || (str == "NM") || (str == "NV") || (str == "NY") || (str == "OH") || (str == "OK") || (str == "OR") || (str == "PA") || (str == "RI") || (str == "SC") || (str == "SD") || (str == "TN") || (str == "TX") || (str == "UT") || (str == "VA") || (str == "VT") || (str == "WA") || (str == "WI") || (str == "WV") || (str == "WY") )
	{
		return "";
	}
	else {
		return "Please enter a valid 2-letter US state code.";
	}
}

// Functions that validates the phone number in the form
function isPhoneNum(str) 
{
	var errstr = "Please enter a phone number in the format 800-555-1212";

  	if (str.length != 12) { 
  		return errstr;
	}
  	for (i=0; i<str.length; i++) {
    	if ((i == 3) || (i == 7)) {
	      	if (str.charAt(i) != "-") { 
				return errstr;
			}
    	} 
		else {
    	  	if ((str.charAt(i) < "0") || (str.charAt(i) > "9")) { 
				return errstr;
			}
	    }
	}
  	return "";
}

function isValidZIPCode(zip)
{
    if (zip.length == 5) {
        return (isAllDigits(zip));
	}
    else if (zip.length == 10)
    {
        return (isAllDigits(zip.substring(0,5)) && (zip.substring(5,6) == "-") && (isAllDigits(zip.substring(6,10))));
	}
	return "Please enter a ZIP code in the format '12345' or '12345-6789'.";
}

function isValidMonth(str)
{
	var errstr;
	if ((errstr = isAllDigits(str)) != "") {
		return errstr;
	}
	var num = new Number(str);
	if (num < 1 || num > 12) {
		return "Please enter a number between 1 and 12.";
	}
	return "";
}

function isValidDay(str)
{
	var errstr;
	if ((errstr = isAllDigits(str)) != "") {
		return errstr;
	}

	var num = new Number(str);
	if (num < 1 || num > 12) {
		return "Please enter a number between 1 and 31.";
	}
	return "";
}



function radio_isBlank(radio)
{
	var	isBlank = true;
	for (index = 0; index < radio.length; index++) {
		if (radio[index].checked == true) isBlank = false;
	}
	return isBlank;
}

/*	This prototype defines a validation "object". We make an array of these objects that is 
	specific for a particular form being validated. */
function valobj(fieldname,fieldcapt,inptype,blankfunc,validfunc,maxlen)
{ this.fieldname = fieldname; this.fieldcapt = fieldcapt; this.inptype = inptype; this.blankfunc = blankfunc;  this.validfunc = validfunc; 
this.maxlen = (("undefined" == "" + maxlen || maxlen == null) ? 0 : 0 + maxlen);
//alert("this.maxlen = " + this.maxlen);
}

/*	This code below should go near the form being validated or in a page-specific script file. */
/*	Example:
var valfields = new Array();
var cnt = 0;

valfields[cnt++] = new valobj("Lname", "Last Name", "text", isBlank, isText);
valfields[cnt++] = new valobj("State", "State", "text", isBlank, isUSState);
valfields[cnt++] = new valobj("Zip", "Zip", "text", isBlank, isValidZIPCode);
valfields[cnt++] = new valobj("Telephone", "Telephone", "text", isBlank, isPhoneNum);
valfields[cnt++] = new valobj("Email", "Email", "text", isBlank, isValidEmail);
valfields[cnt++] = new valobj("C1Fname", "First Child First Name", "text", isBlank, isText);
valfields[cnt++] = new valobj("C1Lname", "First Child Last Name", "text", null, isText);
valfields[cnt++] = new valobj("C1Sex", "First Child Sex", "radio", radio_isBlank, null);
valfields[cnt++] = new valobj("C1month", "First Child Birthday Month", "text", isBlank, isValidMonth);
valfields[cnt++] = new valobj("C1day", "First Child Birthday Day", "text", isBlank, isValidDay);
valfields[cnt++] = new valobj("C1year", "First Child Birthday Year", "text", isBlank, isAllDigits);
valfields[cnt++] = new valobj("C2Fname", "Second Child First Name", "text", null, isText);
*/

/*	Here's the granddaddy function that does it all. */
function validateForm(form) 
{
	var fieldarray = valfields;
	var	local = false;
	
	/*	Allow an alternate field array to be passed in as a second parameter. */
	if (validateForm.arguments.length == 2) {
		fieldarray = validateForm.arguments[1];
		local = true;
	}
		
	for (fieldno in fieldarray)
	{
		var fieldname = fieldarray[fieldno].fieldname;
		var fieldcapt = fieldarray[fieldno].fieldcapt;
		var blankfunc = fieldarray[fieldno].blankfunc;
		var validfunc = fieldarray[fieldno].validfunc;
		var inptype = fieldarray[fieldno].inptype;
		var maxlen = fieldarray[fieldno].maxlen;
//		alert("fieldarray[].maxlen = " + maxlen);
		var blank = false;
		
		if (typeof (form[fieldname]) != "object") {
			alert("Program error: '" + fieldname + "' is not a form input.");
			continue;
		}
		
		/*	First check the blankness of the input. The polarity is such that if the
			function returns true we're blank. If no function is specified then it's ok
			for this input to be blank. But if there's a validfunc we'll still check its
			validity if there's something in it. */
		if (typeof (blankfunc) == "function") {
			if (inptype == "radio") {
				/*	Pass the actual input object */
				blank = blankfunc(form[fieldname]);
				if (blank) {
					alert("Please select an option for '" + fieldcapt + "'.");
					/*	Focus on the first radio in the group. */
					form[fieldname][0].focus();
				}
			}
			else {
				blank = blankfunc(form[fieldname].value);
				if (blank) {
					alert("'" + fieldcapt + "' cannot be blank.");
					form[fieldname].focus();
				}
			}
			if (blank) return (false);
		}
		else {
			/*	This might look funny, but if we passed the blank function but
				if we get here we either don't have a blankfunc or we passed it. But
				do a check to make sure the input isn't blank; if it is it will probably
				fail its validation routine, so continue to the next input. */
			if (inptype == "text" && isBlank(form[fieldname].value)) continue;
		}
		
		/*	Now check the validness of the input. Polarity is true == good value. */
		/*	Figure that radio buttons will not need a validate func. */
		var errstr;
		if ((typeof (validfunc) == "function") && ((errstr = validfunc(form[fieldname].value,maxlen)) != "")) {
			alert("'" + form[fieldname].value + "' is not a valid value for '" + fieldcapt + "'.\r\n" + errstr);
			form[fieldname].select();
			form[fieldname].focus();
			return (false);
		}
	}
	
	if (!local) {
		if (typeof(local_validateForm) == "function") {
			return local_validateForm(form);
		}
	}
	return true;
}



