/////////////////////////////////////////////////////////////////////////////////////
//
//  Usage: for every fields you wish to validate, you add a "validation" attribute;
//  the attributes values has then to be a commma seperated list where each element
//  is the name of a validating function part of the validator class or extended via
//  methods added to the prototype. For proper display of the error icons, 
//  the input tag must be closely enclosed by another block tag (i.e.: a div).

//  I.E.: <div>
//          <input type="text" name"my_text" validation="mandatory,numericOnly"></input>
//        </div>
//
// To trigger the validation, you create a new validator and call the validate method,
// passing it a block for which you wish to check for error.
//
////////////////////////////////////////////////////////////////////////////////////

function validator(globalErrMessageElement){
    var obj = this;
    this.numErrors = 0;
    this.globalErrorMessage = GENERIC_ERROR_MESSAGE;
    this.globalErrMessageElement = globalErrMessageElement;
    this.globalErrors = false;
    this.testFns = new Array();

    this.extend = function(fnName, fn){
	this[fnName] = fn;
    }

    this.addGlobalTestFn = function(fnName, fn){
	this.testFns.push(fnName);
	this.extend(fnName, fn);
    }

    this.parseGlobalTestFns = function(){
	var isErrors = false;
    	for(var i = 0; i < this.testFns.length; i++){
	    var tmpMessage = this[this.testFns[i]]();
    	    if(tmpMessage != true){
		isErrors = true;
		this.appendGlobalErrorMessage(tmpMessage);
	    }
    	}
	this.globalErrors = isErrors;
	return isErrors;
    }

    this.resetGlobalErrorMessage = function(){
	this.globalErrorMessage = GENERIC_ERROR_MESSAGE;
    }

    this.setGlobalErrorMessage = function(msg){
	this.globalErrorMessage = msg;
    }
   
    this.appendGlobalErrorMessage = function(msg){
	this.globalErrorMessage += msg;
    }

    this.displayGlobalErrorMessage = function(){
	this.globalErrMessageElement.innerHTML = this.globalErrorMessage;
    }

    this.hideGlobalErrorMessage = function(){
	this.globalErrMessageElement.innerHTML = "";
    }

    this.validate = function(block){
	this.cleanUp(block);
	var elementsToValidate = block.getElementsByTagName("*");
	for(var i = 0; i < elementsToValidate.length; i++){
	    var elm = elementsToValidate[i];
	    if(elm.getAttribute('validation') != undefined && elm.style.display != 'none'){
		var validateFuns = elm.getAttribute('validation').split(',');
		var passed = true;
		var msg = "";
		for(var j = 0; j < validateFuns.length && passed == true; j++){
		    var validateReturn = obj[validateFuns[j]](elm);
		    passed = validateReturn['bool'];
		    msg = validateReturn['msg'];
		}
		if(passed == false){
		    this.appendErrorMsg(elm, msg);
		}
	    }
	}
	var errorsDetected = this.numErrors > 0 || this.parseGlobalTestFns();
	if(errorsDetected){
	    this.displayGlobalErrorMessage();
	}
	return !errorsDetected;
    }

    this.cleanUp = function(block){
	this.hideGlobalErrorMessage();
	this.resetGlobalErrorMessage();
	if(this.numErrors > 0){
	    var elementsToValidate = block.getElementsByTagName("*");
	    for(var i = 0; i < elementsToValidate.length; i++){
		var elm = elementsToValidate[i];
		var elementClass = elm.getAttribute('class');
		if(elementClass == "errorIcon"){
		    var parent = elm.parentNode;
		    parent.removeChild(elm);
		}
	    }
	    this.numErrors = 0;
	}
    }
        
    this.appendErrorMsg = function(element, msg){
	this.numErrors += 1;
	var errorIcon = document.createElement("img");
	errorIcon.setAttribute('src', "/includes/templates/images/QuoteImages/question.png");
	errorIcon.setAttribute('id', 'errorIcon_' + this.numErrors);
	errorIcon.setAttribute('class', 'errorIcon');
	errorIcon.setAttribute('alt', msg);
	errorIcon.setAttribute('title', msg);
	element.parentNode.appendChild(errorIcon);
    }

    this.mandatory = function(inputElement){
	if(inputElement.value == ""){
	    return this.arrReturn(false, MANDATORY_FIELD);
	}
	else{
	    return this.arrReturn(true);
	}
    }

    this.numericOnly = function(inputElement){
	if(isNaN(inputElement.value)){
	    return this.arrReturn(false, NUMERIC_FIELD);
	}
	else{
	    return this.arrReturn(true);
	}
	  
    }

    this.selectMandatory =  function(inputElement){
	if(inputElement.options[inputElement.selectedIndex].value == ""){
	    return false;
	}
	else{
	    return true;
	}
    }

   this.notZero =  function(inputElement){
	if(parseInt(inputElement.value) == 0){
	    return this.arrReturn(false, ZERO_FIELD);
	}
	else{
	    return this.arrReturn(true);
	}
    }


    this.arrReturn =  function(bln, msg){
	var arr = new Array();
	arr['bool'] = bln;
	arr['msg'] = msg;
	return arr;
    }
        
}