String.prototype.isValidEmail = function() { return (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/.test(this));};
var FormValidator = Class.create();
FormValidator.prototype = {
  succes: false,
  errorMsg: '',
  errorField: {},
  errorsContainer: [],
  rules: {
    notEmpty     : /(\w|\W)+/,
    validMail    : /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/,
    alphaNumeric : /(\w|\d)*/,
    numeric      : /[0-9]*/
  },
  initialize: function(form, options, callback, settings) {
    this.settings = Object.extend({
      handleAllErrors: false, //if true you should supply callback function, which takes array with all errors
      fireEvent: 'submit'     //Event, which will start the validation, without the prefix 
    }, settings || {});
    this.form = $(form);
    this.options = options;
    this.callback = callback || this.onError;
    Event.observe(form, this.settings.fireEvent, this.observer.bindAsEventListener(this));
  },
  observer: function(event) {
    this.succes = true;
    this.options.each(this.fieldsIterator.bind(this));
    if(!this.succes) {
      if(!this.settings.handleAllErrors) {
        this.callback(this.errorMsg, this.errorField);
      } else {
	    this.callback(this.errorsContainer);
	  }
      Event.stop(event);
    }
  },
  fieldsIterator: function(opt) {
    field = eval("this.form."+opt.field);
    //If the rule is function - pass the value to it, if string - test the regex from rules with this key
    if( (typeof opt.rule=='function' && !opt.rule($F(field))) || (typeof opt.rule=='string' && !this.rules[opt.rule].test($F(field))) ) {
      this.errorMsg = opt.errorMsg;
      this.errorField = field;
      this.succes = false;
      if(!this.settings.handleAllErrors) throw $break; // Handle only one first error
      else this.errorsContainer.push({'msg': this.errorMsg, 'field':this.errorField}); //collect all errors and then send them to callback 
    }
  },
  //Default error function
  onError: function(errorMsg, errorField) {
    alert(errorMsg);
    errorField.focus();
  }
};
