var errors;
var errorsTabbed;
var errorFields;

/**
* Validates a form
* If type is 'page', the div#errorMessage must exist in the document
* @param form				The form element to validate
* @param type optional string		The type of display ('page' or 'alert')
* @param highlight optional bool	Should error fields be highlighted ('yes' or 'no')
*/
function validateForm(form, type, highlight) {
	var i;

	if (type != 'alert') {
		type = 'page';
	}
	if (type == 'page' && document.getElementById('errorMessage') == null) {
		type = 'alert';
	}
	if (highlight != 'no') {
		highlight = true;
	} else {
		highlight = false;
	}

	errors = new Array();
	errorsTabbed = new Array();
	errorFields = new Array();
	for (i=0; i<form.length; i++) {
		if (highlight) {
			showError(form.elements[i], false);
		}
		validate(form.elements[i]);
	}
	if (errors.length > 0 || errorsTabbed.length > 0) {
		// Highlight Error Fields
		if (highlight) {
			for (i=0; i<errorFields.length; i++) {
				showError(errorFields[i], true);
			}
		}
		// Combine Error Messages from Fields with or without TabIndexes
		for (i in errors) {
			errorsTabbed[errorsTabbed.length] = errors[i];
		}
		// Display the Error Message
		if (type == 'page') {
			// Display in the errorMessage tag on the page
			errorHTML = '';
			for (i=0; i<errorsTabbed.length; i++) {
				if (errorsTabbed[i]) {
					errorHTML += errorsTabbed[i] + "<br>";
				}
			}
			errorHTML += '<br>';
			document.getElementById('errorMessage').innerHTML = errorHTML;
			// Addresses Safari Redrawing Error (when window is already scrolled to the top)
			if (!window.scrollX) {
				window.scroll(0, 10);
			}
			// Scroll to Top of the Page
			window.scroll(0, 0);
		} else {
			// Display in an alert box
			errorString = "";
			for (i=0; i<errorsTabbed.length; i++) {
				if (errorsTabbed[i]) {
					errorString += errorsTabbed[i] + "\n";
				}
			}
			alert(errorString);
		}
		return false;
	} else {
		return true;
	}
}

function showError(element, isError) {
       	label = document.getElementById(element.name + "_label");
	if (label) {
		labelClass = (isError) ? "error" : "";
		label.className = labelClass;
	}
}

function validate(element) {
	if (element.type == 'NodeList') {
		for (subElt in element) {
			validate(subElt);
		}
	} else if (element) {
		if (element.req && isEmpty(element)) {
			addToErrors(element, 'Please enter a value for the "' + element.pname + '" field.');
			errorFields[errorFields.length] = element;
		} else if (element.checkOne && !atLeastOneChecked(element)) {
			addToErrors(element, 'Please check at least one "' + element.pname + '".');
			errorFields[errorFields.length] = element;
		} else if (element.email && element.value && !matchEmail(element)) {
			addToErrors(element, 'Please verify that the value in the "' + element.pname + '" field is a valid email address.');
			errorFields[errorFields.length] = element;
		} else if (element.phone && element.value && !matchPhone(element)) {
			addToErrors(element, 'Please verify that the value in the "' + element.pname + '" field is a valid 10-digit phone number with an area code.');
			errorFields[errorFields.length] = element;
		} else if (element.reqIfVal && element.options[element.selectedIndex].value == element.reqIfVal && element.reqOther.value == "") {
			addToErrors(element, 'If you select "' + element.reqIfName + '" for "' + element.pname + '", please fill out the "' + element.reqOther.pname + '" field as well.');
			errorFields[errorFields.length] = element;
		} else if (element.reqIfChecked && element.checked && element.reqOther.value == "") {
			addToErrors(element, 'If you select "' + element.reqIfName + '" for "' + element.pname + '", please fill out the "' + element.reqOther.pname + '" field as well.');
			errorFields[errorFields.length] = element;
		}
	}
}

function addToErrors(element, message) {
	if (errors.length == 0 && errorsTabbed.length == 0 && element.tabIndex) {
		tabbedFieldsFirst = true;
	}
	if (element.tabIndex && element.tabIndex >= 0) {
		errorsTabbed[element.tabIndex] = message;
	} else {
		errors[errors.length] = message;
	}
}

function atLeastOneChecked(element) {
	parentElt = element.parentElt;
	for (i=0; i<parentElt.length; i++) {
		if (parentElt[i].checked) {
			return true;
		}	
	}
	return false;
}

function matchEmail(element) {
	return element.value.match(/^([_A-Za-z0-9-]+)(\.[_A-Za-z0-9-]+)*@([A-Za-z0-9-]+)(\.[A-Za-z0-9-]+)*(\.[A-Za-z]{2,4})$/);
}

function matchPhone(element) {
	return element.value.match(/^\(?\d\d\d\)?(\.|-|\s*)?(\d\d\d)(\s*|\.|-)?\d\d\d\d$/);
}

function isEmpty(element) {
	if (element.type == 'text' || element.type == 'textarea') {
		if (element.value == "") {
			return true;
		}
	} else if (element.type == 'select-one') {
		if (element.options[element.selectedIndex].value == "") {
			return true;
		}
	} else {
		alert('The type of form element "' + element.name + '" (' + element.type + ') has not been accounted for yet in formValidation.js.  Please update the code.');
		return false;
	}
}

function checkCountry(country, state) {
	star = document.getElementById("stateStar");
	if (country[country.selectedIndex].value != 'US') {
		star.className = "hideMe";
		state.req = false;
		showError(state, false);
	} else {
		star.className = "required";
		state.req = true;
	}
}
