var AutoForm = Class.create();
AutoForm.prototype =
{
  violation_descriptions : {
    ticket   : ['Select One', 'Defective Equipment', 'Failure to Obey Signal', 'Speeding Violation', 'Violation Not Listed'],
    accident : ['Select One', 'Vehicle Hit Vehicle', 'Vehicle Hit Pedestrian', 'Vehicle Hit Property', 'Other Vehicle Hit Yours', 'Other at Fault Accident', 'Other Not at Fault Accident'],
    claim    : ['Select One', 'Fire/Hail/Water Damage', 'Vandalism Damage', 'Vehicle Hit Animal', 'Vehicle Stolen', 'Windshield Damage', 'Claim Not Listed'],
    dui      : ['DUI/DWI']
  },
  
  initialize : function() {
    this.violations = 0;
    this.step       = $F("step");
    
    //would like to use step, but field on particular step avoids any mixups
    if($("coverage_level_error")) {
      this.initializeStep1();
    }
    
    this.initializeEvents();
  },
  
  initializeStep1 : function() {
    //vehicle information
    $("coverage_level_error").addClassName("validate-selected");

    this.onChangeCurrentlyInsured();

    //contact information
    $("first_name_error").addClassName("validate-alpha");
    $("last_name_error").addClassName("validate-alpha");
    $("address1_street1_error").addClassName("required");
    $("address1_zip_error").addClassName("validate-zip");
    $("phone1_error").addClassName("validate-phone");
    $("email1_error").addClassName("validate-email");
    $("credit_rating_error").addClassName("validate-selected");
    $("residence_status_error").addClassName("validate-selected");
    $("residence_length_in_months_error").addClassName("validate-selected");
  },
  
  initializeEvents : function() {
    
    Event.observe(document, "keypress", this.validateOnReturnKey.bindAsEventListener(this));
    Event.observe("submit", "click", this.validateFields.bindAsEventListener(this));
    
    if($("has_existing_carrier_1")) {
      $("has_existing_carrier_1").observe("click", this.onChangeCurrentlyInsured.bindAsEventListener(this));
      $("has_existing_carrier_0").observe("click", this.onChangeCurrentlyInsured.bindAsEventListener(this));
    }

    /* Load vehicle options via ajax */
    if ( $("current_vehicle_id") ) {
      var num = $F("current_vehicle_id");

      $("vehicle" + num + "_make").disabled = true;
      $("vehicle" + num + "_model").disabled = true;
      $("vehicle" + num + "_submodel").disabled = true;

      $("vehicle" + num + "_year").observe("change", this.onChangeVehicleYear.bindAsEventListener(this));
      $("vehicle" + num + "_make").observe("change", this.onChangeVehicleMake.bindAsEventListener(this));
      $("vehicle" + num + "_model").observe("change", this.onChangeVehicleModel.bindAsEventListener(this));
    }

    if ( $("violation1_description") ) {
      this.addViolationEventHandlers(1);
      this.addViolationEventHandlers(2);
      this.addViolationEventHandlers(3);
      this.addViolationEventHandlers(4);
    }

    if ( $('submit-add-violation') ) {
      $('submit-add-violation').observe('click', this.onAddViolation.bindAsEventListener(this));

      var deletes = $$('.delete-violation');
      for (var i=0; i < deletes.length; i++) {
        Event.observe(deletes[i], 'click', this.onDeleteViolation.bindAsEventListener(this));
      };
    }
  },
  
  validateFields: function(e){
    this.form_elements = $$(".validation-advice");
    var form           = new Validator(this.form_elements);
    this.is_valid      = form.isFormValid();
    
    if(!this.is_valid) Event.stop(e);
    (!this.is_valid) ? fadeIn("master_errors") : fadeOut("master_errors");
  },

  validateOnReturnKey: function(e){
    if(e.keyCode == Event.KEY_RETURN){
      this.validateFields(e);
      Event.stop(e);
    }
  },
  
  onChangeCurrentlyInsured : function() {
    if ( $("has_existing_carrier_1").checked ) {
      $$(".existing-carrier").invoke("show");
      $("existing_carrier_error").addClassName("validate-selected");
      $("policy_expires_on_error").addClassName("validate-policy");
      $("carrier_years_months_error").addClassName("validate-all-selection");
      $("has_existing_carrier_error").removeClassName("validate-one-selected");
      fadeOut("has_existing_carrier_error");
    } else {
      $$(".existing-carrier").invoke("hide");
      $("has_existing_carrier_error").addClassName("validate-one-selected");
      $("existing_carrier_error").removeClassName("validate-selected");
      $("policy_expires_on_error").removeClassName("validate-policy");
      $("carrier_years_months_error").removeClassName("validate-all-selection");
      
      $("has_existing_carrier_error").hide();
      $("existing_carrier_error").hide();
      $("policy_expires_on_error").hide();
      $("carrier_years_months_error").hide();
      
      $("existing_carrier").selectedIndex       = 0;
      $("policy_expires_mm_on").selectedIndex   = 0;
      $("policy_expires_dd_on").selectedIndex   = 0;
      $("policy_expires_yyyy_on").selectedIndex = 0;
      $("carrier_years").selectedIndex          = 0;
      $("carrier_months").selectedIndex         = 0;
    }
    //hide error msg when no radio is clicked 
    if ( $("has_existing_carrier_0").checked ) { fadeOut("has_existing_carrier_error"); }
  },

  onChangeVehicleYear : function(e) {
    var num = $F("current_vehicle_id");
    this.disableAndResetSelect("vehicle" + num + "_model");
    this.disableAndResetSelect("vehicle" + num + "_submodel");
    $("vehicle" + num + "_model_error").hide();
    $("vehicle" + num + "_submodel_error").hide();

    var el = Event.element(e);
    if (el.selectedIndex == 0) {
      this.disableAndResetSelect("vehicle" + num + "_make");
      $("vehicle" + num + "_make_error").hide();
    } else {
      this.loadVehicleOptions("vehicles_polk.php?year=" + $F("vehicle" + num + "_year"), "vehicle" + num + "_make", "Vehicle Make");
      fadeOut("vehicle" + num + "_year_error");
    }
  },

  onChangeVehicleMake : function(e) {
    var num = $F("current_vehicle_id");
    this.disableAndResetSelect("vehicle" + num + "_submodel");
    $("vehicle" + num + "_submodel_error").hide();
    $("vehicle" + num + "_model_error").hide();

    var el = Event.element(e);
    if (el.selectedIndex == 0) {
      this.disableAndResetSelect("vehicle" + num + "_model");
    } else {
      this.loadVehicleOptions("vehicles_polk.php?year=" + $F("vehicle" + num + "_year") + "&make=" + $F("vehicle" + num + "_make"), "vehicle" + num + "_model", "Vehicle Model");
      fadeOut("vehicle" + num + "_make_error");
    }
  },

  onChangeVehicleModel : function(e) {
    var num = $F("current_vehicle_id");
    
    var el = Event.element(e);
    if (el.selectedIndex == 0) {
      this.disableAndResetSelect("vehicle" + num + "_submodel");
    } else {
      fadeOut("vehicle" + num + "_model_error");
      $("vehicle" + num + "_submodel_loading").show();
      new Ajax.Request("vehicles_polk.php?year=" + $F("vehicle" + num + "_year") + "&make=" + $F("vehicle" + num + "_make") + "&model=" + $F("vehicle" + num + "_model"), {
        method: "get",
        evalJSON: true,
        onSuccess: function(transport, json) {
          var el = $("vehicle" + num + "_submodel");

          // Clear options
          while ( el.hasChildNodes() ) {
            el.removeChild( el.firstChild );
          }

          // Add first option
          json.unshift({name: "Vehicle Submodel", code: ""})

          // Add the rest of the options
          for (var i=0; i < json.length; i++) {
            var opt = document.createElement("OPTION");
            
            //dont put in vehicle submodel
            if(json[i].name == "Vehicle Submodel") {
              opt.setAttribute("value", "");
              opt.setAttribute("title",json[i].name);
            } else {
              opt.setAttribute("value",json[i].name);
              opt.setAttribute("title",json[i].name);
            }

            var text = document.createTextNode(json[i].name);
            opt.appendChild(text);
            el.appendChild(opt);
          };

          updateSelectWidth(el);
          el.disabled = false;

        }, 

        onComplete : function(transport) {
          fadeOut("vehicle" + num + "_submodel_loading");
          
          var el = $("vehicle" + num + "_submodel");

          if ( el.options.length == 2 ) {
            fadeOut("vehicle" + num + "_submodel_error");
            // el.selectedIndex = 1;
            el.options[1].selected = true;
            el.options[1].setAttribute("selected", true);
          }
        }
      });
    }
  },

  disableAndResetSelect : function(el) {
    $(el).selectedIndex = 0;
    $(el).disabled = true;
  },

  loadVehicleOptions : function(url, select_to_update, title) {

    $(select_to_update + "_loading").show();

    new Ajax.Request(url, {
      method: "get",
      evalJSON: true,
      onSuccess: function(transport, json) {
        var el = $(select_to_update);
        
        // Clear options
        while ( el.hasChildNodes() ) {
          el.removeChild( el.firstChild );
        }
        
        // Add first option
        var opt = document.createElement("OPTION");
        opt.setAttribute("value","");
        var text = document.createTextNode(title);
        opt.appendChild(text);
        el.appendChild(opt);
        
        // Add the rest of the options
        for (var i=0; i < json.length; i++) {
          var opt = document.createElement("OPTION");
          opt.setAttribute("value",json[i]);
          opt.setAttribute("title",json[i]);
          var text = document.createTextNode(json[i]);
          opt.appendChild(text);
          el.appendChild(opt);
        };
        
        updateSelectWidth(el);
        el.disabled = false;
      }, onComplete : function(transport) { $(select_to_update + "_loading").hide(); }
    });
  },
  

  addViolationEventHandlers : function(num) {
    $("violation" + num + "_type").observe("change", this.onChangeViolationType.bindAsEventListener(this));
    $("violation" + num + "_description").disabled = true;
    //setup amount paid field
    this.resetViolationAmountPaid(num);
  },

  onAddViolation : function(e) {
    if (this.violations < 4) {
      this.violations++;
      $("number_of_violations").value = this.violations;
      //add validations
      var num = this.violations;
      $("violation" + num + "_driver_id_error").addClassName("validate-selected");
      $("violation" + num + "_on_error").addClassName("validate-violation-date");
      $("violation" + num + "_type_error").addClassName("validate-selected");

      if (this.violations == 4) { $("submit-add-violation").hide(); $("submit-add-violation-disabled").show(); }
      $$(".violation").find(function(el) { return !el.visible(); }).show();
    }

    if (e) Event.stop(e);
  },

  onDeleteViolation : function(e) {
    var el  = Event.element(e);
    var num = el.id.match(/(\d)/)[1];

    // Show Add Violation button
    this.violations--;
    $("number_of_violations").value = this.violations;
    $("submit-add-violation").show();
    $("submit-add-violation-disabled").hide();

    this.deleteViolation(num);
    //hide master error if no violations
    if(this.violations == 0) { $("master_errors").hide(); }
  },

  // If the next violation is visible, we shift that violation into this violation"s
  // place and recurse on the next violation.
  // If the next violation is not visible we reset and hide this violation
  deleteViolation : function(num) {
    var next_num = 1 * num + 1; // Convert to integer and add 1

    if ( next_num <= 4 && $("violation" + next_num).visible() ) {
      this.shiftViolationUp(next_num);
      this.deleteViolation(next_num);
    } else {
      this.resetAndHideViolation(num);
    }
  },

  shiftViolationUp : function(num) {
    var dest_num = 1 * num - 1; // Convert to integer and subtract 1

    $("violation" + dest_num + "_driver_id").selectedIndex  = $("violation" + num + "_driver_id").selectedIndex;
    $("violation" + dest_num + "_mm_on").selectedIndex      = $("violation" + num + "_mm_on").selectedIndex;
    $("violation" + dest_num + "_yyyy_on").selectedIndex    = $("violation" + num + "_yyyy_on").selectedIndex;
    $("violation" + dest_num + "_type").selectedIndex       = $("violation" + num + "_type").selectedIndex;

    //if type is claim, move it up
    if($F("violation" + dest_num + "_type") == "claim") {
      $("violation" + dest_num + "_amount_paid").value = $F("violation" + num + "_amount_paid")
      $("violation" + dest_num + "_amount_paid").disabled = false;
      $("violation" + num + "_amount_paid").disabled = true;
    //reset if not claim
    } else {
      this.resetViolationAmountPaid(dest_num);
    }

    //clear out error msg if something was selected
    this.moveErrors("violation" + dest_num + "_driver_id_error", "violation" + num + "_driver_id_error");
    this.moveErrors("violation" + dest_num + "_on_error", "violation" + num + "_on_error");
    this.moveErrors("violation" + dest_num + "_type_error", "violation" + num + "_type_error");
    this.moveErrors("violation" + dest_num + "_description_error", "violation" + num + "_description_error");
    this.moveErrors("violation" + dest_num + "_amount_paid_error", "violation" + num + "_amount_paid_error");

    // Change description if type has value
    this.changeViolationDescription( dest_num, $F("violation" + dest_num + "_type") );
    $("violation" + dest_num + "_description").selectedIndex = $("violation" + num + "_description").selectedIndex;
    $("violation" + dest_num + "_description").options[$("violation" + num + "_description").selectedIndex].setAttribute("selected", true);
  },

  moveErrors : function(dest_error_el, error_el) {
    if($(error_el).visible()) {
    	$(error_el).hide();
    	$(dest_error_el).show();
    } else {
    	$(error_el).hide();
    	$(dest_error_el).hide();
    }
  },

  resetAndHideViolation : function(num) {
    $("violation" + num).hide();

    $("violation" + num + "_driver_id").selectedIndex  = 0;
    $("violation" + num + "_mm_on").selectedIndex      = 0;
    $("violation" + num + "_yyyy_on").selectedIndex    = 0;
    $("violation" + num + "_type").selectedIndex       = 0;
    this.changeViolationDescription(num, null);
    $("violation" + num + "_description").disabled     = true;

    // Clear and hide errors
    $("violation" + num + "_driver_id_error").removeClassName("validate-selected");
    $("violation" + num + "_on_error").removeClassName("validate-violation-date");
    $("violation" + num + "_type_error").removeClassName("validate-selected");
    $("violation" + num + "_description_error").removeClassName("validate-selected");
    $("violation" + num + "_driver_id_error").hide();
    $("violation" + num + "_on_error").hide();
    $("violation" + num + "_type_error").hide();
    $("violation" + num + "_description_error").hide();
    this.resetViolationAmountPaid(num);
  },

  onChangeViolationType : function(e) {
    var el             = Event.element(e);
    var num            = el.id.match(/(\d)/)[1];
    var violation_type = $F(el)

    $("violation" + num + "_description_error").hide();
    if (el.selectedIndex == 0) {
      this.changeViolationDescription(num, null);
      $("violation" + num + "_description").disabled = true
      $("violation" + num + "_description_error").removeClassName("validate-selected");
      this.resetViolationAmountPaid(num);
    } else {      
      this.changeViolationDescription(num, violation_type);
      $("violation" + num + "_description_error").addClassName("validate-selected");
      if(violation_type == "claim") {
        $("violation" + num + "_amount_paid").disabled = false;
        $("violation" + num + "_amount_paid_error").addClassName("validate-claim-amount");
      } else {
        this.resetViolationAmountPaid(num);
      }
    }
  },

  resetViolationAmountPaid : function(num) {
    $("violation" + num + "_amount_paid").disabled = true;
    $("violation" + num + "_amount_paid").value = "";
    $("violation" + num + "_amount_paid_error").removeClassName("validate-claim-amount");
    $("violation" + num + "_amount_paid_error").hide();
  },

  changeViolationDescription : function(num, violation_type) {
    var options = this.violation_descriptions[violation_type];
    if (options == null) options = ["Select One"];
    var select  = $("violation" + num + "_description");
    this.clearSelectOptions(select);
    this.addSelectOptionsFromArray(select, options);
    // updateSelectWidth(select);

    // Disable again if they re-selected the prompt option
    if ( options[0] == "Description" || ($("violation" + num + "_type").selectedIndex == 0) ) {
      select.disabled = true;
      $("violation" + num + "_description_error").removeClassName("validate-selected");
    } else {
      select.disabled = false;
      $("violation" + num + "_description_error").addClassName("validate-selected");
    }
  },

  clearSelectOptions : function(el) {
    while ( el.hasChildNodes() ) {
       el.removeChild( el.firstChild );
    }
  },

  addSelectOptionsFromArray : function(el, a) {
    for (var i=0; i < a.length; i++) {
      var opt = document.createElement("OPTION");
      if(/(select)/i.test(a[i])) {
        opt.setAttribute("value","");
      } else {
        opt.setAttribute("value",a[i]);
      }
      opt.setAttribute("title",a[i]);
      var text = document.createTextNode(a[i]);
      opt.appendChild(text);
      el.appendChild(opt);
    };
  }
}

// Polluting the global namespace since I can"t use "this" inside an ajax callback function
function updateSelectWidth(el) {
  var maxlength = 0;
  for (var i=0; i < el.options.length; i++) {
    if (maxlength < el[i].text.length ) maxlength = el[i].text.length;
  }

  el.style.width = maxlength * 10;
}

if (!(BrowserDetect.browser == "Explorer" && BrowserDetect.version < 6)) {
  FastInit.addOnLoad(function() {
    var auto_form = new AutoForm();
  });
}
