//Action Controller
function ActionControl(message, Action){
  this.ActionMessage = message;
  this.Action = Action;
  this.setMessage = function(msg) {
    this.ActionMessage = msg;
  }
  this.getMessage = function() {
    return this.ActionMessage;
  }
  this.setAction = function(Action) {
    this.Action = Action;
  }
  this.getAction = function() {
    return this.Action;
  }
}

//Rules
function AbstractRule(){
  this.ErrorAction = new ActionControl("Misc. Error", "bad", null);
  this.SuccessAction = new ActionControl("", "", null);
  this.setFailed = function(msg) {
    if(typeof msg == 'string'){
      this.ErrorAction.ActionMessage = msg;
    }else if(typeof msg == 'object'){
      this.ErrorAction = msg;
    }
  }
  this.setSuccess = function(msg) {
    if(typeof msg == 'string'){
      this.SuccessAction.ActionMessage = msg;
    }else if(typeof msg == 'object'){
      this.SuccessAction = msg;
    }
  }
  this.setValid = function(msg) {
    if(typeof msg == 'string'){
      this.ErrorAction.ActionMessage = msg;
    }else if(typeof msg == 'object'){
      this.ErrorAction = msg;
    }
  }
}

isEmail.prototype = new AbstractRule();
function isEmail(){
  this.ErrorMessage = "Failed to Match";
  this.Validate = function() {
    email = document.getElementById(this.ID).value;
    return (email.match(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|[A-Z]{2})$/im));
  }
}

notEmpty.prototype = new AbstractRule();
function notEmpty(){
  this.ErrorMessage = "Empty";
  this.Validate = function() {
    return (document.getElementById(this.ID).value != "");
  }
}

isChecked.prototype = new AbstractRule();
function isChecked(){
  this.ErrorMessage = "Not Checked";
  this.Validate = function() {
    return (document.getElementById(this.ID).checked != false);
  }
}

isSelected.prototype = new AbstractRule();
function isSelected(){
  this.ErrorMessage = "Not Selected";
  this.Validate = function() {
    return (document.getElementById(this.ID).selectedIndex != 0);
  }
}

isCheckedRadio.prototype = new AbstractRule();
function isCheckedRadio(){
  this.ErrorMessage = "Not Selected";
  this.Validate = function() {
    Items = document.getElementsByName(this.ID);
    for(n=0;n<Items.length;n++){
      if(Items[n].checked) return true;
    }
    return false;
  }
}

ValueMatch.prototype = new AbstractRule();
function ValueMatch(ID){
  this.ErrorMessage = "Failed to Match";
  this.ItemBID = ID;
  this.Validate = function() {
    ItemA = document.getElementById(this.ID).value;
    ItemB = document.getElementById(this.ItemBID).value;
    return (ItemA == ItemB);
  }
}

ValueMatchFields.prototype = new AbstractRule();
function ValueMatchFields(ID1,ID2){
  this.ErrorMessage = "Failed to Match";
  this.ItemID1 = ID1;
  this.ItemID2 = ID2;
  this.Validate = function() {
    ItemA = document.getElementById(this.ItemID1).value;
    ItemB = document.getElementById(this.ItemID2).value;
    return (ItemA == ItemB);
  }
}

//Controller
function FormValidationElement(ID){
  this.ID = ID;
  this.FormErrors = Array();
  this.FormSuccess = Array();
  this.Rules = Array();
  if(document.getElementById(this.ID) != null)
    this.theClass = document.getElementById(this.ID).getAttribute("class");

  this.setClass = function(theClass) {
    document.getElementById(this.ID).setAttribute("class", theClass);
  }
  this.reset = function(){
    this.FormErrors = Array();
    this.FormSuccess = Array();
  }

  this.Validate = function(){
    this.reset();
    FVEvalid = true;
    PassRules = Array();
    FailedRules = Array();
    for(Rule in this.Rules){
      with(this.Rules[Rule]){
	if(typeof Validate != 'function') continue;
	if(!Validate()){
	  FVEvalid = false;
	  //this.addError(this.Rules[Rule]);
	  FailedRules.push(this.Rules[Rule]);
	}else{
	  //this.addSuccess(this.Rules[Rule]);
	  PassRules.push(this.Rules[Rule]);
	}
      }
    }
    //Check Passed rules first!
    for(PassRule in PassRules){
      this.addSuccess(PassRules[PassRule]);
    }
    for(FailedRule in FailedRules){
      this.addError(FailedRules[FailedRule]);
    }
    return FVEvalid;
  }
  this.addError = function(Rule){
    if(typeof Rule.ErrorAction.Action == 'function') Rule.ErrorAction.Action();
    this.FormErrors.push(Rule.ErrorAction.ActionMessage);
  }
  this.addSuccess = function(Rule){
    if(typeof Rule.SuccessAction.Action == 'function') Rule.SuccessAction.Action();
    this.FormSuccess.push(Rule.SuccessAction.ActionMessage);
  }
  this.addRule = function(Rule){
    Rule.ID = this.ID;
    this.Rules.push(Rule);
  }
}