// validateForm.js
// A library of functions to validate data entered in a form and
// check for required fields.
//
// Version 1.1
// Matt Travers (matt_travers@yahoo.com) 2002-05-22
//

// Forms are validated on two levels. (1) Each element has a valid
// value and (2) all the required fields have values.
//
// The element "onChange/onClick" event updates the "validated" object to keep
// track of the elements without valid values.
// The form "onSubmit" event makes sure changes were made on the
// elements that were deemed invalid and checks for the required
// elements to have values.

// The following is an example of what should be included at the top of your page.
//
// <script language="javascript" src="validateForm.js"></script>
// <script language="javascript">
// <!--
// function validateForm( form ) {
//		var aRequiredElements = new Array( "fname", "lname", "gender" );
//		return checkFormElements( form, aRequiredElements );
// }
// // -->
// </script>

// We use this as a hash to track those elements that do not
// have valid values.

var oValidated = new Object();

function checkFormElements( form, oRequired ) {
// Takes a form and an array of element names to check for values.

	for (element_name in oRequired) {

		var e = form[element_name];

		if (typeof e.type == 'undefined') {
			var eType = e[0].type;
		} else {
			var eType = e.type;
		}

		var r = /^\[.*\]$/;

		switch (eType) {
			case "text":
			case "textarea":
				if ( e.value == "" || r.test(e.value) ) {
					alert("Please enter a value for " + oRequired[element_name] + ".");
					return false;
				}
				break;
			case "select-one":
				if ( e.options[e.selectedIndex].value == "" || r.test(e.options[e.selectedIndex].value) ) {
					alert("Please select a value for " + oRequired[element_name] + ".");
					return false;
				}
				break;
			case "radio":
			case "checkbox":
				if (typeof e.type == 'undefined') { // If true, this is a collection of elements.
					var isChecked = false;
					for (var j = 0; j < e.length; j++) {
						if (e[j].checked) {
							isChecked = true;
						}
					}
					if (!isChecked) {
						alert("Please choose a " + oRequired[element_name] + ".");
						return false;
					}
				} else {
					if (!e.checked) {
						alert("Please click " + oRequired[element_name] + ".");
						return false;
					}
				}
				break;
		}
	}
	return checkValidated( oRequired );
}

function checkValidated( oRequired ) {
// Verify there are no uncorrected elements that didn't pass validation.

	for (element_name in oValidated) {
		if (!oValidated[element_name]) {
			if (oRequired[element_name]) {
				alert("Please correct the format of " + oRequired[element_name] + ".");
			} else {
				alert("Please correct the format of " + element_name + ".");
			}
			return false;
		}
	}
	return true;
}


////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

// The following functions are a laundry list of all types of value checks.
// Pick and choose the ones you need for each element in your form and add it
// to the "onChange" event of you input tag.
//
// The firt parameter in each function is "e" which is short for "element".
// Each function is called with "this" as its first parameter in the calling page.

function isCheckLimit( e, numberCheckedLimit ) {
	var count = 0;
	for (var j = 0; j < e.form[e.name].length; j++) {
		if (e.form[e.name][j].checked) {
			count++;
		}
	}
	return handle_result( (count <= numberCheckedLimit)?true:false, e, "You may select " + numberCheckedLimit + " items max." );
}

function isDate( e ) {
	var r = /^\d{1,2}[\/-]\d{1,2}[\/-](\d{2}|\d{4})$/;
	return handle_result( r.test( e.value ), e, "Please enter a date in the format 'mm/dd/yyyy'." );
}

function isDBDate( e ) {
	var r = /^(\d{2}|\d{4})-\d{1,2}-\d{1,2}$/;
	return handle_result( r.test( e.value ), e, "Please enter a date in the format 'yyyy-mm-dd'." );
}

function isEmail( e ) {
	var r = /^\S+@\S+$/;
	return handle_result( r.test( e.value ), e, "Please enter a valid e-mail address." );
}

function isInteger( e ) {
	var r = /^\d+$/;
	return handle_result( r.test( e.value ), e, "Please enter a valid number." );
}

function isPhone( e ) {
	var r = /^\(?\d{3}[\)-]?\W?\d{3}-?\d{4}$/;
	return handle_result( r.test( e.value ), e, "Please enter a valid phone number." );
}

function isSSN( e ) {
	var r = /^(\d\D*){9}$/;
	return handle_result( r.test( e.value ), e, "Please enter a valid Social Security Number." );
}

function isStateAbbrev( e ) {
	var r = /^(AB|AK|AL|AR|AS|AZ|BC|CA|CO|CT|DC|DE|DF|FL|FM|GA|GU|HI|IA|ID|IL|IN|KS|KY|LA|MA|MB|MD|ME|MH|MI|MN|MO|MP|MS|MT|NB|NC|ND|NE|NF|NH|NJ|NM|NS|NV|NY|OH|OK|ON|OR|PA|PE|PQ|PR|PW|RI|SC|SD|SK|TN|TX|UT|VA|VI|VT|WA|WI|WV|WY)$/;
	return handle_result( r.test( e.value ), e, "Please enter a valid state." );
}

function isWordCountLimit( e, numberOfWords ) {
	var s = new String(e.value);
	var aWords = s.split(" ");
	return handle_result( (aWords.length <= numberOfWords)?true:false, e, "You may enter " + numberOfWords + " words maximum." );
}

function isZipCode( e ) {
	var r = /^(\d{5}|\d{5}-\d{4})$/;
	return handle_result( r.test( e.value ), e, "Please enter a valid zip code." );
}

////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

function handle_result( result, e, alert_text ) {
// This function is a generic handler of the validation test.
	
	if (! result) {
		alert(alert_text);
		oValidated[e.name] = false;
	} else {
		oValidated[e.name] = true;
	}

	if (! oValidated[e.name]) { e.focus(); }
	return oValidated[e.name];
}

////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

function checkForThree( form ) {
	var count;

	// Check "at_home".
	count = 0;
	for (var i = 0; i < form['at_home[]'].length; i++) {
		if (form['at_home[]'][i].checked) {
			count++;
		}
	}
	if (count != 3) {
		alert('Please choose exactly 3 "at home" activities.');
		return false;
	}
	
	// Check "with_friends".
	count = 0;
	for (var i = 0; i < form['with_friends[]'].length; i++) {
		if (form['with_friends[]'][i].checked) {
			count++;
		}
	}
	if (count != 3) {
		alert('Please choose exactly 3 "with friends" activities.');
		return false;
	}
	
	return true;
}

function checkAge( form, min_years ) {

	var now = new Date();
	var years = now.getFullYear() - form['dob_yyyy'].options[form['dob_yyyy'].selectedIndex].value;
	var months = (now.getMonth() + 1) - form['dob_mm'].options[form['dob_mm'].selectedIndex].value;
	var days = now.getDate() - form['dob_dd'].options[form['dob_dd'].selectedIndex].value;

	var old_enough = false;
	
	if (years > min_years) {
		old_enough = true;
	}

	if (years == min_years && months > 0) {
		old_enough = true;
	}

	if (years == min_years && months == 0 && days >= 0) {
		old_enough = true;
	}

	if (old_enough) {
		return true;
	} else {
		alert("All applicants must be over " + min_years + " years old.");
		return false;
	}
}
