//---------------------------------------------------------------------------------------------			
// FORM VALIDATOR Type 1:
// Perform Validation on individual elements
// Functions use "this", they are a part of the object element.
//---------------------------------------------------------------------------------------------	
function LoadFormBehaviours() {
	// attach events for forms
	for (var i=0; i<document.forms.length; i++) {				
		f = document.forms[i];
		c = f.className;			
		
		// attach other possible form-level validators		
		switch(c) {
			case 'ValidateFormOnSubmit': case 'validateFormOnSubmit' : // this is form validator Type 2 (below)
				addEvent (f, "submit", ValidateFormOnSubmit);
				break;
		} // end switch (form className)
		
		for (var j=0; j<f.elements.length; j++) {
			el = f.elements[j];
			c2 = el.className;
			
			if (c2.lastIndexOf(" ") > 0) {
				c2s = c2.split(" ");
			}
			else {
				c2s = Array();
				c2s[0] = c2;
			}
			
			for (var k=0; k<c2s.length; k++) {
								
				switch (c2s[k]) {
					case 'ValidateEmail' : case 'validateEmail':
						addEvent (el, "blur", ValidateEmail);
						break;
					case 'SubmitOnce' : case 'submitOnce':
						addEvent (el, "click", SubmitOnce);
						break;
					case 'CheckUserDefinedDate': // search function
						addEvent (el, "focus", CheckUserDefinedDate);
						break;	
					case 'CheckPredefinedDate': // search function
						addEvent (el, "focus", CheckPredefinedDate);
						break;		
				} // end switch (form element className)
			} // end for k
		} // end for j
	} // end for i
}

//---------------------------------------------------------------------------------------------	
// FORM VALIDATOR Type 2:
// Perform Form Validation on the Form itself. 
// Search all form elements for particular classNames:
// 		ValidateNonEmptyTextField
// 		ValidateRadio
//		ValidateDateFrom
//		ValidateDateTo
// Functions include the object as the one and only parameter
			
function ValidateFormOnSubmit() {
	// a form.onsubmit event handler	
	// "this" == the form object with className ValidateFormOnSubmit
	var validated = true;			
	var dateFrom = null;
	var dateTo = null;
	
	// traverse array in reverse order 
	for (var i=this.elements.length-1; i>-1; i--) {
		// get element
		el = this.elements[i];
				
		// get element class(es)
		cls = el.className;
		if (cls.lastIndexOf(" ") > 0) {
			oCls = cls.split(" ");
		}
		else {
			oCls = Array();
			oCls.push(cls);
		}		
		// apply validation based on element class name(s)
		for (var j =0; j<oCls.length; j++) {
			valid = true;
			switch(oCls[j]) {
				
				case "ValidateNonEmptyTextField":
					valid = ValidateNonEmptyTextField(el);
					if (!valid) {
						DisplayErrorMessageBefore(el,  "* required field", "error");
					}
					break;
				case "ValidateRadioOnFormSubmit":	
					valid = ValidateRadio(el);
					if (!valid) {
						DisplayErrorMessageBefore(el, "* Please select an option", "error");
					}
					break;	
				case "ValidateDateFrom":
					dateFrom = el;
					break;
				case "ValidateDateTo":
					dateTo = el;
					break;
			} // end switch
			if (!valid) {
				// then focus on first element with an error
				this.elements[i].focus();
				validated = false;
			}
		} // end for j
	} // end for i
	// check for dates
	if (dateFrom && dateTo) {
		var datesValid = ValidateSearchFromAndToDate(dateFrom, dateTo);
	}
	return (validated && datesValid);
}
//---------------------------------------------------------------------------------------------			

// UTILITY FUNCTIONS 

//----------------------------------------------------------------------------------------------
function ChangeValue(id, value) {

// INPUT:
//		id: id of a form element
//		value: new value of the form element
// OUTPUT:
//		true - on success
//		false - on failure

	obj = document.getElementById(id);
	if (!obj) {
		return false;
	}
	else {
		obj.value = value;
		return true;
	}
}	

//----------------------------------------------------------------------------------------------	
function isNull (obj) {

	if ( (obj.value == null) || (obj.value =='') ) {				
		return true;
	}
	else {
		return false;
	}
}
//--------------------------------------------------------------------------------------------------		
function DisplayErrorMessageBefore (obj, msg, cls) {

// INPUT:
//		obj: the form object to display an error message before
//		msg: the txt of the error message
//		cls: the class of the error message
// OUTPUT:
//		none

// a similar function could be created later, DisplayErrorMessageAfter(...)

	RemoveExistingErrorMessage(obj);
					
	var oEm = document.createElement("em");
	oEm.setAttribute("class", cls);
	oEm.setAttribute("id", obj.id + "_err");
			
	var oText = document.createTextNode(msg);
	oEm.appendChild(oText);
			
	p = obj.parentNode;		
	p.insertBefore(oEm, obj);
}
//--------------------------------------------------------------------------------------------------		
function RemoveExistingErrorMessage(obj) {

// INPUT:
//		obj: a form object that may or may not already have had a error message set with DisplayErrorMessageBefore()
// OUTPUT:
//		none

	if (oSpan = document.getElementById(obj.id + "_err") ) {
		p = obj.parentNode;
		p.removeChild(oSpan);
	}
}

//--------------------------------------------------------------------------------------------------		
function SubmitOnce() {

// an internal function
// disables a submit button when it is clicked (to be called from onSubmit event handler)

	this.disabled = true;
	return true;
}
//--------------------------------------------------------------------------------------------------		
function ValidateEmail() {

// a "class" function
// "this" refers to the object that calls the function

	RemoveExistingErrorMessage(this);					
	
	if (isNull(this)) {
		DisplayErrorMessageBefore(this, "* You must enter your email address to continue", "error");
		this.focus();
		return false;
	}
	var regExEmail = /^(?:\w+\.?)*\w+@(?:\w+\.?)*\w+$/; //regEx for a valid email
	valid = regExEmail.test(this.value);
	if (!valid) {
		DisplayErrorMessageBefore(this, "You have entered an invalid email address", "error");
		this.focus();
		return false;
	}
	return true;
}
//--------------------------------------------------------------------------------------------------		
function ValidatePassword() {
	// not yet implemented	
}
//--------------------------------------------------------------------------------------------------		
function ValidateNonEmptyTextField(obj) {
// INPUT:
//		obj: a form element
// OUTPUT:
//		true: if obj value is NOT null
//		false: if obj value is null

	return !isNull(obj);
}
//--------------------------------------------------------------------------------------------------		
function ValidateRadio(obj) {
// INPUT:
//		obj: a form element
// OUTPUT:
//		false: if no radio selection made, or
//		obj.value: the value of the radio selection
	//if (!obj.length) {
	if (!obj) {
		for (var i=0; i<document.forms.length; i++) {				
			f = document.forms[i];
			for (var j=0; j<f.elements.length; j++) {
				el = f.elements[j];
				if (el.id == obj.id) {
					break;
				}
			}
		}		
		obj = f[el.name];
	}
	if (obj.length) {
		for (var i=0; i<obj.length; i++) {
			if (obj[i].checked) {
				return obj[i].value;
			}
		}
		return false;
	}
	else { // if error, by default the element is valid
		return true;
	}
}

// SEARCH-specific functions
				
//---------------------------------------------------------------------------------------------	
function ValidateSearchFromAndToDate(objFrom, objTo) {

// This function is not re-usable. It is intended to validate existing form elements, with particular names:
//	"searchDateType"
//	"FromDay", "FromMonth", "FromYear"
//	"ToDay", "ToMonth", "ToYear"

// INPUT:
//		objFrom: a form element (hidden?) that will have a valid "From" date placed in it
//		objTo: a form element that will have a valid "To" date placed in it
// OUTPUT:			
//		none
	
	var firstDate = new Date (2002, 0, 1);
	var today = new Date();	 // initialized to today		
	var fromDate = new Date(); // initialized to today
	var toDate = new Date(); // initialized to today
			
	formEl = objFrom.parentNode;
	if (formEl.tagName != 'FORM') {
		formEl = formEl.parentNode;
	}
	searchType = ValidateRadio(formEl["searchDateType"]);
	
	if (!searchType) {
		searchType = "searchDatePreset";
		formEl["searchDateType"][0].checked = true;
	}
			
	if (searchType == "searchDatePreset") {
		// then a predefined search
		// set fromDate to appropriate value
		var today = new Date();
		var preset = formEl["searchDatePreset"].value;
			
		if (preset!="past6Months" && preset!="pastYear") {
			if (preset=="all") {
				fromDate = firstDate;
			}
			else {
           		fromDate.setTime(today.getTime() + parseInt(preset)*24*60*60*1000);
       		}
		}
		if (preset=="past6Months") {
			if (fromDate.getMonth() > 5) {
				fromDate.setMonth(fromDate.getMonth() - 6);
			}
			else {
				fromDate.setMonth(fromDate.getMonth() + 6);
				fromDate.setYear(fromDate.getYear() + 1);
			}
		}
		if (preset=="pastYear") {
			fromDate.setYear(fromDate.getYear() - 1);
		}		
	}
	else {	// user-defined date range.				
		var errorMessage = "";
		fD = formEl["FromDay"].value;
		fM = formEl["FromMonth"].value;
		fY = formEl["FromYear"].value;			
		tD = formEl["ToDay"].value;
		tM = formEl["ToMonth"].value;
		tY = formEl["ToYear"].value;
		
		
		if  (  (fD==0) || (fM==0) || (fY==0) || (tD==0) || (tM==0) || (tY==0) ) {
			errEl = formEl["FromDay"];
			DisplayErrorMessageBefore(errEl, "Please enter all the required date fields", "error");
			return false;
		}
		from = new Date(fY, fM-1, fD);
		to = new Date(tY, tM-1, tD);
		errEl = formEl["FromDay"];
		RemoveExistingErrorMessage(errEl);

		if (to < from) {			
			DisplayErrorMessageBefore(errEl, "Start Date greater than end date", "error");
			return false;
		} else {
			return true;
		}
	}
}
//---------------------------------------------------------------------------------------------
function CheckUserDefinedDate() {
	// check the "user defined" radio button for the searchDateType element.
	// this is called when related form-elements are changed
	el = document.getElementsByName("searchDateType")
	el[1].checked = true;
}		
function CheckPredefinedDate() {
	// check the "pre-defined" radio button for the searchDateType element.
	// this is called when related form-elements are changed
	el = document.getElementsByName("searchDateType")
	el[0].checked = true;
}

addEvent(window,"load",LoadFormBehaviours); 
