/*  Some level of validation - based on the Ajax in Practice book Chapter 6
 *	
 * 	Added Required Validator, the ability to pass in a Key attribute for feedback and also a 
 *  check on the Confirm attribute of specified and linked fields
 *--------------------------------------------------------------------------*/
 var Validator = Class.create();

/*   Base validator     */
Validator.prototype = {
  type: "all",

  initialize: function(validators) {                 
    validators[this.type] = this;
  },

  doValidate: function(input) {                               
    return "";
  },
  
  doValidate: function(input, keys) {                               
    return "";
  },

  validate: function(input, errordiv) {                       
    errorMsg = this.doValidate(input);
    errordiv.innerHTML = errorMsg;
    return (errorMsg.length == 0);
  },
  
  validate: function(input, key, errordiv) {                       
    errorMsg = this.doValidate(input, key);
    errordiv.innerHTML = errorMsg;
    return (errorMsg.length == 0);
  }
  
}

/*  Required Field Validator  */
var RequiredValidator = Class.create();
Object.extend(RequiredValidator.prototype,
              Validator.prototype);
Object.extend(RequiredValidator.prototype, {
    type: "required",                                           

     doValidate: function(input) {                            
      if (input == "" || input == null) {
        return "This field is a required field." ;
      } else {
        return "";
      }
    },
    
    doValidate: function(input, key) {                            
      if (input == "" || input == null) {
        return "The: '" + key + "' field is required.";
      } else {
        return "";
      }
    }
    
});


/*     Number validator      */
var NumberValidator = Class.create();
Object.extend(NumberValidator.prototype,
              Validator.prototype);

Object.extend(NumberValidator.prototype, {
    type: "number",                                           

     doValidate: function(input) {                            
      var numberpattern=/(^\d+$)|(^\d+\.\d+$)/;
      if (numberpattern.test(input)) {
        return "";
      } else {
        return "The value: '" + input + "' is not a number." ;
      }
    }
});



/*   Date based validator     */
var DateValidator = Class.create();                           
Object.extend(DateValidator.prototype, Validator.prototype);
Object.extend(DateValidator.prototype, {
  type: "date",

   doValidate: function(input) {
    var value = Date.parse(input);                            
    if(value <= 0) {
      return "'" + input + "' is not a date.";
    } else {
      return "";
    }
  }
});



var ValidatorFramework = Class.create();
ValidatorFramework.prototype =
{
  validators: 0,
  crossValidators: 0,                                         

  validateForm: function(form) {
    var retval = true;
    for(i = 0; i < form.length; i++) {
      currentInput = form[i];
      type = currentInput.getAttribute("valid");
      errorDivName = currentInput.getAttribute("error");
      inputKey = currentInput.getAttribute("keyname");
      if(type == null || errorDivName == null) {
        continue;
      } else {
      	if (inputKey != null){
      		valid = this.validate(type, currentInput.value, inputKey, $(errorDivName)); 
      	} else {
        	valid = this.validate(type, currentInput.value, $(errorDivName));
      	}
        if(!valid) {
          retval = false;
        }
      }
    }
    for(i = 0;                                                
        i < this.crossValidators.length; i++) {
      	this.crossValidators[i].clearErrors();
    }
    if (retval) {                                             
      for(i = 0; i < this.crossValidators.length; i++)  {
        valid = this.crossValidators[i].validate();
        if(!valid) {
          retval = false;
        }
      }
    }
    return retval;
  },

  validate: function(type, input, errordiv) {
    var validator = this.validators[type];
    if(!validator) {
      alert("No validator for type '" + type + "'.");
      return "";
    }
    return validator.validate(input, errordiv);
  },
  
  validate: function(type, input, key, errordiv) {
    var validator = this.validators[type];
    if(!validator) {
      alert("No validator for type '" + type + "'.");
      return "";
    }
    return validator.validate(input, key, errordiv);
  },

  initialize: function() {
    this.validators = new Array();
    this.crossValidators = new Array();

    new Validator(this.validators);
    new NumberValidator(this.validators);
    new DateValidator(this.validators);
    new RequiredValidator(this.validators);
  }

}

var CrossValidator = Class.create();                          
Object.extend(CrossValidator.prototype, {
    type: "none",
    crossError: 0,
    crossInputs: 0,

    initialize: function(framework,                           
                         p_crossInputs,                       
                         p_crossError) {                      
      framework.crossValidators.push(this);                   
      this.crossError = p_crossError;
      this.crossInputs = p_crossInputs;
    },

    validate: function() {
      errorMsg = this.doValidate(
        this.crossInputs);                                    
      this.crossError.innerHTML = errorMsg;
      return (errorMsg.length == 0);
    },

    clearErrors: function() {                                 
      this.crossError.innerHTML = "";
    }
});

var DateRangeCrossValidator =                                 
  Class.create();                                             
Object.extend(DateRangeCrossValidator.prototype,
              CrossValidator.prototype);
Object.extend(DateRangeCrossValidator.prototype, {

  doValidate: function(inputs) {
    var startDate = Date.parse(inputs[0].value);
    var endDate = Date.parse(inputs[1].value);
    if (startDate > endDate) {
      return "The start date cannot be after the end date.";
    } else {
      return "";
    }
  }
});
  
  var RequiredRangeCrossValidator =                                 
  Class.create();                                             
Object.extend(RequiredRangeCrossValidator.prototype,
              CrossValidator.prototype);
Object.extend(RequiredRangeCrossValidator.prototype, {

  doValidate: function(inputs) {
    var string01 = inputs[0].value;
    var string02 = inputs[1].value;
        if (string01 != string02) {
      return "The fields do not match, please enter their values again.";
    } else {
      return "";
    }
  }

});
