var aErrors = new Array();
var IE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;

// validate that the given control has a value entered
function validateRequired(oInput) {
	return (oInput.value != "");
}

function validatePhone(oInput) {
	var regExp = /^(\+\d{1,3} ?)?(\(\d{1,5}\)|\d{1,5}) ?\d{3,4}(\s|\s?-\s?)?\d{0,7}(?: (x|xtn|extn?|extension)\.? ?\d{1,5})?$/i;
	return regExp.test(oInput.value);
}

// make sure control's value is a proper email format
function validateEmail(oInput) {
	var regExp = /^\w(\.?\w)*@\w(\.?[-\w])*\.([a-z]{3}(\.[a-z]{2})?|[a-z]{2}(\.[a-z]{2})?)$/i;
	return regExp.test(oInput.value);
}

// add the error message to the DOM when validation fails
function showInvalidError(oInput, msg) {
	var inputMsg = (IE) ? oInput.message : oInput.getAttribute('message');
	var msgToShow = (inputMsg && inputMsg != "") ? inputMsg : msg;
	aErrors[aErrors.length] = msgToShow;
}

// make sure the input's value contains a specified string
// TODO: DO WE NEED A CASE SENSITIVE AND CASE INSENSITIVE VERSION OF THIS(?)
function validateContains(oInput) {
	var inputRE = (IE) ? oInput.cVal : oInput.getAttribute('cVal');
	var regExp = new RegExp(inputRE, "i");
	return regExp.test(oInput.value);
}

// make sure values in two inputs are equal to each other
function validateEqual(oInput) {
	var inputCT = (IE) ? oInput.compareTo : oInput.getAttribute('compareTo');
	return (oInput.value == document.getElementById(inputCT).value);
}

// make sure input value is between the ower and upper bounds
// TODO: MAKE A VERSION TO VALIDATE STRING RANGES(?)
function validateRange(tVal, lb, ub) {
	return (tVal <= ub && tVal >= lb);
}

function validate(oForm) {
	var isValid = true;
	
	// replace the current list of errors with a new one
	aErrors = new Array();
	
	// TODO: MAKE WORK FOR MULTIPLE VALIDATION ON SINGLE INPUT(?)
	for (var x = 0; x < oForm.elements.length; x++) {
		oInput = oForm.elements[x];
		
		var val = (IE) ? oInput.validate : oInput.getAttribute('validate');
		if (!val) {
			continue;
		} else {
			switch (val) {
				case "required":
					if(!validateRequired(oInput)) {
						if (isValid) {
							oInput.focus();
							isValid = false;
						}
						
						showInvalidError(oInput, "Required field")
					}
					break;
				case "email":
					if(!validateEmail(oInput)) {
						if (isValid) {
							oInput.focus();
							isValid = false;
						}
						
						showInvalidError(oInput, "Invalid e-mail.");
					}
					break;
				case "contains":
					if(!validateContains(oInput)) {
						if (isValid) {
							oInput.focus();
							isValid = false;
						}
						
						showInvalidError(oInput, "Field value must contain \"" +
							((IE) ? oInput.cVal : oInput.getAttribute('cVal')) + "\"");
					}
					break;
				case "equal":
					if(!validateEqual(oInput)) {
						if (isValid) {
							oInput.focus();
							isValid = false;
						}
						
						showInvalidError(oInput, "Values not equal");
					}
					break;
				case "range":
					// get the range we're looking for
					var inputRange = (IE) ? oInput.range : oInput.getAttribute('range');
					var aRange = inputRange.split(":");
					var uBound = parseFloat(aRange[0]);
					var lBound = parseFloat(aRange[1]);
					
					if(!validateRange(parseFloat(oInput.value), aRange[0], aRange[1])) {
						if (isValid) {
							oInput.focus();
							isValid = false;
						}
						
						showInvalidError(oInput, "Values must be between " + aRange[0] + " and " + aRange[1]);
					}
					break;
				case "phone":
					if(!validatePhone(oInput)) {
						if (isValid) {
							oInput.focus();
							isValid = false;
						}
						
						showInvalidError(oInput, "Invalid phone number.");
					}
					break;
				default:
					alert("Validate attribute unknown");
					break;
			}
		}
	}
	
	// if an error was found, display it on the page
	oErrUl = document.getElementById("ulErrors");
	oErrUl.innerHTML = "";
	if (!isValid) {
		// add the list of errors to the output
		for (var x = 0; x < aErrors.length; x++) {
			oErrUl.innerHTML += "<li>" + aErrors[x] + "</li>";
		}
	} else {
		// clear all error messages from the screen
		oErrU.innerHTML = "";
	}
	
	return isValid;
}
