DOM2Event.initRegistration(window);
window.addEventListener("load", validateInit, false);

var validateDebug = true;
var validateMsg = "";

function validateInit(event) {
	event = new DOM2Event(event, window.event, this);
    if (!document.getElementsByTagName) return;
	
    var forms = document.getElementsByTagName("form");
	
    for (i=0; i<forms.length; i++) {
		DOM2Event.initRegistration(forms[i]);
		forms[i].addEventListener("submit", validateAll, false);
    }
}

function validateAll(event) {
	event = new DOM2Event(event, window.event, this);
	var form = event.target;
	// Validate all elements that have a validate attribute for this form.
	// If an error is encountered, stop here and let the focus stay on the
	// error element.
	if (validateDebug) window.status = "Checking fields for validity...";
	var elements = form.elements;
	for (var i=0; i<elements.length; i++) {
		if (elements[i].getAttribute("validate") != null)
			if (!validate(elements[i])) {
				if (validateDebug) window.status = "Not all fields are valid.";
				event.preventDefault();
				return false;
			}
	}
	if (validateDebug) window.status = "All fields are valid.";
	common_submitOnce(event);
	return true;
}

function validate(obj) {
	validateMsg = obj.getAttribute("validate_msg");
	if (validateMsg == null) 
		validateMsg = "";
	else
		validateMsg = validateMsg.replace(/\\n/g,'\n').replace(/\\t/g,'\t');
	
	// The different validation types go here.
	var type = obj.getAttribute("validate");
	if (type == "text")
		return validateText(obj);
	if (type == "date")
		return validateDate(obj);
	if (type == "select")
		return validateSelect(obj);
	if (type == "number")
		return validateNumber(obj);
	if (type == "email")
		return validateEmail(obj);
	if (type == "telephone")
		return validateTelephone(obj);
}

function validateText(text) {
	text.value = (text.value.replace(/^\s+/,'')).replace(/\s+$/,'');
	if (text.getAttribute("validate_min")) {
		if (text.value.length < parseInt(text.getAttribute("validate_min"), 10)) {
			alert(validateMsg + "Your text cannot be shorter than " + text.getAttribute("validate_min") + " characters.\n(Your text has " + (text.getAttribute("validate_min") - text.value.length) + " too few.)");
			text.focus();
			return false;
		}
	} else {
		if (text.value == "") {
			alert(validateMsg + "You must provide a value for this field.");
			text.focus();
			return false;
		}
	}
	if (text.getAttribute("validate_max")) {
		if (text.value.length > parseInt(text.getAttribute("validate_max"), 10)) {
			alert(validateMsg + "Your text cannot be longer than " + text.getAttribute("validate_max") + " characters.\n(Your text has " + (text.value.length - text.getAttribute("validate_max")) + " too many.)");
			text.focus();
			return false;
		}
	}
	return true;
}

function validateSelect(select) {
	// TODO: We need to take account of select multiple  too.
	if (select.getAttribute("validate_min")) {
		if (select.selectedIndex < parseInt(select.getAttribute("validate_min"), 10)) {
			alert(validateMsg + "Please select a valid option.");
			select.focus();
			return false;
		}
	}
	return true;
}

function validateNumber(text) {
	text.value = (text.value.replace(/^\W+/,'')).replace(/\W+$/,'');
	
	if (text.value.search(/\D+/) >= 0) {
		alert(validateMsg + "You must provide a valid number for this field.");
		text.focus();
		return false;
	}
	
	var val = parseInt(text.value, 10);
	
	if (isNaN(val)) {
		alert(validateMsg + "You must provide a valid number for this field.");
		text.focus();
		return false;
	}
	if (text.getAttribute("validate_min")) {
		if (val < parseInt(text.getAttribute("validate_min"), 10)) {
			alert(validateMsg + "Your number cannot be less than " + text.getAttribute("validate_min") + ".");
			text.focus();
			return false;
		}
	}
	if (text.getAttribute("validate_max")) {
		if (val > parseInt(text.getAttribute("validate_max"), 10)) {
			alert(validateMsg + "Your number cannot be greater than " + text.getAttribute("validate_max") + ".");
			text.focus();
			return false;
		}
	}
	return true;
}

function validateDate(textbox) {
	// This is as long as it is so it can return a helpful message of why its not valid.
	var aDate = textbox.value.split("/");
	var day, month, year;
	var month_invalid = false;
	var max_days;
	var sError = "";
	var month_num;
	var this_date;
	
	if (aDate.length == 3) {
		day = parseInt(aDate[0], 10);
		month = aDate[1].toUpperCase();
		year = parseInt(aDate[2], 10);
		if (!isNaN(day) && !isNaN(year)) {
			if ((year > 2100) || (year < 1900))
				sError += "\nYour year (" + year + ") is invalid. (It should be 1900-2100.)";
			switch (month) {
				case "JAN": month_num = 1; max_days = 31; break;
				case "FEB": 
					month_num = 2; 
					if (new Date(year,2-1,29).getDate()==29) 
						max_days = 29;
					else 
						max_days = 28;
					break;
				case "MAR": month_num = 3; max_days = 31; break;
				case "APR": month_num = 4; max_days = 30; break;
				case "MAY": month_num = 5; max_days = 31; break;
				case "JUN": month_num = 6; max_days = 30; break;
				case "JUL": month_num = 7; max_days = 31; break;
				case "AUG": month_num = 8; max_days = 31; break;
				case "SEP": month_num = 9; max_days = 30; break;
				case "OCT": month_num = 10; max_days = 31; break;
				case "NOV": month_num = 11; max_days = 30; break;
				case "DEC": month_num = 12; max_days = 31; break;
				default: 
					month_invalid = true; 
					max_days = 31;
			}
			if ((day > max_days) || (day < 1))
				sError += "\nYour day (" + day + ") of the month is invalid. (It should be 1-31 depending on the month.)";
			if (month_invalid)
				sError += "\nYour month (" + month + ") is invalid. (It should be the first 3 letters like 'AUG'.)";
		} else {
			sError += "\nWhere each value is a valid number.";
		}
	} else {
		sError += "\n'" + textbox.value + "' is not a valid date.";
	}

	if (sError != "") {
		alert(validateMsg + "Date fields must be of the format\n\n\tdd/mmm/yyyy\n" + sError);
		textbox.focus();
		return false;
	}
	
	var this_date = new Date(year, month_num - 1, day);
	
	if (textbox.getAttribute("validate_min")) {
		var min_type = (textbox.getAttribute("validate_min").toLowerCase().replace(/^\W+/,'')).replace(/\W+$/,'')
		var min;
		var today = new Date();
		if (min_type == "tomorrow")
			min = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
		else if (min_type == "today")
			min = new Date(today.getFullYear(), today.getMonth(), today.getDate());
		else if (min_type == "yesterday")
			min = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1);
		else
			min = new Date(today.getFullYear(), today.getMonth(), today.getDate());

		if (this_date < min) {
			alert(validateMsg + "This date cannot be before " + min_type + ".");
			textbox.focus();
			return false;
		}
	}

	return true;
}

function validateEmail(text) {
	text.value = (text.value.replace(/^\s+/,'')).replace(/\s+$/,''); // strip leading and trailing whitespace

	var val = new String(text.value);

	if (((val.indexOf("@") < 0) || (val.indexOf(".") < 0)) || (val.indexOf(" ") >= 0)){
		alert(validateMsg + "This email address is not valid.");
		text.focus();
		return false;
	}
	
	return true;
}

function validateTelephone(text) {
	text.value = (text.value.replace(/^\s+/,'')).replace(/\s+$/,''); // strip leading and trailing whitespace

	var val = new String(text.value);

	if (val.search(/[^+()0-9 ]/) >= 0){
		alert(validateMsg + "This telephone number is not valid.");
		text.focus();
		return false;
	}
	
	return true;
}
