/**
 * Calls ILR.form.validation.validate() and displays the error messages on the form.
 * @namespace ILR.form
 * @module ILR.form.validation
 * @author Rebecca Younes
 */

ILR.namespace("form.validation");

ILR.form.validation.formErrorMsg = "There are errors in the form input. Please correct the errors marked in red below, and resubmit the form.";

/** 
 * @description Page-load initializations for the validation framework
 * NB This should be called directly when a new form loads via an Ajax call
 * @method init
 */
ILR.form.validation.init = function() {
	
	ILR.form.validation.hideEmptyErrorDivs();
	
};

/**
 * @description Hide empty error divs. Required by IE6 because empty divs still take up space unless
 * they're hidden. 
 * NB Call ILR.form.validation.init directly when a new form is loaded via an Ajax call, else 
 * the IE6 problem will occur on the new form.
 * @method hideEmptyErrorDivs
 */
ILR.form.validation.hideEmptyErrorDivs = function() {
	
	var errorDivs = getElementsByClassName("errorMsg", null, "div"),
		i;
	
	for (i = 0; i < errorDivs.length; i++) {
		// Make sure it's empty before hiding it
		// RY is this necessary?
		if (errorDivs[i].innerHTML == "") {
			addClass(errorDivs[i], "hidden");
		}
	}
	
};

/**
 * @description Get a unique error message specified for an element, or
 * if there is none return a standard message.
 * @method getErrorMsg
 * @param {HTMLElement} e The form element
 * @param {String} errorType The type of error on element e. Defined error types:
 * required: a required element is empty or blank
 * format: invalid format
 * filetype: invalid file type for file upload
 * @return {String} The error message
 */
ILR.form.validation.getErrorMsg = function(e, errorType) {

	var msg;
	
	// if the element is a checkbox or radio, only test the first input element
	if( e[0] && e[0].type in {radio: true, checkbox: true} ) {
		e = e[0];
	}

	switch (errorType) {
		case "required" :
			msg = ILR.form.validation.getFieldDescriptor(e, true) + " is required";
			break;
		case "format" : 
			msg = "Invalid " + ILR.form.validation.getFieldDescriptor(e, false);
			break;
		case "filetype" :
			msg = "Invalid filetype for " + ILR.form.validation.getFieldDescriptor(e, false);
			break;
	}

	return msg;	
};

/** 
 * @description This is the form submit / button click event handler. We need it as a wrapper
 * around ILR.form.validation.showErrors, because the latter is not itself an event handler,
 * being callable from within a larger event handler (as in Career Services business cards
 * app). Here we just call it and stop the default action of the event if there were errors.
 * @method verifySubmit
 * @static
 * @param {Event} event The event
 * @param {String|HTMLElement} form Form element or id
 * @return {void}
 */
ILR.form.validation.verifySubmit = function(event, form) {
	
	var hasErrors = 0;
	
	form = getElement(form);
	
	hasErrors = ILR.form.validation.showErrors(form);
	if (hasErrors) {
		stopDefaultAction(event);
	}	
};

/**
 * @description Call the validation routine and display the errors in designated divs.
 * @method showErrors
 * @static
 * @param {Event} event The event that triggered form validation
 * @param {String|HTMLElement} form The form id or element
 * @return {Number} The number of errors
 */
ILR.form.validation.showErrors = function(event, form) {
	
	var errors, 
		elName,
		el,
		errorEl,
		formErrorEl,
		errorSfx = "_errorMsg",
		numErrors = 0;

	form = getElement(form);

	// Clear any errors displayed from a previous submission attempt.
	// Caution: if there are multiple forms on the page that get shown/hidden
	// with Javascript, this function needs to be called when the form gets hidden too. 
	ILR.form.validation.clearErrors(form);
	
	errors = ILR.form.validation.validate(event, form);

	for (elName in errors) {
		
		el = form[elName];
		// Skip properties of errors that are not DOM elements
		// RY 7/30/07 Needed this when including json.js, since it adds functions to the
		// Object prototype. Yuck!! Should never do this. Look for an alternative 
		// json serializer/deserializer.
		if (el) {
			numErrors++;
			errorEl = document.getElementById(elName + errorSfx);
			if( errorEl ) {
				errorEl.innerHTML = ILR.form.validation.getErrorMsg(el, errors[elName]);
				// The divs must start out hidden rather than just empty, 
				// because in IE6 empty divs still take up space on the page.
				removeClass(errorEl, "hidden");
			}
		}
	}
	
	if (numErrors) {
		formErrorEl = document.getElementById(form.id + errorSfx);
		// Make this optional. For example, on very short forms that don't go below the
		// fold, it may seem redundant.
		if (formErrorEl) {
			formErrorEl.innerHTML = ILR.form.validation.formErrorMsg;
			removeClass(formErrorEl, "hidden");
			window.scrollToElement(formErrorEl, 20);
		}
	}
	return numErrors;

};

/**
 * @description Clear the child error divs of an element (generally either a form or a div
 * containing more than one form). Called before the form is validated, to clear errors from a previous 
 * submission attempt. Caution: if there are multiple forms on the page that get shown/hidden 
 * with Javascript, this function needs to be called when the form gets hidden too.
 * @method clearErrors
 * @static
 * @param {HTMLElement|String} el The element/id 
 * @return {void}
 */
ILR.form.validation.clearErrors = function(el) {

	var i, 
		elements = getElementsByClassName("errorMsg", getElement(el), "div");

	for (i = 0; i < elements.length; i++) {
		elements[i].innerHTML = "";
		// This class was dynamically applied if the error message was too long to
		// be accomodated in the default errorMsg width. Reset here.
		removeClass(elements[i], "longMsg-dynamic");
		// Need to hide the divs rather than just emptying their innerHTML 
		// because in IE6 empty divs still take up space on the page.
		addClass(elements[i], "hidden");
	}
};

YAHOO.util.Event.addListener(window, "load", ILR.form.validation.init);