var ID_MESSAGE_BOX = "msg";
var CLASS_ERRORS   = "err";
var CLASS_NO_ERRORS   = "pass";


// validation functions should also be provided in the module script
// file, hence allowing them to be customised to each module
function isEmpty(obj){if(obj.value==""){return true;}return false;} 

var validators = [{
  fld:"ename",
  validate: [
    {func:isEmpty, msg:"your name"}  
            ]  
},{
  fld:"eenquiry",
  validate: [
    {func:isEmpty, msg:"your enquiry"}  
            ]  
}]                  
for (var i = 0; i < validators.length; i++){validators[validators[i].fld] = validators[i].validate;}

// extend the array object with two new methods
function _hasKey(str) {return(typeof this[str]!="undefined");}
function _hasValue(str){for(var i=0;i<this.length;i++){if (this[i]==str){return(i + 1);}}return false;}
Array.prototype.hasKey   = _hasKey;
Array.prototype.hasValue = _hasValue;


function formatErrors(err) {
  // build the error message
  var strMsg;
  if (err.length == 0) {
    strMsg = "All required fields have now been completed, please submit the form!";  
  }
  else {
    strError = err.join(", "); 
    var re = /,(\s[\(\)a-z0-9\s]+)$/i;
    var result = strError.replace(re, ' and$1');   
    strMsg = (result.substring(0,6) == "select") ? "Please " : "Please enter ";
    strMsg += (result + ".");        
  }
  return strMsg;
}


function FieldListener(elem, parent) { // extends EventListener
  var me = this;
  this.base = EventListener;
  this.base(elem, me);
  this._form = parent;
  this.helper;
  
  this.validator = [];
  
  this.init = function() {

    this.helper = this.elem.getAttribute('title');    

    this.register("focus", this.clear);
    //this.register("blur",  this.redisplay);
    
    //this.register('blur', this.validate);
    this.register('focus', this.clear);       

    if (validators.hasKey(this.elem.id)) {      
      this.setValidator(validators[this.elem.id]);
    }    

        
  }

  this.clear = function(evt) {
    if (me.helper == me.elem.value) {
      me.elem.value = "";  
    }
  }
  
  this.redisplay = function(evt) {
    if (me.elem.value == "") {
      me.elem.value = me.helper;  
    }  
  }
  
  this.setValidator = function(validator) {
    this.validator = validator;
    for (var i = 0; i < validator.length; i++) {
      this.validator[i].passed = false;  
    } 
  }
  
  this.clear = function() {
    if (me.elem.value == me.helper) {
        me.elem.value = "";
    }
    else {
      me.elem.select();  
    }
  }
  
  this.validate = function() {
    for(var i=0; i < me.validator.length; i++) {
      if (me.validator[i].func(me.elem)) {
        me._form.addErrors(me.validator[i].msg);       
        me.validator[i].passed = false;  
        break;
      }
      else {
        me._form.removeErrors(me.validator[i].msg);        
        me.validator[i].passed = true;  
      }
    }
  }
}
FieldListener.prototype = new EventListener;


function FormListener(elem) { // extends EventListener
  var me = this;
  this.base = EventListener;
  this.base(elem, me);
  this.fields = new Array();
  this.errors = [];
  this.messagebox = document.getElementById(ID_MESSAGE_BOX);
  
  this.init = function() {
    var elemFields = this.elem.elements, elem, handle; 
    for (var i=0;elem=elemFields.item(i++); ){
      if(elem.nodeName=="INPUT"||elem.nodeName=="TEXTAREA"){
        handle = new FieldListener(elem, this);

        handle.init();

        this.fields[this.fields.length] = handle;
      }
    }   
    // this.register('submit', this.validate);    
  }
  
  this.removeErrors = function(err) {
    if (idx = this.errors.hasValue(err)) {
      this.errors.splice((idx - 1), 1);  
      this.displayErrors();
    }  
  }
  
  this.addErrors = function(err) {
    if (! this.errors.hasValue(err)) {
      this.errors.push(err);      
      this.displayErrors();
    }
  }
  
  this.displayErrors = function() {
    this.messagebox.className = (this.errors.length > 0) ? CLASS_ERRORS : CLASS_NO_ERRORS;
    this.messagebox.firstChild.nodeValue = formatErrors(me.errors);        
  }

  /**
   * Event Handlers for FormListener
   */
  this.validate = function(evt) {
    me.errors = [];
    me.invoke(evt);        

    for(var i = 0; i < me.fields.length; i++) {
      me.fields[i].validate();
    }        
    if (me.errors.length > 0) {
      me.cancelDefault();
    }
  }
  
}
FormListener.prototype = new EventListener;

function init()
{
  if (document.getElementById) {   
    if (document.getElementsByTagName("form").length > 0) {
      var listener = new FormListener(document.getElementsByTagName("form").item(0));
      listener.init();
    }
  }  
}

addLoadEvent(init);
