/** 
 * Functions for client-side form validation
 */

/**
 * Validate controls of the given form against their validation rules.
 * @param pForm Form to validate
 */
function validateForm(pForm) {
	var isValidated = true;	
	for(var i = 0; i < form_array.length; i+=6) {	
		var name        = form_array[i];
		var caption     = form_array[i+1];
		var validation  = form_array[i+2];
		var errorMsg    = form_array[i+3];
		var isMandatory = form_array[i+4];
		var maxLength   = form_array[i+5];
		var isMultiple  = (typeof name != "string");
		var message = null;

		var subElements = new Array();
		var subElementNames = new Array();
		if (isMultiple) {
			for(var j = 0; j < name.length; j++ ){
				subElements[j] = pForm.elements[name[j]];
				subElementNames[j] = name[j];
			}			
			message = getMessageMultiple(subElements, validation, isMandatory, errorMsg, caption);
		} 
		else {
			subElements[0] = pForm.elements[name];				
			subElementNames[0] = name;
			message = getMessage(subElements[0], validation, isMandatory, maxLength, errorMsg);
		}		
		
		for (var x = 0; x < subElementNames.length; x++) {
			if (message) {
				isValidated = false;
				if (typeof caption != "string") {
					// Build a composite caption for the mandatory message
					caption = caption.join("/");
				}
				// Replace placeholder in the generic resource messages
				message = message.replace(/\{0\}/, caption); 
				message = message.replace(/\{1\}/, maxLength); 
				writeElementError(subElementNames[x], message);
			} else {
				resetElementError(subElementNames[x]);
			}
		}
	}
	if (!isValidated) {
		writeGlobalError();
	}
	return isValidated;
}

function writeElementError(pElementName, pErrorMessage) {
	var cssPostfix = "_error";
	// Modify Element Class
	var controlElement = document.getElementById(pElementName);
	if (controlElement && controlElement.className) {
		if (controlElement.className.indexOf(cssPostfix) != controlElement.className.length - cssPostfix.length) { // endsWith
			controlElement.oldClassName = controlElement.className;
			controlElement.className += cssPostfix;
		}
	}
	// Fill Error Box
	var controlErrorBox = document.getElementById(pElementName + "_error_box")
	if (controlErrorBox) {
		controlErrorBox.innerHTML = "<div class=\"contact_reference\">" + pErrorMessage + "</div>";
	}
}

function resetElementError(pElementName) {
	var controlElement = document.getElementById(pElementName);
	// Reset Element Class
	if (controlElement && controlElement.oldClassName) {
		controlElement.className = controlElement.oldClassName;
	}
	// Clear Error Box
	var controlErrorBox = document.getElementById(pElementName + "_error_box")
	if (controlErrorBox) {
		controlErrorBox.innerHTML = "";
	}
}

function writeGlobalError() {
	// Do nothing		
}

/**
 *  Return the value of the given form element.
 *  @param pElement Element to get the value of
 */
function getValue(pElement) {
	if(!pElement){
		return null;		
	}
	var value = "";
	if (pElement.length) {
		for (var x = 0; x < pElement.length; x++) {
			if (pElement[x].checked || pElement[x].selected) {
				value += (value ? "," : "") + pElement[x].value;
				break;
			}
		}
	} else {
		value = pElement.value;
	}
	return value;
}

var JS_IDENTIFIER = "javascript:";

/**
 *  Get the validation message for the given form element.
 *  @param pElement Form element to get the message for
 *  @param pValidation Validation expression
 *  @param pIsMandatory Whether the element is mandatory
 *  @param pMaxLength Max length of the element
 *  @param pErrorMessage Custom error message
 */
function getMessage(pElement, pValidation, pIsMandatory, pMaxLength, pErrorMsg) {
	if(!pElement) {
		return null;
	}
	var message = null;
	var value = getValue(pElement);
	var emptyVal = (!value || value.length == 0);
	if (pIsMandatory && emptyVal) {
		if (pElement.options) {
			message = lang['submit_error_selection_missing'];
		} else {
			message = lang['submit_error_field_missing'];
		}
	}
	else if (pValidation.length > 0 && !emptyVal) {
		var indexJs = pValidation.indexOf(JS_IDENTIFIER);
		if (indexJs == 0) { 
			var jsMethodName = pValidation.substring(indexJs + JS_IDENTIFIER.length);		 	
			var values = new Array(value);
			eval("message = " + jsMethodName + "(values)");
		} else {
			var regExp = new RegExp(pValidation);
			var match = regExp.exec(value);
			if (!match || match[0] != value) { // Submatches are not valid
				message = pErrorMsg ? pErrorMsg : lang['submit_error_field_invalid']; 
			}
		}
	} else if (pMaxLength > 0 && value.length > pMaxLength) {
		message = lang['submit_error_field_too_long'];
	}
	return message;
}

/**
 *  Get the validation message for the given form elements.
 *  @param pElements Form elements to get the message for
 *  @param pValidationRules Validation expressions
 *  @param pIsMandatory Whether the elements are mandatory
 *  @param pErrorMessages Custom error messages
 */
function getMessageMultiple(pElements, pValidationRules, pIsMandatory, pErrorMessages, pCaptions) {
	if(!pElements) {
		return null;
	}
	var message = null;
	var values = new Array();
	var emptyVal = false;
	for (var k = 0; k < pElements.length; k++) {
		values[k] = getValue(pElements[k]);	
		if(!values[k] || values[k].length == 0)	{
			emptyVal = true;
		}
	}
	if (pIsMandatory && emptyVal) {
		message = lang['submit_error_field_missing'];
	}
	else if (typeof pValidationRules == "string") {
		// if validation expression contains javascript...
		var indexJs = pValidationRules.indexOf(JS_IDENTIFIER);
		if(indexJs > -1) { 
		 	var jsMethodName = pValidationRules.substring(indexJs + JS_IDENTIFIER.length);		 	
		 	eval("message = " + jsMethodName + "(values)");
		} 
	}
	else if (pValidationRules.length > 0) {
		for (var i = 0; i < pValidationRules.length; i++) {
			var rule = pValidationRules[i];
			if (rule.length > 0) {
				var value = values[i];
					var regExp = new RegExp(rule);
					var match = regExp.exec(value);
					if (!match || match[0] != value) { // Submatches are not valid
						message = pErrorMessages[i] ? pErrorMessages[i] : lang['submit_error_field_invalid']; 
						message = message.replace(/\{0\}/, pCaptions[i]);
						return message; 
				} 		
			}			
		}
	}
	return message;
}

/** constant regexp matching numeric expressions*/
var PATTERN_NUMERIC = /^\d*$/;

/**
 * custom validation of date fields
 * @param pValues array of values to check
 */
function validateDate(pValues){
	var message = null;
	var day = pValues[0];
	var month = pValues[1];
	var year = pValues[2];	
	var regExp = new RegExp(PATTERN_NUMERIC);		
			
	if (!regExp.test(day) || !regExp.test(month) || !regExp.test(year)) {
		message = lang['submit_error_date_invalid'];
	}
	return message;
}

/**
 * custom validation of email fields
 * @param pValues array of values to check
 */
function validateEmail(pValues){
	var message = null;
	var value = pValues[0];
	var regExp=/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/i			
	if (value && !regExp.test(value)) {
		message = lang['submit_error_email_invalid'];
	}
	return message;
}
