/*-------------------------------------
Input object
-------------------------------------*/
function TextField(pEl, vForm){	
  this.pEl = pEl;
  this.pElClass = this.pEl.className; 
  this.vForm = vForm;
  this.valCase = this.pEl.className.match('val_[a-z0-9_-]*');
  this.inp = pEl.getElementsByTagName('input')[0] || pEl.getElementsByTagName('textarea')[0];
  this.invMsg = pEl.getElementsByTagName('span')[0];
  this.topInvMsg;
  this.inp.obj = this;
  this.inp.onfocus = this.setFocusClass;
  this.inp.onblur = this.validate;	   
}
	
TextField.prototype = {
 
  validate: function(){    
	 //check if this is an object or an html element
	 var obj = (this.nodeName)? this.obj : this;
	 obj.pEl.className = obj.pEl.className.replace(' focus', '');
	 var state = false;
	 
	 // validate if empty
	 state = (obj.inp.value == '')? false :  true;
	 // check other validation rules 
	 if(obj.valCase != null){
      var val = obj.valCase[0];
      var valFunc = val.match('val_[a-z_]*');
      var f = obj.vForm.valFunctions[valFunc];
      state = (!f(val, obj.inp.value))? false : true;
    }
	 if(obj.inp.value == '' && obj.pElClass.search('optional') > -1) state = true;
	 //display and hide warning msg
	 obj.vForm.invalidMsg(state, obj);
			 
	 return state;
  },
  
  setTopInvMsg: function(pWarningEl){
    this.topInvMsg = pWarningEl;
	 pWarningEl.obj = this;
  },
  
  focusInput: function(){
    this.obj.inp.focus();
  },
  
  setFocusClass: function(){
    this.obj.pEl.className += ' focus';
  }
}
/*-------------------------------------
Radiobuttons and Checkboxes object
-------------------------------------*/
function RadioCheckBoxes(pEl, vForm){
  this.pEl = pEl;
  this.vForm = vForm;
  this.cBoxes = pEl.getElementsByTagName('input');
  this.invMsg = pEl.getElementsByTagName('span')[0];
  this.topInvMsg;
  this.obj = this;
  for(var i = 0; i < this.cBoxes.length; i++){
    this.cb = this.cBoxes[i];
    this.cb.obj = this; 
	 this.cb.onclick = this.validate;
  }
 }
  
RadioCheckBoxes.prototype ={

  validate : function(){
    var obj = (this.nodeName)? this.obj : this;
    var boxArr = obj.cBoxes;
    for(var i = 0; i < boxArr.length;i++ ){
      if(boxArr[i].checked == true ){
        obj.vForm.invalidMsg(true,this.obj);
		  return true;
		  
      }
    }
	 obj.vForm.invalidMsg(false,this.obj);
  },
  
  setTopInvMsg: function(pWarningEl){
     this.topInvMsg = pWarningEl;
	  pWarningEl.obj = this;
  },
  
  focusInput: function(){
    this.obj.cBoxes[0].focus();
  }
}
/*-------------------------------------
Select object
-------------------------------------*/
function Select(pEl, vForm){
  this.pEl = pEl;
  this.vForm = vForm;
  this.select = pEl.getElementsByTagName('select')[0];
  this.invMsg = pEl.getElementsByTagName('span')[0];
  this.topInvMsg;
  this.select.obj = this;
  this.select.onchange = this.validate;	
}

Select.prototype={
  
  validate: function(){
  //check if this is an object or an html element
  var obj = (this.nodeName)? this.obj : this;
  var valid = (obj.select.selectedIndex == 0)? false: true;
  obj.vForm.invalidMsg(valid,obj);
  return valid;
  },
  
  setTopInvMsg: function(pWarningEl){
     this.topInvMsg = pWarningEl;
	  pWarningEl.obj = this;
  },
  
  focusInput: function(){
    this.obj.select.focus();
  }
}

/*-------------------------------------
init
-------------------------------------*/	

function validationForm(){
   this.enclosingTag = 'div';
   this.vForm;
   this.warningList;
	this.reqsArr= new Array();
   this.warnArray = new Object();
	this.originalSubmit;
	this.existingButton;
	this.newButton;
}

validationForm.prototype = {

  init: function(){
    var ps = document.getElementsByTagName(this.enclosingTag);
    this.warningList = document.getElementById('warningList');
    var count = 0; 	
    for(var i = 0; i < ps.length;i++){
		if(ps[i].className.search('required')!= -1 || ps[i].className.search('optional')!= -1){
		  this.reqsArr[count] = this._checkType(ps[i]);
		  count++;
      }
      if(ps[i].className.search('val_button')!= -1){   
		  var existingButton = ps[i].getElementsByTagName('input')[0];
		  if(existingButton.onclick == undefined){
		     existingButton.obj = this;
		     existingButton.onclick = this._validateAll;
		  }
		  else{
          //create new button  
	       var newButton = document.createElement('input');
         
          newButton.setAttribute('type', existingButton.type);
          newButton.setAttribute('value', existingButton.value);

          ps[i].appendChild(newButton);

          newButton.className = existingButton.className;
	       newButton.obj = this;
          newButton.onclick = this._validateAll;
		 
		    //remove original button and store the event
		    this.originalSubmit = existingButton.onclick;
		    ps[i].removeChild(existingButton);
		  }
      }
    }
	 for(var i = 0; i<this.reqsArr.length; i++){
		var newWarning = document.createElement('li');
		warningMsg = this.reqsArr[i].invMsg.innerHTML
		newWarning.appendChild(document.createTextNode(warningMsg));
		this.warningList.appendChild(newWarning);
		newWarning.style.display = "none";
		this.reqsArr[i].setTopInvMsg(newWarning);
		newWarning.onclick = this.reqsArr[i].focusInput;
	 }
  },
  
  _checkType: function(pElement){  
  	  var inp = pElement.getElementsByTagName('input')[0];
	  if(inp != null ){
	    if(inp.type == 'text')
		   return new TextField(pElement, this);
		 else if(inp.type == 'radio' || inp.type == 'checkbox')
		   return new RadioCheckBoxes(pElement, this);
	   }
		var ta = pElement.getElementsByTagName('textarea')[0];
		if(ta){ return new TextField(pElement, this); } 
		var sel =  pElement.getElementsByTagName('select')[0];
		if(sel){ return new Select(pElement, this); }
  },
   
  _validateAll: function(){
     var valid = true;
	  document.getElementById('warningList').style.display = 'none';
	  var obj = (this.nodeName)? this.obj : this;
      
	  for(var i = 0; i < obj.reqsArr.length;i++){
       var state = obj.reqsArr[i].validate(obj);
	    if(state == false || state == undefined){
	      valid = false;
	    }
     }
     if(valid == true){
       obj.originalSubmit.call();
     }
   },
	
	invalidMsg: function (valid, obj){
	  var pClass = obj.pEl.className;
	  var wIndex = pClass.search('warning');
     if(valid == false && wIndex == -1){
       obj.pEl.className += ' warning';
		 obj.topInvMsg.style.display = ''; 
	  }
     else{
		 if(valid == true && wIndex != -1){
		   var str = pClass.replace(' warning', '');
			obj.topInvMsg.style.display = 'none';
         obj.pEl.className = str;   
		 }
	  } 
   },
	
   valFunctions : {
    val_email: function(email, input){
      //var regxpObj = new RegExp("^[A-Za-z0-9\._-]+@+[a-z0-9\._-]+\.+[a-z]{2,4}$");
      var regxpObj = new RegExp("^[a-z0-9\._-]+@[A-Za-z0-9\._-]+?[\.]{1}[a-z]{2,4}$","gi");
      return regxpObj.test(input);	
   },
	
	val_number: function(length, input){
	   var regxpObj = new RegExp("(^[0-9]+$)");
      return regxpObj.test(input);
	},
	
    val_number_length: function(length, input){
      var len = length.match('[0-9]*$')[0];
      var baseExp =  "^[0-9]{?}$";
      var newExp = baseExp.replace(/[?]/,len);
      var regxpObj = new RegExp(newExp);
      return regxpObj.test(input); 
    },
  
    val_dateformat_ddmmyyyy: function(date, input){
      var regxpObj = new RegExp("(^[0-2][1-9]|^[3][0-1])(\.)([0-1][0-2])(\.)[12][0-9]{3}$");
      return regxpObj.test(input);
    },

    val_creditcard: function(creditcard, input){
      var regxpObj = new RegExp("^[0-9]{16}$");
      return regxpObj.test(input);	
    }
  }
}
window.onload = function(){
  var vf = new validationForm();
  vf.init();
  

}

