(function($){
  $.extend($.validator.prototype,{
    loadErrors: function(errors){
      this.showErrors(errors);
      $.extend(this.submitted, this.errorMap);
    }
  });
  // Stolen from remote validator
  $.validator.addMethod('remote_compare',
    function(value, element, param){
      if ( this.optional(element) )
        return "dependency-mismatch";

      param = typeof param == "string" && {url:param} || param;

      var compare_to = (typeof param['compare_to'] === "undefined") ? true : param['compare_to'];
      delete param['compare_to'];

      var validation_method = (typeof param['validation_method'] === "undefined") ? 'remote_compare' : param['validation_method'];
      delete param['validation_method'];

      var previous = this.previousValue(element);
      if (!this.settings.messages[element.name] )
        this.settings.messages[element.name] = {};

      if ( previous.old !== value ) {
        previous.old = value;
        var validator = this;
        this.startRequest(element);
        var data = { element: element.name, value: value };
        $.ajax($.extend(true, {
          url: param,
          mode: "abort",
          port: "validate" + element.name,
          dataType: "text",
          cache: false,
          data: data,
          success: function(response) {
            var valid = false;
            if(typeof compare_to === 'object' && compare_to.constructor === Array){
              for(var i = 0;!valid && i < compare_to.length;i++){
                valid = response === compare_to[i];
              }
            }else{
              var valid = response === compare_to;
            }
            if ( valid ) {
              var submitted = validator.formSubmitted;
              validator.prepareElement(element);
              validator.formSubmitted = submitted;
              validator.successList.push(element);
              validator.showErrors();
            } else {
              var errors = {};
              var message = validator.defaultMessage( element, validation_method );
              errors[element.name] = $.isFunction(message) ? message(value) : message;
              validator.showErrors(errors);
            }
            previous.valid = valid;
            validator.stopRequest(element, valid);
          },
          error: function(response){
            1===1;
          }
        }, param));
        return "pending";
      } else if( this.pending[element.name] ) {
        return "pending";
      }
      return previous.valid;
    }
  );
  $.validator.addMethod('email_exists',
    function(value, element, param){
      param = $.extend(true,{compare_to:['pending','registered','deactivated'],validation_method:'email_exists'},(typeof param == "string" && {url:param} || param));
      return $.validator.methods.remote_compare.call(this,value, element, param);
		}
  );
  $.validator.addMethod('email_available',
    function(value, element, param){
      param = $.extend(true,{compare_to:['available','pending','deactivated'],validation_method:'email_available'},(typeof param == "string" && {url:param} || param));
      return $.validator.methods.remote_compare.call(this,value, element, param);
		}
  );
})(jQuery)

