// **************************************
// ** Form validation library
// ** Author: Youri Ginieys <yginieys@stepnet-ingenierie.com>
// ** Company: Stepnet Ing�nierie 2005
// ** Version: 1.0
// **************************************

//
// *** Returns Validation function for aClassName
// *** NB: a validation function is a function that takes an input as argument 
// *** 	   and returns true if its value is correct.
//
function getValidatorForClass(aClassName) {
	return _validators[aClassName];
}

//
// *** Register the Validation function for aClassName
// *** NB: a validation function is a function that takes an input as argument 
// *** 	   and returns true if its value is correct.
//
function setValidatorForClass(aClassName, aValidatorFunction) {
	_validators[aClassName] = aValidatorFunction;
}

function getErrorMessage(anInput, failedValidatorClasseName) {
	//alert("getErrorMessage() : "+anInput+" - "+failedValidatorClasseName+" => "+_errorMessages[errorKeyFor(anInput, failedValidatorClasseName)]);
	var result = _errorMessages[errorKeyFor(anInput, failedValidatorClasseName)];
	if(result == null) {
		result = _errorMessages[errorKeyFor(anInput)];
	}
	
	return result;
}

function setErrorMessage(errorMessage, anInput, failedValidatorClasseName) {
	//alert("setErrorMessage() : "+errorMessage+" - "+anInput+" - "+failedValidatorClasseName);
	_errorMessages[errorKeyFor(anInput, failedValidatorClasseName)] = errorMessage;
}

function errorKeyFor(anInput, failedValidatorClasseName) {
	if(anInput == null) {
		alert("errorKeyFor() : anInput cannot be null here");
	}
	var errorKey = '';
	if(anInput.form != null && anInput.form.name != null && anInput.form.name != '') {
		errorKey += (anInput.form.name+'.');
	}
	errorKey += anInput.name;
	
	if(failedValidatorClasseName != null) {
		errorKey += ('.'+failedValidatorClasseName);
	}
		
	return errorKey;
}

// *** isRegExpr[MAIL] -> isRegExpr
function getValidatorName(cssClass) {
	var result = cssClass;
	var i = cssClass.indexOf('[');
	if(i != -1) {
		result = cssClass.substring(0, i);
	}
	
	return result;
}

// *** isRegExpr[MAIL] -> MAIL
function getValidatorParams(cssClass) {
	var result = null;
	var i = cssClass.indexOf('[');
	if(i != -1) {
		result = cssClass.substring(i+1, cssClass.length-1);
	}
	
	return result;	
}

// 
// *** Check aForm's values and displays errors.
// *** Usage  <FORM onSubmit="...; return verify(this);">
//
function verify(aForm) {
	var hasErrors = false ;
	var errorMsg = '' ;
	for(var i=0; i<aForm.elements.length; ++i) {
		var input = aForm.elements[i];
		//alert("verify() 2 : "+input+" - "+input.className);
		var tmp = input.name + "Error";
		var spanError = document.getElementById(tmp);
		if(spanError != null) {
			spanError.innerHTML = '';
			spanError.style.display = "none";		
		}
		if(input.className != null) {
			var cssClassesArray = input.className.split(' ');
			for(var j=0; j<cssClassesArray.length; ++j) {			
				//alert("verify() 3 : "+cssClassesArray);	
				var cssClass = cssClassesArray[j];	
				var validator = getValidatorForClass(getValidatorName(cssClass));
				if(validator != null && !validator(input, cssClass)) {
					hasErrors = true;
					var msg = getErrorMessage(input, cssClass) ;
					if(msg == null && _debugMode) {
						msg = "Validation Failed for "+errorKeyFor(input, cssClass)+'\n';
					}
					if(msg != null) {
						if(spanError != null) {
							spanError.innerHTML = msg;
							spanError.style.display = "block";
						} else {
							errorMsg += msg+"\n";
						}
					}
					input.className += ' hasFailed';
				} 					
			}
		}		
	}
	
	if(errorMsg != '') {
		alert(errorMsg);
	}
	if(hasErrors) {
		var spanMainError = document.getElementById('main-error');
		if(spanMainError != null) {
			spanMainError.style.display='inline';
		}		
		document.location.hash = 'HdP';
	}
	
	return !hasErrors;
}

// *********************************************************************************
// *** Validators private functions. return true if input's value is correct.  *****
// *********************************************************************************
// 
// *** Check that input's value is not empty. 
function _checkMandatory(input) {
	//alert("_checkMandatory() "+input.value+" => "+(input.value != null && input.value != ''));
	return input.value != null && input.value != '' ;
}

function _checkRegExpr(input, cssClassName) {
	if(cssClassName == null || cssClassName=='') {
		alert("_checkRegExpr() : No cssClassName provided");
	}
	
	var regExpr = null;
	var regExprParam = getValidatorParams(cssClassName);
	if(regExprParam == null) {
		alert("_checkRegExpr() : No regexpr pattern provided in "+cssClassName);	
	}
	
	regExpr = REG_EXPR[regExprParam];
	if(regExpr == null) {
		try {
			regExpr = new RegExp(regExprParam);
		} catch (e) {
			alert("_checkRegExpr() : Cannot build RegExpr from "+regExprParam);	
		}		
	}
	return _generateRegexprValidator(regExpr)(input);
}

// *** Generates a Validator function that checks regexp regular expression.
// *** See _checkEmail(input)
function _generateRegexprValidator(regexp) {
	return function(input) { 
		if(!_checkMandatory(input)) {
			return true;	
		}
		
		return regexp.exec(input.value) != null ;					
	}
}

// *** This validator function check that input's value is an email (empty value is accepted)
// *** The only purpose of this function is to demonstrate the use of _generateRegexprValidator() 
function _checkEmail(input) {
	return _generateRegexprValidator(REG_EXPR.EMAIL)(input);
}


// ***********************************************************************************
// *** formValidation initialization *************************************************
// ***********************************************************************************
// This flags activates alert error messages even if they are not defined.
var _debugMode = false;
// _validator is the validator library.  Keys are cssClassName, values are validator functions.
var _validators = new Array();
// _errors is the error messages library. Keys are [[formName.]inputName].cssClassName, values are error messages
var _errorMessages = new Array();

// Regular Expression Library
var REG_EXPR = new Object();
REG_EXPR.EMAIL=/^[a-zA-Z0-9\_\-\.]+@[a-zA-Z0-9\-\.]{2,}[\.][a-zA-Z]{2,4}$/;
REG_EXPR.INTEGER=/^[+-]?\d*$/;
REG_EXPR.POSITIVE_INTEGER=/^[+]?\d*$/;
REG_EXPR.NEGATIVE_INTEGER=/^-\d*$/;
REG_EXPR.SIXCHARACTERS=/^.{6}$/;
REG_EXPR.TENCHARACTERS=/^.{10}$/;
REG_EXPR.SEVENTEENCHARACTERS=/^.{17}$/;
REG_EXPR.DATE=/^[0-9]{2}[-]{1}[0-9]{2}[-]{1}[0-9]{4}$/;
REG_EXPR.TIJDSTIP=/^[0-9]{2}[.]{1}[0-9]{2}$/;
REG_EXPR.TELEFON=/^[0-9]{10,11}$/;
REG_EXPR.POSTCODE=/^.{6,7}$/;

// Register validators
setValidatorForClass("isMandatory", _checkMandatory);
setValidatorForClass("isEmail", _generateRegexprValidator(REG_EXPR.EMAIL));
setValidatorForClass("isRegExpr", _checkRegExpr);
setValidatorForClass("isInteger", _generateRegexprValidator(REG_EXPR.INTEGER));
setValidatorForClass("isPositiveInt", _generateRegexprValidator(REG_EXPR.POSITIVE_INTEGER));
setValidatorForClass("isNegativeInt", _generateRegexprValidator(REG_EXPR.NEGATIVE_INTEGER));
setValidatorForClass("hasSixCharacters", _generateRegexprValidator(REG_EXPR.SIXCHARACTERS));
setValidatorForClass("hasTenCharacters", _generateRegexprValidator(REG_EXPR.TENCHARACTERS));
setValidatorForClass("hasSeventeenCharacters", _generateRegexprValidator(REG_EXPR.SEVENTEENCHARACTERS));
setValidatorForClass("isDate", _generateRegexprValidator(REG_EXPR.DATE));
setValidatorForClass("isTijdstip", _generateRegexprValidator(REG_EXPR.TIJDSTIP));
setValidatorForClass("isTelefon", _generateRegexprValidator(REG_EXPR.TELEFON));
setValidatorForClass("isPostcode", _generateRegexprValidator(REG_EXPR.POSTCODE));
