var fV = {};

/**
 * Add an event listener to the specified element.
 */
fV.addEvent = function(el, evtType, fn, useCapture) {
	var ret;
	
	if (el.addEventListener) {
		el.addEventListener(evtType, fn, useCapture);
		return (true);
	} else if (el.attachEvent) {
		ret = el.attachEvent("on" + evtType, fn);
		return (ret);
	} else {
		el["on" + evtType] = fn;
	} // if - else
} // addEvent


/**
 * Initialise the form validation.
 */
fV.init = function() {
	var elId;
	var formField;
	
	if (!document.getElementById) return false;
	if (!document.getElementsByTagName) return false;
	if (!document.createElement) return false;
	if (!document.createTextNode) return false;
	
	for (elId in validationSet) {
		if (document.getElementById(elId)) {
			formField = document.getElementById(elId);
			
			if (!formField.form.validateSubmit) {
				fV.addEvent(formField.form, "submit", fV.checkValidSubmit, false);
				formField.form.onsubmit = fV.checkSubmit;		// Workaround for Safari
				formField.form.validateSubmit = true;
			} // if
		} // if
	} // for - in
} // init
	
	
/**
 * Validate the form on submission.
 */
fV.checkValidSubmit = function(evt) {
	var frm, form_error, field_error;
	var field, failed, errors;
	var loop_count, loop_length;
	
	frm = window.event ? window.event.srcElement : evt ? evt.target : null;
	if (!frm) return;
	
	errors = [];
	loop_length = frm.elements.length;
	
	// Validate all the form elements
	for (loop_count = 0; loop_count < loop_length; loop_count++) {
		field = frm.elements[loop_count];
		
		// Found a field to validate
		if (field.id && validationSet[field.id]) {
			failed = fV.handleValidity(field);
			
			// If the field already has an error message associated with it, delete it.
			// We could clear it, but this is a bit simpler
			field_error = document.getElementById("error_" + field.id);
			if (field_error) field_error.parentNode.removeChild(field_error);
			
			// The field failed validation
			if (failed) {
				errors.push(validationSet[field.id]["error"]);

				// Create the field error from scratch.
				field_error = document.createElement("span");
				field_error.setAttribute("id", "error_" + field.id);
				field_error.className = "field_error";
				
				// Insert the error message text
				field_error.appendChild(document.createTextNode(validationSet[field.id]["error"]));
				
				// Add the field error to the document
				insertAfter(field_error, field);
				
				// Fade in the field error
				Fat.fade_element(field_error.id, 30, 3000, "#FFFFFF", "#EEEEEE");
			} // if (failed)
		} // if (field)
	} // for
	
	// If the form already has an error message associated with it, delete it.
	form_error = document.getElementById("error_" + frm.id);
	if (form_error) form_error.parentNode.removeChild(form_error);
	
	// Create a new main error message, if required
	if (errors.length > 0) {		
		// Create the form error from scratch.
		form_error = document.createElement("div");
		form_error.setAttribute("id", "error_" + frm.id);
		form_error.className = "form_error";
		
		// Add the form error elements.
		// Heading
		heading = document.createElement("h3");
		heading.appendChild(document.createTextNode("Oops"));
		form_error.appendChild(heading);
		
		// Introductory text
		para = document.createElement("p");
		para.appendChild(document.createTextNode("There was a problem submitting the form. Please fix the following errors and resubmit:"));
		form_error.appendChild(para);
		
		// Errors list
		ul = document.createElement("ul");
		loop_length = errors.length;
		for (loop_count = 0; loop_count < loop_length; loop_count++) {
			li = document.createElement("li");
			li.appendChild(document.createTextNode(errors[loop_count]));
			ul.appendChild(li);
		} // for
		form_error.appendChild(ul);
		
		// Add the form error to the document
		frm.insertBefore(form_error, frm.firstChild);
		
		// Fade in the form error
		Fat.fade_element(form_error.id, 30, 1500, "#CCCCCC", "#FFFFFF");
	} // if (errors)
	
	// Handle the event propagation etc.
	if (errors.length > 0) {
		frm.submitAllowed = false;
		if (evt && evt.stopPropagation && evt.preventDefault) {
			evt.stopPropagation();
			evt.preventDefault();
		} // if

		if (window.event) {
			window.event.cancelBubble = true;
			window.event.returnValue = false;
			return (false);
		} // if
	} else {
		frm.submitAllowed = true;
	} // if - else
} // checkValidSubmit
	
	
/**
 * Validation check for Safari.
 */
fV.checkSubmit = function() {
	if (this.attachEvent) return (true);
	return (this.submitAllowed);
} // checkSubmit


/**
 * Validate the specified form field.
 */
fV.handleValidity = function(field) {
	var ret;
	
	if (!field.value) return (field);
	
	ret = validationSet[field.id]["regexp"];
	if (!field.value.match(ret)) {
		return (field);
	} else {
		return (null);
	} // if - else
} // handleValidity


/**
 * Clear the error message
 *
 * @param				formId				A String containing the ID of the form.
 */
fV.resetErrors = function(formId) {
	var form, error, spans;
	var span_class;
	
	form = document.getElementById(formId);
	if (form) {
		// Clear and hide the error message
		error = document.getElementById("error_" + formId);
		if (error) {
			while (error.childNodes.length > 0) {
				error.removeChild(error.firstChild);
			} // while

			error.className = error.className.replace(/form_error_show/, "");
			error.className = error.className.replace(/form_error_hide/, "");
			error.className += " form_error_hide";
		} // if

		// Clear all the field error flags
		spans = form.getElementsByTagName("span");
		loop_length = spans.length;
		for (loop_count = 0; loop_count < loop_length; loop_count++) {
			span_class = " " + spans[loop_count].className + " ";
			
			// Found an error field, so clear it.
			if (span_class.indexOf(" field_error ") >= 0) {
				while (spans[loop_count].childNodes.length > 0) {
					spans[loop_count].removeChild(spans[loop_count].firstChild);
				} // while
			} // if
		} // for
	} // if
} // resetErrors


// Add the window.load event listener
addLoadEvent(fV.init);

