// setup standard UI elements
UI = {
  setupMenu: function () {
    UI.addMenuNav();
    UI.addMenuRollovers();
  },
  addMenuNav: function () {
    $('.menu').not(':first').hide();
    $('#menu_nav a:first').addClass('selected');
    $('#menu_nav a').click(function () {
      $('#menu_nav a').removeClass('selected');
      $(this).addClass('selected');
      $('.menu').hide();
      $('#' + $(this).attr('href').match(/[^#]+$/)[0]).show();
      return false;
    });
  },
  addMenuRollovers: function () {
    var t = 300;
    $('.menu_item').mouseover(function () {
      var div = $(this);
      if (div.children('img').hasClass('shown')) { return; }
      $('.menu_item img.shown').animate({marginTop: div.css('height')},t,null,function(){$(this).removeClass('shown')});
      div.children('img').addClass('shown').animate({marginTop: 0},t);
    });
  }
};

// Setup registration form
Registration = {
  emailRegex: (/^[^@]+@[^@]+$/),
  registrationForm: '#registration',
  errorMessageDiv: '#errors_on_page',
  errors: [],

  // return false & trigger UI action if form not valid
  // @param {Boolean} onlyZIP - pass in true if only validating the ZIP field (eg, on blur)
  validate: function (onlyZIP) {
    this.resetErrors();
    form = $(this.registrationForm);
    var message, i, field, requiredFields;
    
    var hasErrors = function (customErrorDiv) {
      if (Registration.errors.length > 0) {
        Registration.displayErrors(customErrorDiv);
        return true;
      }
    };

    if (!onlyZIP) {
      // 1. Require all user information first (account & delivery)
      requiredFields = $("#account_information .required, #delivery_information .required");
      for (i=0; i<requiredFields.length; i++) {
        message = "cannot be blank";
        field = $(requiredFields[i]);
        if (field.val() == "") {
          this.errors.push({name: field.attr('name'), message: message});
        }
      }
    }
    
    // 2. Make sure the user entered a 5-digit ZIP
    field = $('#delivery_zip');
    if (field.val().replace(/[^0-9]/g, '').length != 5) {
      this.errors.push({name: field.attr('name'), message: "must be 5 digits long."});
    }

    if (hasErrors()) return false;
    
    // 3. If user's ZIP code not in accepted list, no point in filling out the form...
    field = $('#delivery_zip');
    if ($.inArray(field.val(), Registration.validZips) < 0) {
      this.errors.push({name: field.attr('name'), message: "is outside our current delivery area."});

      // Show the lightbox
      $("#notify_zip").val(field.val());
      $("#notify_zip_display").html(field.val());
      $("#notify_email").val($("#user_email").val());

      $.facebox($("#unavailable").show());
      
      $("#notify_of_zip").submit(function () {
        // another level of email validation
        var field = $('#notify_email');
        if (!Registration.emailRegex.test(field.val())) {
          Registration.resetErrors();
          Registration.errors.push({name: field.attr('name'), message: "is not a valid email address."});
          if (hasErrors($("#errors_on_lightbox"))) return false;
        }
        
        $.post("/signup_log?" + $("#notify_of_zip").serialize(), null, function(){
          $.facebox($("#notify_confirmation").show());
          $(document).bind('close.facebox', 
            function() { window.location = window.location; })
        });
        return false;
      });

    }

    if (hasErrors()) return false;
    
    if (onlyZIP) {
      Registration.populateDummyZip();
      return true;
    }
    
    Registration.putWidgetDateInForm();

    // 4. Other required fields must not be blank
    requiredFields = $("#"+form.attr('id')+' .required').not("#account_information .required, #delivery_information .required");
    for (i=0; i<requiredFields.length; i++) {
      message = "cannot be blank";
      field = $(requiredFields[i]);
      if (field.val() == "") {
        this.errors.push({name: field.attr('name'), message: message});
      }
    }
    
    if($("#billing_credit_card_type").val() == "83"){
      // Amex
      if($("#billing_credit_card_number").val().length != 15){
        this.errors.push({name: "billing[credit_card_number]", message: "has the wrong number of digits."});
      }
    } else {
      if($("#billing_credit_card_number").val().length != 16){
        this.errors.push({name: "billing[credit_card_number]", message: "has the wrong number of digits."});
      }
    }

    // 5. Billing address cannot be blank unless "same as shipping" is checked
    if (!$('#delivery_billing_is_same').attr('checked')) {
      var billingAddressFields = $("#billing_address input");
      for (i=0; i<billingAddressFields.length; i++) {
        message = "cannot be blank unless your billing and shipping addresses are the same";
        field = $(billingAddressFields[i]);
        if (field.val() == "" && (field.attr("id") != "billing_suite")) {
          this.errors.push({name: field.attr('name'), message: message});
        }
      }
    }
    
    // Take the start date from the widget into the form.

    
    /* Start Date...
      1. It must be in the future
      2. It cannot be <today>
      3. It cannot be a Saturday.
      4. It cannot be a Sunday.
   */

    var startDateString = [$("#start_month").val(), $("#start_day").val(), $("#start_year").val()].join("/");
    var startDate = new Date(startDateString);
    
    var today = new Date();
    var todayString = (today.getMonth() + 1) + "/" + today.getDate() + "/" + today.getFullYear();
    
    if(startDate <= today){
      this.errors.push({name : "delivery[starting_date]", message : 'must be in the future.'});
    }
    
    if(startDateString == todayString){
      this.errors.push({name : "delivery[starting_date]", message : 'cannot be today.'});
    }
    
    if( startDate.getDay() == 6 || startDate.getDay() == 0 ){
      this.errors.push({name : "delivery[starting_date]", message : 'cannot fall on the weekend.'});
    }
    
    // Expiration date must be this month or in the future
    var expDate = new Date((parseInt($("#billing_expiration_month").val().replace(/^0/, '')) + 1) + "/1/" + $("#billing_expiration_year").val());
    if(expDate <= today){
      this.errors.push({name : "billing[credit_card_expiration_date]", message : 'must be in the future.'});
    }
    
    // 4. Must accept TOS
    if (!$('#user_terms_and_conditions').attr('checked')) {
      this.errors.push({name: 'user[terms_and_conditions]', message: "must be checked."});
    }

    if (hasErrors()) return false;

    // Email format (liberal with input)
    var field = $('#user_email');
    if (!Registration.emailRegex.test(field.val())) {
      this.errors.push({name: field.attr('name'), message: "is not a valid email address."});
    }
    
    // State format:
    field = $("#delivery_state");
    if (field.val().length != 2){
      this.errors.push({name: field.attr('name'), message: "is not a valid state abbreviation."});
    }
    
    field = $("#billing_state");
    if (!$("#delivery_billing_is_same").attr("checked") && field.val().length != 2){
      this.errors.push({name: field.attr('name'), message: "is not a valid state abbreviation."});
    }
    
    var zipField = $("#billing_zip");
    if (!$("#delivery_billing_is_same").attr('checked') && zipField.val().length != 5) {
      this.errors.push({name: zipField.attr('name'), message: "must be five digits."});
    }

    // Phone format: ###-###-####
    field = $('#user_phone');
    if (!field.val().match(/^\d{3}-\d{3}-\d{4}$/)) {
      this.errors.push({name: field.attr('name'), message: 'is not a valid phone number.'});
    }
    
    // Password format (6 char min)
    field = $('#user_password');
    if (field.val().length < 6) {
      this.errors.push({name: field.attr('name'), message: "must be at least 6 characters."});
    }

    // password == password conf
    if ($("#user_password").val() !== $("#user_password_confirmation").val()) {
      this.errors.push({name: $("#user_password_confirmation").attr('name'), message: 'must match your password.'});
    }
    
    if (hasErrors()) return false;
  },
  
  populateDummyZip: function () {
    $("#dummy_zip").val($("#delivery_zip").val());
  },
  
  resetErrors: function () {
    this.errors = [];
  },
  
  resetErrorDisplay: function () {
    $(this.errorMessageDiv).html(''); 
    $('form .error').removeClass('error');
    $('form .errorField').removeClass('errorField');    
  },
  
  displayErrors: function (errorDiv) {
    this.resetErrorDisplay();
    errorDiv = errorDiv || $(this.errorMessageDiv);
    var i, errorField, labelText, label, error, errorMessages = "<h1>Please correct the errors below.</h1><ul>";
    for (i=0; i<this.errors.length; i++) {
      error = this.errors[i];
      if(error.name == "other_error"){
        errorDiv.html("Something went wrong. Try again later.");
        return false;
      }
      
      errorField = $("[name="+error.name+"]");

      label = $("[for='"+errorField.attr('id')+"']");
      if (!label[0]) {
        // Some fields do not have a label displayed but instead have a 
        // 'p.label' which refers to a number of fields (eg: Name)
        label = errorField.prevAll('p.label');
        labelText = error.name.match(/\[(.+)\]$/)[1].replace(/_/g, " ");
        labelText = labelText.substr(0,1).toUpperCase() + labelText.substr(1); // capitalize first letter
      } else {
        labelText = label.html().replace(/\s+\*?$/, '');
      }
      errorField.addClass('errorField');
      label.addClass('error');
      errorMessages += "<li>"+labelText+' '+error.message+"</li>";
    }
    errorMessages += "</ul>";
    errorDiv.html(errorMessages); 
    $(document).scrollTop(0)
  },
  
  displayName: function (paramName) {
    return paramName.match();
  },
  
  putWidgetDateInForm : function(){
    var widgetDate = $("#datepicker").datepicker('getDate');
    var widgetDateString = (widgetDate.getMonth() + 1) + "/" + widgetDate.getDate() + "/" + widgetDate.getFullYear();
    var i, dateParts = widgetDateString.split('/'); // mm/dd/yy
    for (i=0; i<3; i++) {
      $('#start_date_fieldset input:eq('+i+')').val(dateParts[i]);
    };

  },
  
  setupUI: function () {
    // display any server errors
    if (Registration.serverErrors) {
      this.errors = Registration.serverErrors;
      this.displayErrors();
    }
    
    Registration.populateDummyZip();
    
    // Add blur handler to ZIP field
    $("#delivery_zip").blur(function () {
      Registration.validate(true);
    });

    // Add fix for IE6 display bug
    $(document).bind("beforeReveal.facebox", function(){$("select").css('visibility', 'hidden');}) 
    $(document).bind("close.facebox", function(){$("select").css('visibility', 'visible');}) 
    
    // Dynamic Form sections
    $("input[name='delivery[location_info]']").val() == "key_needed" ? $('#send_key_to').show() : $('#send_key_to').hide();
    $('#delivery_billing_is_same').attr('checked') ? $('#billing_address').hide() : $('#billing_address').show();

    $("input[name='delivery[location_info]']").change(function () {
      $(this).val() == 'key_needed' ? $('#send_key_to').show() : $('#send_key_to').hide();
    });
    $("#delivery_billing_is_same").change(function () {
      $(this).attr('checked') ? $('#billing_address').hide() : $('#billing_address').show();
    });

    if (jQuery.browser.msie) { // fix IE's event firing only on blur
      $("#delivery_billing_is_same, input[name='delivery[location_info]']").click(function () {
        $(this).change();
      });      
    }

    // input helpers
    $('#user_phone').blur(function () {
      var inputNumbers = $(this).val().replace(/[^0-9]/g, '');
      if (inputNumbers.length == 10) {
        $(this).val(inputNumbers.substr(0,3) + '-' + inputNumbers.substr(3,3) + '-' + inputNumbers.substr(6));
      }
    });
    
    $('#billing_credit_card_number').blur(function () {
      var oldVal = $(this).val();
      $(this).val(oldVal.replace(/[^0-9]/g, ''));
    });
    
    $("#restrictions_r32").change(Registration.synchronizeFish);
    $("#restrictions_r56").change(Registration.synchronizePoultry);
    
    // Form validation
    $(this.registrationForm).submit(function (evt) {
      try {
        return Registration.validate();
      } catch (e) {
        // if (window.console) console.log(e)
        return false
      }
    });
    
    $('.errorField').live('change', function () {$(this).removeClass('errorField')});
    
  },
  
  setupDatePicker: function () {
    // Calendar widget
    // Set default date to 2 days ahead, or to monday if that falls on weekend
    var today = new Date(), i=0;
    var defaultDate = new Date(today.getFullYear(), today.getMonth(), today.getDate()+2);
    while (defaultDate.getDay() == 6 || defaultDate.getDay() == 0) {
      i++;
      defaultDate = new Date(today.getFullYear(), today.getMonth(), today.getDate()+2+i);
    }
    
    $("#datepicker").datepicker({ minDate: defaultDate });
    
    // if the server populated a date, sync the widget:
    if ($("#start_day").val() != ""){
      var oldDateString = [$("#start_month").val(), $("#start_day").val(), $("#start_year").val()].join("/");
      var oldDate = new Date(oldDateString);
      $("#datepicker").datepicker('setDate', oldDate);
    }
  },
  
  synchronizeFish: function () {
    $("#restrictions_r58").attr('checked', $("#restrictions_r32").attr('checked'));
    $("#restrictions_r64").attr('checked', $("#restrictions_r32").attr('checked'));
    $("#restrictions_r84").attr('checked', $("#restrictions_r32").attr('checked'));
    $("#restrictions_r57").attr('checked', $("#restrictions_r32").attr('checked'));
  },
  
  synchronizePoultry: function () {
    $("#restrictions_r66").attr('checked', $("#restrictions_r56").attr('checked'));
    $("#restrictions_r85").attr('checked', $("#restrictions_r56").attr('checked'));
  }
  
};