var emailPattern =
/^(([^<>;()[\]\\.,;:@"]+(\.[^<>()[\]\\.,;:@"]+)*)|(".+"))@((([a-z0-9]([-a-z0-9]*[a-z0-9])?)|(#[0-9]+)|(\[((([01]?[0-9]{0,2})|(2(([0-4][0-9])|(5[0-5]))))\.){3}(([01]?[0-9]{0,2})|(2(([0-4][0-9])|(5[0-5]))))\]))\.)*(([a-z]([-a-z0-9]*[a-z0-9])?)|(#[0-9]+)|(\[((([01]?[0-9]{0,2})|(2(([0-4][0-9])|(5[0-5]))))\.){3}(([01]?[0-9]{0,2})|(2(([0-4][0-9])|(5[0-5]))))\]))$/i;

/**
 * Create a form validator.
 */
FormValidator = Class.create({
  initialize: function(form, valid_form_info, success_callback, failure_callback) {
    var do_validate = function() {
      var error_messages = FormValidator.validate($(form), valid_form_info);

      (error_messages.length > 0) ? failure_callback(error_messages) : success_callback($(form));
    };

    Event.observe(form, 'submit', function(e) {
      Event.stop(e);
      do_validate();
    });

    $(form).validate = do_validate;
  }
});

/**
 * Validate a form based on the provided criteria.
 */
FormValidator.validate = function(form, valid_form_info) {
  var error_messages = [];

  valid_form_info.each(function(check) {
    var ok = false;
    var process = true;
    if (check.conditions) {
      check.conditions.each(function(condition) {
        if (process) {
          var target = null;
          if (condition.id) { target = $(condition.id); }
          if (target) {
            switch(target.type) {
              case "checkbox":
                process = (target.checked == condition.checked);
                break;
              case "equal":
                process = (target.getValue() == condition.value);
                break;
            }
          } else {
            process = false;
          }
        }
      });
    }

    if (process) {
      switch (check.type) {
        case "any_checked":
          form.getInputs("checkbox", check.name).each(function(elem) {
            if (elem.checked) { ok = true; }
          });
          break;
        case "validate_email":
          ok = true;
        case "required_email":
          form.getInputs("text", check.name).each(function(elem) {
            var address = elem.value.strip();
            if (/\S/.test(address)) {
              ok = emailPattern.test(address);
            }
          });
          break;
        case "any_radio_selected":
          form.getInputs("radio", check.name).each(function(elem) {
            if (elem.checked) { ok = true; }
          });
          break;
        case "not_empty":
          ["text","textarea"].each(function(type) {
            form.getElements(type).each(function(elem) {
              if (elem.name == check.name) {
                ok = /\S/.test(elem.value.strip());
              }
            });
          });
          break;
      }
    }
    if (process && !ok) {
      error_messages.push(check.message);
    }
  });

  return error_messages;
};
