//========================= General =========================//
	//  Compatability test for W3C Document Object Model
	var W3CDOM = document.createElement && document.getElementsByTagName;
	

//========================= Error Messages and Functions  =========================//
	//  Error messages to be displayed in error label
	var validationErrorMessage = new Object();
		validationErrorMessage['postal_code'] = 'Please provide as XXXXX';
		validationErrorMessage['phone'] = 'Please provide as XXX-XXX-XXXX';
		validationErrorMessage['email'] = 'Invalid email address';

//========================= Form Validation Types  =========================//
	//  Requires values for 'text' and 'textarea' inputs
	function isRequired (formField) {
		switch (formField.type) {
			case 'text':
			case 'textarea':
			case 'select-one':
				if (formField.value) {
					return true;
				}
			return false;
		}
	}

	//  Establishes a regular expression, tests it, and returns TRUE or FALSE
	function isPattern(formField, pattern) {
		//  Helps with focusing scope
		var pattern = pattern; 
		//  ^ ==> 'start of line'
		//  $ ==> 'end of line'
		var regExp = new RegExp("^" + pattern + "$");
		// .test() ==> returns a TRUE or FALSE based on is the pattern is found in the provided string
		var correct = regExp.test(formField.value);
		
		//  Returns the result of the test
		return correct;
	}
	
	//  Are we looking at a valid zip code?
	function isValidZip(formField) {
		return isPattern(formField, "^[0-9]{5}(-[0-9]{4})?$");
	}
	
	//  Are we looking at a valid email?
	function isValidEmail(formField) {
		return isPattern(formField, "[a-zA-Z0-9._+%-]+@([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$")
	}
	
	//  Are we looking at a valid phone number?
	function isValidPhone(formField) {
		return isPattern(formField, "^[0-9]{3}-[0-9]{3}-[0-9]{4}$")
	}

//========================= Form Validation  =========================//
	function validate () {
		//  Grabs all of the form fields for current form
		var formFields = this.elements;
				
		//  Tella us if the form is valid
		var validForm = true;
		
		//  Loops through form fields
		for (var i = 0; i < formFields.length; i++) {
			//  If there is an error attached, it is removed as the form is initialized
			if (formFields[i].removeError) {
				formFields[i].removeError();
			}
			
			//  Looks for all formfields with our custom attribute of 'validation'
			var validation = formFields[i].getAttribute('validation');
			
			//  Moves on if 'validation' attribute isn't on form field
			if (!validation) continue;
			
			var OK, requiredFirst = true; 
			
			//  Runs different validation checks based on form field id
			switch (formFields[i].id) {
						case "first_name":
						case "last_name":
						case "address":
						case "city":
						case "state":
						case "program_code":
							OK = isRequired(formFields[i]);
							break;
							
						case "postal_code":
							OK = isRequired(formFields[i]);
							if (OK) { 
								OK = isValidZip(formFields[i]);
								requiredFirst = false;
							}
							break;
							
						case "email":
							OK = isRequired(formFields[i]);
							if (OK) { 
								OK = isValidEmail(formFields[i]);
								requiredFirst = false;
							}
							break;
							
						case "phone":
							OK = isRequired(formFields[i]);
							if (OK) { 
								OK = isValidPhone(formFields[i]);
								requiredFirst = false;
							}
							break;
							
						default:
							OK = isRequired(formFields[i]);
							break;
					};
			
			if (!OK) {
				var errorMessage = "Required Field"; 
					if (!requiredFirst) {
						errorMessage =  validationErrorMessage[formFields[i].id] || "";
					} 
					
				writeError(formFields[i], errorMessage);
				
				formFields[i].onfocus = removeError;
				validForm = false;
			}
			
		}
		
		//  Returns out whether the form is valid or not
		return validForm;
	}


//========================= Error Handling  =========================//
	//  Writes out a new error label if trouble is found
	function writeError(formField, message) {
		//  Adds the class of 'errorMessage' to element with validation trouble
		formField.className = 'errorMessage';
		//  Sets the onfocus event on this elements to remove the error
		formField.onfocus = removeError;
		
		//  If an error message has already been set, we exit out
		if (formField.errorMessage || message == "") return;
		
		//  Writes out a second label tag for the element which contains the appropriate error message
		var errorMessage = document.createElement('label');
			errorMessage.className = 'errorMessage';
			if (formField.type == "select-one") {
				errorMessage.className += ' selectError';
			}
			errorMessage.setAttribute('for',formField.id);
			errorMessage.setAttribute('htmlFor',formField.id);
			errorMessage.appendChild(document.createTextNode(message));
		
		//  Attaches the errorMessage to the parantElement of invalid form field
		formField.parentNode.appendChild(errorMessage);
		formField.errorMessage = errorMessage;
	}

	//  Removes indicator of error
	function removeError() {
		//  Strips out the errorMessage CSS class name
		this.className = this.className.replace(/errorMessage/,'');
			
		//  If the element in question has an error message, it is removed and everything is set back to defaults
		if (this.errorMessage) {
			this.parentNode.removeChild(this.errorMessage);
			this.errorMessage = null;
			this.parentNode.errorMessage = null;
		}
			
		//  Removes onfocus event function
		this.onfocus = null;	
	}
//========================= Initialization =========================//
	// Initializes all forms on the page to use our validate script on submit
	function initializeForms () {
		if (!W3CDOM) return; 
		
		var forms = document.forms;
		
		for (var i = 0; i < forms.length; i++) {
			forms[i].onsubmit = validate;
		}		
	}