addEvent(window, "load", validate_init);

function validate_init() {
    // Find all tables with class greenbar and make them greenbar
    if (!document.getElementsByTagName) return;
    frms = document.getElementsByTagName("form");
    for (fi=0;fi<frms.length;fi++) {
		if (hasClassName(frms[fi], "validate")) frms[fi].onsubmit = function() { return validate(this); }; 
    }
}

// Generic form validation
function validate(formObj) {
	var validateMessage = "";
	var i, thisElement, required, displayname, validateType;
	// Loop through the elements of the form
	for (i = 0; i < formObj.elements.length; i++) {
		thisElement = formObj.elements[i];
		required = hasClassName( thisElement, 'required' );
		displayName = thisElement.getAttribute('title');
		if (displayName == "undefined" || displayName == "null") displayName = thisElement.name;
		
    	switch(thisElement.type) {
	     case "checkbox":
	     	if (required && !thisElement.checked) validateMessage += displayName + " must be checked.\n";
	     break;
		 
	     case "radio":
		 	// Not working at the moment because you have to consider Radio buttons as a group;
	     break;
		 
		 case "select-one":
			  if ( hasClassName( thisElement, 'notFirst' ) && thisElement.selectedIndex == 0 ) validateMessage += displayName + " must be selected.\n";
			  if ( hasClassName( thisElement, 'notZero' ) && thisElement.options[thisElement.selectedIndex].value == 0 ) validateMessage += displayName + " must be selected.\n";
	     break;
		 
		 case "select-multiple":
			// Yet to be implimented
	     break;
		 
		 case "button","submit","reset":
	     break;
		 
	     default: // text and text area
		 	if (isEmpty(thisElement.value)) {
				if (required) validateMessage += displayName + " is required.\n";
			} else {
				if ( hasClassName( thisElement, 'number' ) && isNaN(thisElement.value) ) validateMessage += displayName + " must be a number.\n";
				if ( hasClassName( thisElement, 'date' ) && !isDate(thisElement.value) ) validateMessage += displayName + " must be a date.\n";
				if ( hasClassName( thisElement, 'dateFuture' ) && !isFutureDate(thisElement.value) ) validateMessage += displayName + " must be a future date.\n";
				if ( hasClassName( thisElement, 'datePast' ) && !isPastDate(thisElement.value) ) validateMessage += displayName + " must be a past date.\n";
				if ( hasClassName( thisElement, 'email' ) && !isValidEmail(thisElement.value) ) validateMessage += displayName + " must be a valid email address.\n";
			}
	     break;
	    }
	}
	
	if (validateMessage != "") {
		alert("The following items must be addressed on this form:\n\n" + validateMessage);
		return false;
	}
}

/*===============================================================
	Helper Functions
===============================================================*/

function isEmpty (strValue) {
	return (! strValue.replace(/^(\s*)/, "", strValue));
}

/*---------------------------------------------------------------
	Date Functions
---------------------------------------------------------------*/

function isDate (strValue) {
	var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{4})$/; 
	var bits = strValue.match(datePat); 
	if (bits == null) return false;	
	day = bits[1]; month = bits[3]; year = bits[4];
	if (month < 1 || month > 12) return false;
	if (day < 1 || day > 31) return false;
	if ((month==4 || month==6 || month==9 || month==11) && day==31) return false;
	if (month==2) {
		var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
		if (day>29 || (day==29 && !isleap)) return false;
	}
	return true;  // date is valid
}

function isFutureDate (strValue) {
	var d = returnDate(strValue);
	var today = new Date();
	today.setHours(0,0,0,0);
	if (d == -1) return false;
	return (d >= today);
}

function isPastDate (strValue) {
	var d = returnDate(strValue);
	var today = new Date();
	today.setHours(0,0,0,0);
	if (d == -1) return false;
	return (d <= today);
}

function returnDate (strValue) {
	var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{4})$/;
	var bits = strValue.match(datePat);
	if (bits) {
		var d = new Date();
        d.setYear(bits[4]);
        d.setMonth(parseInt(bits[3], 10) - 1); // Because months indexed from 0
		d.setDate(parseInt(bits[1], 10));
		d.setHours(0,0,0,0);
        return d;
	} else {
		return -1;
	}
}

/*---------------------------------------------------------------
	Radio Button Functions
---------------------------------------------------------------*/
function isChecked(fieldObj) {
	var i;
	for (i = 0; i < fieldObj.length; i++) {
		if (fieldObj[i].checked) return true;
	}
	return false;
}

function numChecked(fieldObj, minRequired) {
	var actionsChecked = 0;
	var i;
	for (i = 0; i < fieldObj.length; i++) {
		if (fieldObj[i].checked) actionsChecked++;
	}
	return (actionsChecked >= minRequired);
}

/*---------------------------------------------------------------
	Email Functions
---------------------------------------------------------------*/
// Check an email address for validity. Uses a heap of regexps

function isValidEmail (emailStr) {
	var emailPat=/^(.+)@(.+)$/;
	var specialChars="\\(\\)<>@,;:\\\\\\\"\\.\\[\\]";
	var validChars="\[^\\s" + specialChars + "\]";
	var quotedUser="(\"[^\"]*\")";
	var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
	var atom=validChars + '+';
	var word="(" + atom + "|" + quotedUser + ")";
	var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
	var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
	var matchArray=emailStr.match(emailPat);
	if (matchArray==null) return false; 
	var user=matchArray[1];
	var domain=matchArray[2];
	if (user.match(userPat)==null) return false;
	var IPArray=domain.match(ipDomainPat);
	if (IPArray!=null) {
		for (var i=1;i<=4;i++) {
			if (IPArray[i]>255) return false;
		}
		return true;
	}
	var domainArray=domain.match(domainPat);
	if (domainArray==null) return false;
	var atomPat=new RegExp(atom,"g");
	var domArr=domain.match(atomPat);
	var len=domArr.length;
	if (domArr[len-1].length<2 || domArr[len-1].length>4) return false; 
	if (len<2) return false;
	return true;
}