/*
SAMPLE USAGE:
var contactForm = new RobotForm("form")


<form id="contact_form" method="XHR" action="/robot/lib/handleform.php">

  <input type="text" name="first_name" class="required text"/>
  <input type="text" name="last_name" class="required text"/>
  <input type="text" name="zip" class="required numeric"/>
</form>

*/
var RobotForm = Class.create();

RobotForm.prototype = {
  initialize: function (form_id, options) {
    this.id = form_id;
    this.options = Object.extend({
      onSuccess: this.onSuccess,
      onSubmit: this.onSubmit,
      onFailure: this.onFailure,
      server_error_msg: "There was a server problem.",
      input_error_msg: "Please check the form for errors.",
      success_msg: "Thank you for contacting us.",
      posting_msg: "Submitting form...",
      submit_btn: "submit_btn",
      message_div: "message_div"
    }, options || {});
    //collect all form elements
    this.fields = $A($(form_id).getElementsByTagName('*')).inject([],
      function(elements, child) {
        if (Form.Element.Serializers[child.tagName.toLowerCase()])
            elements.push(Element.extend(child));
         return elements;
       });
    //register events
    Event.observe(this.options.submit_btn, "click", this.do_submit.bindAsEventListener(this));
  },
  validate: function() {
    var valid = true;
    for (var i = 0; i < this.fields.length; i++) {
      if (!this.validate_field(this.fields[i])) {
        valid = false;
      }
    }
    if (valid) {
      
    }
    else {
      alert(this.options.input_error_msg);
    }
    return valid;
  },
  onSubmit: function(obj) {
    $(obj.id).hide();
    $(obj.options.message_div).update(obj.options.posting_msg);
  },
  onSuccess: function() {
    $(this.options.message_div).update(this.options.success_msg);
  },
  onFailure: function() {
    $(this.options.error_message).show(this.options.success_msg);  
  },
  validate_field: function(f) {
    //get validation classes
    var classes = $w(f.className);
    var valid = true;
    for (var c=0; c < classes.length; c++) {
      if (typeof Validators[classes[c]] == "function") {
        if (!Validators[classes[c]](f)) {
          valid = false;
          break;
        }
      }
    }
    if (valid) {
      if (f.type == "select-one" && Prototype.Browser.IE) {
        f.up().removeClassName("invalid");
      }
      f.removeClassName("invalid");
    }
    else {
      if (f.type == "select-one" && Prototype.Browser.IE) {
        f.up().addClassName("invalid");
      }
      f.addClassName("invalid");    
    }
    return valid;
  },
  do_submit: function() {
    if (this.validate()) {
      if ($(this.id).getAttribute("method").toUpperCase() == "POST") {
        $(this.id).submit();
      }
      else {
        this.options.onSubmit(this);
        new Ajax.Request($(this.id).getAttribute("action"), {
          postBody: $(this.id).serialize(),
          method:"POST",
          onSuccess: this.options.onSuccess.bind(this),
          onFailure: this.options.onFailure.bind(this)
       
        });
      }
    }
  } 
  
}


function validateTimestamp (strValue) {
    var rgx = /(\d{4})-(\d{2})-(\d{2})/;
    return strValue.match(rgx);
}

function validateUSDate( strValue) {
  var objRegExp = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/

  //check to see if in correct format
  if(!objRegExp.test(strValue))
    return false; //doesn't match pattern, bad date
  else{
    var strSeparator = strValue.substring(2,3) 
    var arrayDate = strValue.split(strSeparator); 
    //create a lookup for months not equal to Feb.
    var arrayLookup = { '01' : 31,'03' : 31, 
                        '04' : 30,'05' : 31,
                        '06' : 30,'07' : 31,
                        '08' : 31,'09' : 30,
                        '10' : 31,'11' : 30,'12' : 31}
    var intDay = parseInt(arrayDate[1],10); 

    //check if month value and day value agree
    if(arrayLookup[arrayDate[0]] != null) {
      if(intDay <= arrayLookup[arrayDate[0]] && intDay != 0)
        return true; //found in lookup table, good date
    }
    var intMonth = parseInt(arrayDate[0],10);
    if (intMonth == 2) { 
       var intYear = parseInt(arrayDate[2]);
       if (intDay > 0 && intDay < 29) {
           return true;
       }
       else if (intDay == 29) {
         if ((intYear % 4 == 0) && (intYear % 100 != 0) || 
             (intYear % 400 == 0)) {
              // year div by 4 and ((not div by 100) or div by 400) ->ok
             return true;
         }   
       }
    }
  }  
  return false; //any other values, bad date
}



Validators = {
  isEmpty: function(f) {
    return ((f.value == null) || (f.value.length == 0));
  },
  verify: function(f) {
    var verifyField = $$("input[name=" + f.name + "-verify]")[0];
    if (f.value == verifyField.value) {
      verifyField.removeClassName("invalid");
      return true;
    }
    else {
      verifyField.addClassName("invalid");
      return false;
    }
  },
  required: function(f) {
    return !Validators.isEmpty(f);
  },
  name: function(f) {
    return Validators.isEmpty(f) ||  /^[a-zA-Z\'\s\-]+$/.test(f.value);  
  },
  alpha: function(f) {
    return Validators.isEmpty(f) ||  /^[a-zA-Z]+$/.test(f.value);  
  },
  alphanum: function(f) {
    return Validators.isEmpty(f) || !/\W/.test(f.value);
  },
  digits: function(f) {
    return Validators.isEmpty(f) || !/[^\d]/.test(f.value) ;
  },
  email: function(f) {
    return Validators.isEmpty(f) || /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(f.value);  
  },
  password: function(f) {
//    return Validators.isEmpty(f);  
  },
  email: function(f) {
    return Validators.isEmpty(f) || /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(f.value);  
  },
  phone: function(f) {
    return Validators.isEmpty(f) || /^[0-9\-\(\)]+$/.test(f.value);
  },
  us_phone: function(f) {
    return Validators.isEmpty(f) || /(\d{3}\-\d{3})\-(\d{4})$/.test(f.value);
  },
  date: function(f) {
    return Validators.isEmpty(f) || validateUSDate(f.value);
  },
  timestamp: function(f) {
    return Validators.isEmpty(f) || validateTimestamp(f.value);
  }

}




