jQuery.fn.extend({
  addError: function(message){
    return this.each(function(){
      var $input=$(this);
      var errors=$input.data("errors")||[];
      errors.push(message);
      $input.data("errors",errors);
    }).invalidate();
  },
  addValidation: function(validation){
    return this.each(function(){
      var $input=$(this);
      var validations = $input.data("validations")||[];
      validations.push(function(){validation($input)});
      $input.data("validations", validations);
    });
  },
  clearErrors: function(){
    return this.each(function(){
      $(this).data("errors",[]).data("valid", true);
    });
  },
  disable: function(){
    return this.attr("disabled",true).addClass("disabled");
  },
  enable: function(){
    return this.attr("disabled",false).removeClass("disabled");
  },
  hintify: function(){
    return this.each(function(){
      $(this).val($(this).attr("title")).addClass("hint_on");
    });
  },
  humanName: function(){
    var $input=$(this);
    var name=$("label[for='"+$input.attr('id')+"']").html();
    if(!name) name=$input.attr("name");
    return name;
  },
  invalidate: function(){
    return this.each(function(){
      $(this).data("valid", false);
    });
  },
  isValid: function(){
    var valid=true;
    this.each(function(){
      if(!$(this).data("valid")) valid=false;
    });
    return valid;
  },
  renderErrors: function(){  
    $("#errors_for_"+this.parents("form").attr("id")).html("").hide();
    var set_focus_target = null;
    return this.each(function(){
      var $input=$(this);
      var label_for_input=$("label[for='"+$input.attr("id")+"']");
      var $container=$("#errors_for_"+$input.attr("id")).hide();
      // fallback to the errors_for container for the form,
      // if none exists specifically for the input element.
      if(!$container.length) $container=$("#errors_for_"+$input.parents("form").attr("id"));
      var errors=$input.data("errors")||[];
      var valid=(errors.length==0);
//      if(!$container.length) {
//        $input.after("<ul class=\"error\" id=\"errors_for_"+$input.attr("id")+"\"></ul>");
//        $container = $("#errors_for_"+$input.attr("id")).hide();
//      }
      $container.text('');
      if(valid) {
        $input.removeClass("error");
        label_for_input.removeClass("invalid");
        label_for_input.removeClass("error");	// Added
      } else {
        label_for_input.addClass("invalid");
        label_for_input.addClass("error");		// Added
				$("#"+$input.attr("id")).addClass("error");	// Modified
		
				// ADDED FOLLOWING STATEMENTS
				if ($input.attr("type") == "password")
					$("input[id='" + $input.attr("id") + "_mock']").addClass("error");
				else if ($input.attr("id").search(/month_of_/i) == 0)
					$("label[for='" + $input.attr("id").replace('month_of_', '') + "']").addClass("error");
				else if ($input.attr("id").search(/day_of_/i) == 0)
					$("label[for='" + $input.attr("id").replace('day_of_', '') + "']").addClass("error");
				else if ($input.attr("id").search(/year_of_/i) == 0)
					$("label[for='" + $input.attr("id").replace('year_of_', '') + "']").addClass("error");
				// END OF ADDITION
					
        $container.show();
        if(set_focus_target === null) {
          set_focus_target = $input;
          $input.focus();
        }
        var list_items="";
        for(e=0;e<errors.length;e++){
          if(errors[e]!=null)
            //need to send real copy to the error display markup; name values arent readable
            var str = errors[e];
            if(str.match('password') != null)
            {
            	str = 'Please Enter a Password';
            }
            else
            if(str.match('email') != null)
            {
            	str = 'Please Enter an Email Address';
            }

            list_items+="<li>"+str+"</li>";
        }
        $container.append(list_items);
        $container.show();
      }
    });
  }, 
/*  renderErrors: function(){ alert($("#"+$input.attr("id")));
    $("#errors_for_"+this.parents("form").attr("id")).html("").hide();
    var set_focus_target = null;
    return this.each(function(){
      var $input=$(this);
      var label_for_input=$("label[for='"+$input.attr("id")+"']");
      var $container=$("#errors_for_"+$input.attr("id")).hide();
      // fallback to the errors_for container for the form,
      // if none exists specifically for the input element.
      if(!$container.length) $container=$("#errors_for_"+$input.parents("form").attr("id"));
      var errors=$input.data("errors")||[];
      var valid=(errors.length==0);
      if(!$container.length) {
        $input.after("<ul class=\"error\" id=\"errors_for_"+$input.attr("id")+"\"></ul>");
        $container = $("#errors_for_"+$input.attr("id")).hide();
      }
      if(valid) {
        $input.removeClass("invalid");
        label_for_input.removeClass("invalid");
      }
      else {
        label_for_input.addClass("invalid");
        $input.addClass("invalid");
        $container.show();
        if(set_focus_target === null) {
          set_focus_target = $input;
          $input.focus();
        }
        var list_items="";
        for(e=0;e<errors.length;e++){
          if(errors[e]!=null)
            list_items+="<li>"+errors[e]+"</li>";
        }
        $container.append(list_items);
        $container.show();
      }
    });
  }, */
  trimValue: function(){
    return this.each(function(){
      var $this=$(this);
      $this.val($this.val().toString().replace(/^\s+|\s+$/g,""));
    });
  },
  unhintify: function(){
    return $(this).val("").removeClass("hint_on");
  },
  validate: function(){
    return this.each(function(){
      var $this=$(this);
      var validations = $this.data("validations");
      $this.data("valid",true);
      $this.data("errors",[]);
      if(validations) for(v=0;v<validations.length;v++){validations[v]()}
    });
  }
});

$(function(){
  
  /**
   * An 'autoselect' field has its content selected when it
   * is clicked or gets the focus.  Only makes sense for
   * textareas, passwords and text inputs.
   */
  $("input.autoselect[type='password'],"+
    "input.autoselect[type='text'],"+
    "textarea.autoselect").click(function(){
    var $this = $(this);
    $(this).select();
  });
  $("textarea.autoselect").focus(function(){
    $(this).select();
  });

  /**
   * Hinted text shows some greyed out example text
   * or "hint" until the user changes it.  Hints will
   * return if the user leaves the field blank or
   * otherwise types the exact content of the hint.
   */
  $("input.hinted").livequery(function(){
    $(this).focus(function(){
      if($(this).attr("title")==$(this).val()){
        $(this).unhintify();
      }
    });
    $(this).blur(function(){
      if($(this).attr("title")==$(this).val() || $(this).val()==""){
        $(this).hintify();
      }
    });
  });
  $("input.hinted").each(function(){
    $(this).hintify();
  });
  $("form").submit(function(){
    $(this).find("input.hinted.hint_on").each(function(){
      $(this).unhintify();
    });
    true;
  });
  
  /**
   * All 'hidden' elements should be hidden and the hidden class marker
   * should be removed.
   */
  $(".hidden").each(function(){$(this).hide().removeClass("hidden")});

  $("input.confirmation").addValidation(function($input){
    var related_input_name = $input.attr("name").replace(/_confirmation\]$/,"]");
    var $related_input = $input.parents("form").find("input[name='"+related_input_name+"']");
    if($related_input.val() != $input.val()) {
      var reason_confirmation = $input.attr("reason_confirmation");
      if(!reason_confirmation)
        reason_confirmation = $input.humanName()+" does not match.";
      $input.addError(reason_confirmation);
    }
  });
  $("input.required,select.required,textarea.required").addValidation(function($input){
    if(!$input.val()){
      var reason_required = $input.attr("reason_required");
      if(!reason_required)
        reason_required = $input.humanName()+" is required.";
      if(reason_required == "null")
        reason_required = null;
      $input.addError(reason_required);
    }
  });
  $("input.date").addValidation(function($input){
    if($input.val()){
      var date=new Date($input.val());
      if(date.getDay()==NaN){
        $input.addError($input.humanName()+" is not a valid date.");
      }
    }
  });
  $("input,select,textarea").change(function(){ 

    if(!$(this).hasClass("nochange")) $(this).parents("form").find("input,select,textarea").filter(".invalid").trimValue().validate().renderErrors();
  });
  $("form").submit(function(event){
    var valid = $(this).find("input,select,textarea").trimValue().validate().renderErrors().isValid();
    if(!valid) event.stopPropagation();
    return valid;
  });

  /**
   * A 'remote' form is one that submits its data to the server via AJAX
   * and evaluates the javascript which comes back.
   *
   * If the form contains any elements which are 'invalid', it will not
   * submit at all.  This means that the form submit handler for client-
   * side validation must be registered prior to this submit event handler.
   */
  $("form.remote").submit(function(event){
    $form=$(this);
    if(!$form.find(".invalid").length) {
      var data={};
      $form.find("input,select,textarea").each(function(){
        var $this=$(this);
        var include=true;
        if($this.attr("type")=="checkbox" || $this.attr("type")=="radio")
          include=($this.attr("checked"));
        if(include)
          data[$this.attr("name")]=$this.val();
      });
      $submit_buttons=$form.find("input[type=submit]");
      $submit_buttons.disable();
      $.ajax({
	    type: "POST",
        url: $form.attr("action")+".js",
        data: data,
        complete: function(xhr) {
		  if(xhr.status==278) {
            window.location = xhr.getResponseHeader("Location");
          }
          else {
		    eval(xhr.responseText);
            // Start of added code - display error msgs in an alert popup
						var alertErrors = "";
						$("input,select,textarea").each(
							function() {
						    var $input=$(this);
						    var errors=$input.data("errors")||[];
						    var valid=(errors.length==0);
						    if (!valid) {
								//REVISIT:  this makes it impossible to display the same error text for two different fields
								if(alertErrors.indexOf(errors[0]) == -1) alertErrors += errors[0] + "\n"; }
							}
						);
						alert(alertErrors);
            // End of added code - display error msgs in an alert popup
          }
        },
        error: function(xhr) {
          $submit_buttons.enable();
        }
      });
    }
    event.stopPropagation();
    return false;
  });

  /**
   * An 'autofocus' field has the focus when the page
   * loads.
   */
  $("input.autofocus,select.autofocus,textarea.autofocus").focus().select();

});
