IU.autoForm = (function(){

//Private Members

/**
* Mask all the inputs that are static
* Params:
* - none
* 
* Returns:
* - none
*/
function maskInputs(){
  $("#Zip").mask("99999");  
  $("#Telephone").mask("(999) 999-9999");  
  $("#Fax").mask("(999) 999-9999"); 
}

/**
* Fill all the fields in the form passed
* Params:
* - form: JQueryObject --  A form element wrapped with JQuery
* - exceptions: String -- JQuery string of ids not to be filled
* 
* Returns:
* - none
*/
function fillValues(form, exceptions){
  if (true){
    var elements = form.find(".required");
    if (exceptions && exceptions != ""){
      elements = elements.not(exceptions);
    }
    var i = 0;
    for (i in elements){
      if (elements[i].nodeName == "SELECT"){
        elements[i].selectedIndex = 1;
      }
      else{
        elements[i].value = i;
      }
    }
  }
}

  
/**
* Private custom function used to create a specific number of rows/columns
* and input elements for the vehicle information section
* Params:
* - attribs: {id : String, label: String, type: string, classes: string,
*             options: [String, String, ...], noBreak: Boolean,
*             tdOptions: {attrib: value, ....} } -- This a hash
*             with the elements that will specifiy attributes and input type.
* 
* Returns:
* - element: JQueryObj -- A TR element wrapped in JQuery with the vehicle
*            html elements appended to it.
*/
function createCustomInput(attribs){
  attribs.id = "Vehicle_" + attribs.id;
  var element = IU.createElement("td", attribs.tdOptions); 
  if (attribs.label && attribs.label != "") {
    element.append(IU.createElement("label", {"for" : attribs.id}, null,
                                    attribs.label));
    if (attribs.noBreak == null || attribs.noBreak == false){
      element.append(IU.createElement("br"));
    }
  }                                    
  switch(attribs.type){
    case "select":
      var j;
      var select = IU.createElement("select", {id : attribs.id, 
                                               name : attribs.id},
                                               attribs.classes);
      select.append(IU.createElement("option", 
                                     {value : ""}, null,
                                     "- select -"));
      for (j in attribs.options){
        select.append(IU.createElement("option", 
                                       {value : attribs.options[j]}, null,
                                       attribs.options[j]));
      };
      element.append(select);
      break;
    case "textarea":
      element.attr("colspan", "4")
      var div = IU.createElement("div");
      div.html(element.html());
      element.html("");
      div.append(IU.createElement("textarea", {id : attribs.id, 
                                               name : attribs.id},
                                               attribs.classes));
      element.append(div);
      break;
    default:
      element.append(IU.createElement("input", {id : attribs.id, 
                                                name : attribs.id,
                                                maxlength : "40",
                                                type : "text"},
                                                attribs.classes));
  };
  return element;
};

/**
* Mask the inputs for correct format.
* Params;
* - element: JQqueryObj -- DOM element containing the inputs to be masked
*/
function maskElements(element){
  element.find("input[id^=Year_]").each(function(){ $(this).mask("9999") });
  element.find("#Policy_Exp_Date").each(function(){ 
    $(this).mask("99/99/999");
  });
  element.find("input[id^=Driver_DOB_]").each(function(){ 
    $(this).mask("99/99/9999");
  });
}

/**
* Private method that creates the dinamyc parts of steps 2 and 3. 
* These steps have to do with vehicle information.
* Params:
* - number: Integer -- Number of cars selected on the form
*/
function updateVehicleInputs(number){
  
  /**
  * This is used to decides where to put the content based on if the custom
  * equipment textarea has been created or not.
  * Params:
  * - chkElement: JQueryObj -- Element to check if has been created or not. Also
  *   used to add the content before this element.
  * - element: JQueryObj -- When the content has not been created before, append
  *   to this element.
  * - addObj: JQueryObj -- The content to add.
  * 
  * Returns:
  * - none
  */
  function appendPrepend(chkElement, element, addObj){
    if (chkElement.length == 0){
      element.append(addObj);
    } 
    else{
      chkElement.parents("tr").before(addObj);
    }
  }
  
  /**
  * Encapsulation of the iteration that adds new elements for step 2
  * Params:
  * - start: Integer -- Offset number for the interations to start
  * - num: Integer -- Number of iterations to go through
  * - element: JQueryObj -- The Object where all the new DOM elements will be
  *                         appended.
  * 
  */
  function addElements(start, num, element){
    var rowTemp;
    var k;
    for (start; start < num; start++){
      rowTemp = IU.createElement("tr", null, "vehicleRow");
      k = start + 1;
      rowTemp.append(IU.createElement("td", {}, "", "Vehicle " + k));
      rowTemp.append(createCustomInput({id: "Year_" + k, label : "*Year:", 
                                        classes: "required inputElement"}));
      rowTemp.append(createCustomInput({id: "Make_Model_" + k, 
                                        label : "*Make/Model:", 
                                        classes: "required inputElement"}));
      rowTemp.append(createCustomInput({id: "Vin_" + k, label : "*Vin #:", 
                                        classes: "required inputElement"}));
      appendPrepend($("#Custom_Equipment"), element, rowTemp);
      rowTemp = IU.createElement("tr");
      rowTemp.append(IU.createElement("td"));
      rowTemp.append(createCustomInput({id: "Yearly_Milage_" + k, 
                                        label : "*Yearly Milage:", 
                                        classes: "required inputElement"}));
      rowTemp.append(createCustomInput({id: "Usage_" + k, label : "*Usage:", 
                                        classes: "required selectElement",
                                        type: "select",
                                        options: ["Pleasure", "Work over 3 mi.",
                                                  "Work less 3 mi.",
                                                  "Business"] }));
      rowTemp.append(createCustomInput({id: "Alarm_" + k, label : "*Alarm:", 
                                        classes: "required selectElement",
                                        type: "select",
                                        options: ["Yes", "No"] }));
      appendPrepend($("#Custom_Equipment"), element, rowTemp);
    }
  }
  
  /**
  * Encapsulation of the iteration that adds new elements for step 2
  * Params:
  * - start: Integer -- Offset number for the interations to start
  * - num: Integer -- Number of iterations to go through
  * - element: JQueryObj -- The Object where all the new DOM elements will be
  *                         appended.
  * 
  */
  function addElementsStep3(start, num, element){
    var rowTemp;
    var k;
    for (start; start < num; start++){
      rowTemp = IU.createElement("tr", null, "vehicleCoverageRow");
      k = start + 1;
      rowTemp.append(IU.createElement("td", {}, "", "Vehicle " + k));
      rowTemp.append(createCustomInput({id: "Comp_Collision_" + k, 
                                        classes: "required selectElement",
                                        type: "select",
                                        options: [ "$100/$100", "$100/$250",
                                          "$100/$500", "$100/$1,000",
                                          "$250/$100", "$250/$250", "$250/$500",
                                          "$250/$1,000", "$500/$100",
                                          "$500/$250", "$500/$500",
                                          "$500/$1,000", "$1,000/$100",
                                          "$1,000/$250", "$1,000/$500",
                                          "$1,000/$1,000"]
                                       }));
      rowTemp.append(createCustomInput({id: "Towing_" + k, 
                                        classes: "required selectElement",
                                        type: "select",
                                        options: ["Yes", "No"]}));
      rowTemp.append(createCustomInput({id: "Rental_Reimb_" + k, 
                                        classes: "required selectElement",
                                        type: "select",
                                        options: ["Yes", "No"]}));
      appendPrepend([], element, rowTemp);
    }
  }
  
  /**
  * Encapsulation of the iteration that removes elements
  * Params:
  * - start: Integer -- Offset number for the interations to start
  * - num: Integer -- Number of iterations to go through
  * - element: JQueryObj -- The Object where all the new DOM elements will be
  *                         appended.
  * 
  * Returns:
  * - None
  */
  function deleteElements(start, num, element){
    for (start; start > num; start--){
      $(".vehicleRow:last + tr").remove();
      $(".vehicleRow:last").remove();
    }
  }
  
  /**
  * Encapsulation of the iteration that removes elements
  * Params:
  * - start: Integer -- Offset number for the interations to start
  * - num: Integer -- Number of iterations to go through
  * - element: JQueryObj -- The Object where all the new DOM elements will be
  *                         appended.
  * 
  * Returns:
  * - None
  */
  function deleteElementsStep3(start, num, element){
    for (start; start > num; start--){
      $(".vehicleCoverageRow:last").remove();
    }
  }
  
  /**
  * This creates the text area for Custom Equipment.
  * Params:
  * - element: JQueryObj -- The element to append the new content to.
  * 
  * Returns:
  * - none
  */
  function makeCustomEquipmentBox(element){
    var rowTemp = IU.createElement("tr");
    if ($("#Custom_Equipment").length == 0){
      rowTemp.append(createCustomInput({id: "Custom_Equipment", label : 
                  "Any Custom equipment of vehicles? (if YES, give their value):", 
                  classes: "inputElement",
                  type: "textarea"}));
      element.append(rowTemp);
    }
  }
    
  var table = $("#Number_Of_Cars").parents("form").children("table");
  var nextTable = $("#stepForm_3").children("table");
  var currentElements = $(".vehicleRow");
  if (number > currentElements.length){
    addElements(currentElements.length, number, table);
    addElementsStep3(currentElements.length, number, nextTable);
    maskElements(table);
    maskElements(nextTable);
  }
  else if (number < currentElements.length){
    deleteElements(currentElements.length, number, table);
    deleteElementsStep3(currentElements.length, number, nextTable);
  }
  if ($(".vehicleRow").length > 3){
    $(".autoStep2").addClass("verticalScroll");
  }
  else {
    $(".autoStep2").removeClass("verticalScroll");
  }
//  if ($(".vehicleCoverageRow").length > 7){
//    $(".autoStep3").addClass("verticalScroll");
//  }
//  else {
//    $(".autoStep3").removeClass("verticalScroll");
//  }
  makeCustomEquipmentBox(table);
}

/**
* Private method that creates steps 4. These steps have to do with 
* Driver(s) information
* Params:
* - number: Integer -- Number of cars selected on the form
*/
function updateDriverInputs(number){

  /**
  * Encapsulation of the iteration that removes elements
  * Params:
  * - start: Integer -- Offset number for the interations to start
  * - num: Integer -- Number of iterations to go through
  * 
  * Returns:
  * - None
  */
  function deleteDriverElements(start, num){
    for (start; start > num; start--){
      $(".driverRow:last + tr").remove();
      $(".driverRow:last + tr").remove();
      $(".driverRow:last + tr").remove();
      $(".driverRow:last + tr").remove();
      $(".driverRow:last + tr").remove();
      $(".driverRow:last + tr").remove();
      $(".driverRow:last").remove();
    }
  }

  /**
  * Encapsulation of the iteration that adds new elements for step 4
  * Params:
  * - start: Integer -- Offset number for the interations to start
  * - num: Integer -- Number of iterations to go through
  * - element: JQueryObj -- The Object where all the new DOM elements will be
  *                         appended.
  * 
  */
  function addDriverElements(start, num, element){
    var rowTemp;
    var k;
    var label;
    for (start; start < num; start++){
      rowTemp = IU.createElement("tr", null, "driverRow");
      k = start + 1;
      rowTemp.append(IU.createElement("td", {colspan:"4"}, "centerColumn", "Driver " + k));
      element.append(rowTemp);
      rowTemp = IU.createElement("tr");
      label = IU.createElement("label", {}, "", "*Name:");
      rowTemp.append(IU.createElement("td", {}, "rightAlignColumn", label));
      rowTemp.append(createCustomInput({id: "Driver_Name_" + k, noBreak : true,
                                        classes: "required inputElement" }));
      label = IU.createElement("label", {}, "", "*Sex:");
      rowTemp.append(IU.createElement("td", {}, "rightAlignColumn", label));
      rowTemp.append(createCustomInput({id: "Driver_Sex_" + k, noBreak : true,
                                        classes: "required selectElement",
                                        type: "select",
                                        options: ["Male", "Female"] }));
      element.append(rowTemp);
      rowTemp = IU.createElement("tr");
      label = IU.createElement("label", {}, "", "*DL #:");
      rowTemp.append(IU.createElement("td", {}, "rightAlignColumn", label));
      rowTemp.append(createCustomInput({id: "Driver_License_" + k, noBreak : true,
                                        classes: "required inputElement"}));
      label = IU.createElement("label", {}, "", "*Marital Status:");
      rowTemp.append(IU.createElement("td", {}, "rightAlignColumn", label));
      rowTemp.append(createCustomInput({id: "Driver_Marital_Status_" + k, noBreak : true,
                                        classes: "required selectElement",
                                        type: "select",
                                        options: ["Married", "Single"] }));
      element.append(rowTemp);
      rowTemp = IU.createElement("tr");
      label = IU.createElement("label", {}, "", "*Date Of Birth:");
      rowTemp.append(IU.createElement("td", {}, "rightAlignColumn", label));
      rowTemp.append(createCustomInput({id: "Driver_DOB_" + k, noBreak : true,
                                        classes: "required inputElement"}));
      label = IU.createElement("label", {}, "", "*Driver's Education?");
      rowTemp.append(IU.createElement("td", {}, "rightAlignColumn", label));
      rowTemp.append(createCustomInput({id: "Driver_Education_" + k, noBreak : true,
                                        classes: "required selectElement",
                                        type: "select",
                                        options: ["Yes", "No"] }));
      element.append(rowTemp);
      rowTemp = IU.createElement("tr");
      label = IU.createElement("label", {}, "", "*Social Security #:");
      rowTemp.append(IU.createElement("td", {}, "rightAlignColumn", label));
      rowTemp.append(createCustomInput({id: "Driver_SS_" + k, noBreak : true,
                                        classes: "required inputElement"}));
      label = IU.createElement("label", {}, "", "*Defensive Driving:");
      rowTemp.append(IU.createElement("td", {}, "rightAlignColumn", label));
      rowTemp.append(createCustomInput({id: "Driver_Defensive_Driving_" + k, noBreak : true,
                                        classes: "required selectElement",
                                        type: "select",
                                        options: ["Yes", "No"] }));
      element.append(rowTemp);
      rowTemp = IU.createElement("tr");
      label = IU.createElement("label", {}, "", "*Years Licensed:");
      rowTemp.append(IU.createElement("td", {}, "rightAlignColumn", label));
      rowTemp.append(createCustomInput({id: "Driver_Years_Licensed_" + k, noBreak : true,
                                        classes: "required inputElement"}));
      label = IU.createElement("label", {}, "", "*Good Student:");
      rowTemp.append(IU.createElement("td", {}, "rightAlignColumn", label));
      rowTemp.append(createCustomInput({id: "Driver_Good_Student_" + k, noBreak : true,
                                        classes: "required selectElement",
                                        type: "select",
                                        options: ["Yes", "No"] }));
      element.append(rowTemp);
      rowTemp = IU.createElement("tr");
      label = IU.createElement("label", {}, "", "*Occupation:");
      rowTemp.append(IU.createElement("td", {}, "rightAlignColumn", label));
      rowTemp.append(createCustomInput({id: "Driver_Occupation_" + k, noBreak : true,
                                        classes: "required inputElement"}));
      label = IU.createElement("label", {}, "", "*SR 22 Filing?");
      rowTemp.append(IU.createElement("td", {}, "rightAlignColumn", label));
      rowTemp.append(createCustomInput({id: "Driver_SR22_" + k, noBreak : true,
                                        classes: "required selectElement",
                                        type: "select",
                                        options: ["No", "Yes"] }));
      element.append(rowTemp);
      
    }
  }

  var table = $("#Number_Of_Drivers").parents("form").children("table"); 
  var currentElements = $(".driverRow");
  if (number > currentElements.length){
    addDriverElements(currentElements.length, number, table);
  }
  else if (number < currentElements.length){
    deleteDriverElements(currentElements.length, number);
  }
  if ($(".driverRow").length > 1){
    $(".autoStep4").addClass("verticalScroll");
  }
  else {
    $(".autoStep4").removeClass("verticalScroll");
  }
}

/**
* Private method that creates steps 4. These steps have to do with 
* Accident(s) information
* Params:
* - number: Integer -- Number of cars selected on the form
* 
* Returns:
* - none
*/
function updateAccidentInputs(number){

  /**
  * Encapsulation of the iteration that removes accident/violation elements
  * Params:
  * - start: Integer -- Offset number for the interations to start
  * - num: Integer -- Number of iterations to go through
  * - element: JQueryObj -- The Object where all the new DOM elements will be
  *                         appended.
  * 
  * Returns:
  * - None
  */
  function deleteAccidentElements(start, num, element){
    for (start; start > num; start--){
      $(".accidentRow:last").remove();
    }
  }

  function addAccidentElements(start, num, element){
    var rowTemp;
    var colTemp;
    var k;
//    var label;
    var prependElm = element.find("#Convictions_Suspensions").parents("tr");
    if (element.find("td:contains('Cost ($)')").length == 0){
      rowTemp = IU.createElement("tr"); 
      rowTemp.append(IU.createElement("td", {}, "centerColumn", "Date"));
      rowTemp.append(IU.createElement("td", {}, "centerColumn", "Driver"));
      rowTemp.append(IU.createElement("td", {}, "centerColumn", "Violation"));
      rowTemp.append(IU.createElement("td", {}, "centerColumn", "Cost ($)"));
      prependElm.before(rowTemp);
    }
    for (start; start < num; start++){
      rowTemp = IU.createElement("tr", null, "accidentRow");
      k = start + 1;
      rowTemp.append(createCustomInput({id: "Accident_Violation_Date_" + k,
                                        tdOptions: {"class":"centerColumn"}, 
                                        classes: "required inputElement" }));
      rowTemp.append(createCustomInput({id: "Accident_Violation_Driver_" + k,
                                        tdOptions: {"class":"centerColumn"}, 
                                        classes: "required inputElement" }));
      rowTemp.append(createCustomInput({id: "Accident_Violation_" + k,
                                        tdOptions: {"class":"centerColumn"},
                                        classes: "required inputElement",
                                        type: "select",
                                        options: ["Speed under 20 mph",
                                                  "Speed over 20 mph",
                                                  "At fault accident",
                                                  "Non At fault accident",
                                                  "DUI",
                                                  "Reckless driving",
                                                  "Minor not listed",
                                                  "Major not listed"] }));
      rowTemp.append(createCustomInput({id: "Accident_Violation_Cost_" + k,
                                        tdOptions: {"class":"centerColumn"},
                                        classes: "required inputElement" }));
      prependElm.before(rowTemp);
    }
  }

  var table = $("#Had_Accidents").parents("form").children("table"); 
  var currentElements = $(".accidentRow");
  if (number > currentElements.length){
    addAccidentElements(currentElements.length, number, table);
    maskElements(table);
  }
  else if (number < currentElements.length){
    deleteAccidentElements(currentElements.length, number);
  }
//  if ($(".accidentRow").length > 2){
//    $(".autoStep5").addClass("verticalScroll");
//  }
//  else {
//    $(".autoStep5").removeClass("verticalScroll");
//  }
}

/**
* Bind all the DOM objects that generate some dinamic content
* Params:
* - none
* 
* Returns:
* - none
*/
function initializeOnClickEvents(){
  $("#Number_Of_Cars").change(function(){
    updateVehicleInputs(this.value);
//    fillValues($("#stepForm_2"), "#Number_Of_Cars"); 
//    fillValues($("#stepForm_3")); 
  });
  $("#Number_Of_Drivers").change(function(){
    updateDriverInputs(this.value);
//    fillValues($("#stepForm_4"), "#Number_Of_Drivers"); 
  });
  $("#Had_Accidents").change(function(){
    updateAccidentInputs(this.value);
//    fillValues($("#stepForm_5"), "#Had_Accidents"); 
  });
}

//Public Members
return {
  initialize: function(){
    maskInputs();
    initializeOnClickEvents();
//    fillValues($("#stepForm_1"), "#Age");
  }
};

})();
