var accordion;

var submitbutton;

function init () {
  var options = $("options");
  if (options.childNodes.length) {
    accordion = new Rico.Accordion (options, {expandedBg: '', collapsedBg: '', collapsedTextColor: '', collapsedFontWeight: '', borderColor: '#999' });
  }
  var tabs = new EJAX.TAB_WIDGET ("configurator-tabs");
  $("system-quote").onsubmit = validate_form;
  Event.observe ("new-customer", "click", function(){submitbutton = 2;});
  // change event not fired on IE
  Event.observe ("options", "click", function (ev) {
    var e = Event.element(ev);
    if (typeof e.value  != "undefined") {
      var checked_value = EJAX.FORM.checked_value ("system-quote", e.name);
      if (checked_value == "") {
        remove_selection(e.name.slice(5));
      }
      else {
        if (checked_value > 0) {
          var e = $("c-" + checked_value);
          set_selection(e.value);
        }
      }}});
  if (window.ac_dc_power) {
    Element.show ("power-selection");
    if (EJAX.FORM.checked_value ("system-quote", "power") == "ac") {
      ac_dc_power.each (function (pair) {
        Element.show ("v-" + pair.key);
        Element.hide ("v-" + pair.value);
      });
    }
    else {
      ac_dc_power.each (function (pair) {
        Element.hide ("v-" + pair.key);
        Element.show ("v-" + pair.value);
      });
    }
  }
  if (window.ac_dc_power) {
    /* always hide panel 119, base system with AC/DC selection */
    var e = $("tab-119");
    if (e) {
      Element.hide (e);
      /* set the AC version of this base system as the default, but only when we load the page, i.e. when none has been selected */
      if (EJAX.FORM.checked_value ("system-quote", "type-119") == "") {
        types["119"].components.each (function(component_id) {
          if (ac_dc_power[component_id]) {
            $("c-" + component_id).checked = true;
            set_selection (component_id);
          }
        });
      }
    }
  }
  if ($F("ejax-reloaded") != "0") {
    fixup_reloaded_page ();
  }
  else {
    $("ejax-reloaded").value = 1;
  }
  Event.observe ("country", "change", function (){country_changed()});
  country_changed();
  /* Shipping costs */
  /*
  Event.observe ("confirm-shipping-costs", "click", function () {
    set_shipping_options();
  });
  */
  // Enable observers at the end, hopefully helps for load time
  new Form.Element.Observer ("quantity", 1, function(){calculate_total()});
  new Form.Element.Observer ("currency", 1, function(){on_currency_changed("currency")});
  /* enable quantity change observers for individual components */
  for (var component_type_id in types) {
    var q = $("q-" + component_type_id);
    if (q) {
      new Form.Element.Observer (q, 1, new Function ("on_quantity_changed (" + component_type_id + ")"));
    }
  }
  try {
    $$ ("#shipping-methods input").each (function (e) {
      // Event.observe (e, "change", function (){calculate_shipping_costs()});
      new Form.Element.Observer (e, 1, function (e){ if (e.checked) { calculate_shipping_costs()}});
    });
  }
  catch (err) {
    // Ignore, above gives error on IE, and we're not using this anyway.
  }
  $ ("critical_message").value = '';
  Element.Methods.remove('loading');
  Event.observe ("next-1", "click", function () {
      tabs.show_pane ($ ("tab-shipping-details"));
    });
  Event.observe ("next-2", "click", function () {
      tabs.show_pane ($ ("submit-quote"));
    });
  if ($F("currency")!=1)
    on_currency_changed("currency");
}

Event.onDOMReady(init);


/* http login */

function try_login (url, username, password) {
  again = username;
  username = $F(username);
  password = $F(password);
  var myAjax = new Ajax.Request("/check/email",
    {method:'get',
     parameters: "email=" + encodeURIComponent(username) + "&password=" + encodeURIComponent(password),
       asynchronous: false});
  if (myAjax.transport.status == 200) {
    var request = Ajax.getTransport();
    request.open("HEAD", url, false, username, password);
    request.send(null);
    if ((request.status == 200) || (request.status == 302)) {
      return true;
    }
    else {
      alert (request.status);
      return false;
    }
  }
  else {
    EJAX.FORM.alert_invalid_input (again, "Username and/or password not valid.")
    return false;
  }
}


/* support forced logins */

function force_login (url, username, password) {
  var request = Ajax.getTransport();
  request.open("HEAD", url, false, username, password);
  request.send(null);
  console.log (self.location);
  window.location = window.location.protocol + '//' + window.location.host + window.location.pathname;
}


function set_login_contact_name (data) {
  Element.update ("login-contact-name", data.contact_name);
  $ ("email").value = data.email;
  $ ("password").value = data.password;
  $ ("password2").value = data.password;
  $ ("company_name").value = data.company_name;
  $ ("contact_name").value = data.contact_name;
  $ ("address1").value = data.address1;
  $ ("address2").value = data.address2;
  $ ("city").value = data.city;
  $ ("zip").value = data.zip;
  //$ ("country").value = data.country;
  var country = $("country");
  for (var i = 0; i < country.length; i++) {
    if (country.options[i].text == data.country) {
      country.selectedIndex = i;
      break;
    }
  }
  country_changed();
  $ ("state").value = data.state;
  $ ("phone").value = data.phone;
  $ ("extension").value = data.extension;
  $ ("fax").value = data.fax;
  if (data.show_prices == "True") {
    $ ("system-price").style.display = "";
    var sel = $ ("currency");
    var text = sel.options[sel.selectedIndex].text;
    new Insertion.Before ("currency", text);
  }
}

/* price, in correct currency, for component `component_id' */
function component_price (component_id) {
  return (components[component_id].price * currencies[$F('currency')]);
}

function component_quantity (component_type_id) {
  require ("valid component_type_id", component_type_id);
  var q;
  q = $("q-" + component_type_id);
  if (q) {
    return $F(q);
  }
  else {
    return 1;
  }
}

function selected_component (component_type_id) {
  require ("has component_type_id", component_type_id);
  return EJAX.FORM.checked_value ("system-quote", "type-" + component_type_id);
}

function is_percentage (type_id) {
  return types[type_id].is_percentage ? true : false;
}

function remove_selection (component_type_id) {
  var tr = $("tr-" + component_type_id);
  check ("row for category " + component_type_id + " not found.", tr);
  Element.hide (tr);
  var price = $("cprice-" + component_type_id);
  price.innerHTML = 0;
  update_percentage_based_prices ();
  calculate_total ();
  set_price_differentials (component_type_id);
  update_slots ();
}

function set_selection (component_id) {
  var component_type_id = components[component_id].type;
  set_selected_row (component_type_id, component_id);
  update_percentage_based_prices ();
  calculate_total ();
  set_price_differentials (component_type_id, component_id);
  update_slots ();
}

function set_selected_row (type_id, component_id) {
  var price, td, tr, text;
  tr = $("tr-" + type_id);
  check ("row for category " + type_id + " not found.", tr);
  text = $("text-" + component_id);
  td = $("descr-"+ type_id);
  td.innerHTML = text.innerHTML;
  if (types[type_id].is_percentage) {
    price = components[component_id].price;
  }
  else {
    price = component_price (component_id);
  }
  td = $("cprice-" + type_id);
  var quantity = component_quantity (type_id);
  if (is_percentage (type_id)) {
    td.innerHTML = EJAX.Currency.as_currency (total_without_percentages() * price);
  }
  else {
    td.innerHTML = EJAX.Currency.as_currency (price * quantity);
  }
  Element.show (tr);
}


/* update every price that is based on a percentage  */

function update_percentage_based_prices () {
  var i, type, type_id, component_id, new_price, type_selected_component, selected_price;
  var total = total_without_percentages();
  for (type_id in types) {
    type = types[type_id];
    if (type.is_percentage) {
      var component_id = selected_component (type_id);
      if (component_id) {
        selected_price = total * components[component_id].price;
      }
      else {
        selected_price = 0;
      }
      for (i = 0; i < type.components.length; i++) {
        component_id = type.components [i];
        new_price = total * components[component_id].price;
        $("price-" + component_id).innerHTML = EJAX.Currency.as_currency (new_price - selected_price);
        type_selected_component = selected_component (type_id);
        if (component_id == type_selected_component) {
          $("cprice-" + type_id).innerHTML = EJAX.Currency.as_currency (new_price);
        }
      }
    }
  }
}


/* change prices in a panel to be the difference with `component_id' */

function set_price_differentials (component_type_id, component_id) {
  //if (! is_percentage (component_type_id)) {
    var e, selected_price, price, prefix, total, new_price;
    if (component_id) {
      if (is_percentage (component_type_id)) {
        total = total_without_percentages();
        selected_price = total * components[component_id].price;
      }
      else {
        selected_price = component_price (component_id);
      }
      // not required components have a not required option
      // show price to be subtracted there
      e = $("nr-" + component_type_id);
      if (e) {
        e.innerHTML = " (subtract $" + EJAX.Currency.as_currency (selected_price) + ")";
      }
    }
    else {
      selected_price = 0;
      $("nr-" + component_type_id).innerHTML = "";
    }
    if (types[component_type_id].components) {
      types[component_type_id].components.each (function (id) {
        var s = $("s" + id);
        var u = $("u" + id);
        if (id == component_id) {
          Element.Methods.show(s);
          Element.Methods.hide(u);
        }
        else {
          Element.Methods.hide(s);
          if (is_percentage (component_type_id))
            price = total * component_price (id);
          else
            price = component_price (id);
          new_price = price - selected_price;
          if (new_price < 0)
            prefix = 'subtract ';
          else
            prefix = 'add ';
          u.innerHTML = prefix + "$<span id='price-" + id + "'>" + EJAX.Currency.as_currency (new_price) + "</span>";
          Element.Methods.show(u);
        }
      })
    }
    //}
}

function total_without_percentages () {
  var cell, i, n, table, total;
  table = $("configuration-table");
  total = 0;
  /* first go through default and selected components */
  for (i = 1; i != table.rows.length; i++) {
    cell = table.rows[i].cells[2];
    if ((cell) && (!Element.Methods.hasClassName (cell, "percentage"))) {
      try {
        n = parseFloat (cell.innerHTML.replace (",", ""));
        if (! isNaN (n)) {
          total = total + n;
        }
      }
      catch (err) {
        console.debug (err);
      }
    }
  }
  return total;
}

function calculate_total () {
  var cell, i, n, table, total;
  total = total_without_percentages ();
  /* next add the percentages */
  table = $("configuration-table");
  for (i = 1; i != table.rows.length; i++) {
    cell = table.rows[i].cells[2];
    if ((cell) && (Element.Methods.hasClassName (cell, "percentage"))) {
      try {
        n = parseFloat (cell.innerHTML.replace (",", ""));
        if (! isNaN (n) && n > 0) {
          total = total + n;
        }
      }
      catch (err) {
        console.debug (err);
      }
    }
  }
  var price = $("price");
  var quantity = $F("quantity");
  price.innerHTML = EJAX.Currency.as_currency ((quantity * total));
}

/* recalculate all prices, except total, if currency has changed */
/* you will need a separate call to calculate_total() to update that */

function recalculate_prices (currency_rate) {
  var component_id, component_type_id, e, price, price_differential, quantity, s, type, type_selected_component;
  /* change prices on configuration panel */
  /* has to take care of price differentials */
  for (component_type_id in types) {
    type = types[component_type_id];
    if (! type.is_percentage) {
      type_selected_component = selected_component (component_type_id);
      if (type_selected_component) {
        price_differential = components[type_selected_component].price;
      }
      else {
        price_differential = 0;
      }
      for (i in type.components) {
        component_id = type.components[i];
        e = $("price-" + component_id);
        if (e) {
          e.innerHTML = EJAX.Currency.as_currency ((components[component_id].price - price_differential) * currency_rate);
        }
      }
    }
  }
  /* change prices for default components */
  for (component_id in defaults) {
    e = $("dprice-" + component_id);
    if (e) {
      s = defaults[component_id];
      if (s) {
        price = components[component_id].price * currency_rate;
        e.innerHTML = EJAX.Currency.as_currency (price);
      }
    }
  }
  /* change prices for selected components */
  for (component_type_id in types) {
    type = types[component_type_id];
    if (! type.is_percentage) {
      type_selected_component = selected_component (component_type_id);
      if (type_selected_component) {
        e = $("cprice-" + component_type_id);
        if (e) {
          quantity = component_quantity (component_type_id);
          price = quantity * components[type_selected_component].price * currency_rate;
          e.innerHTML = EJAX.Currency.as_currency (price);
        }
      }
    }
  }
}

function on_currency_changed (currency) {
  recalculate_prices (currencies[$F(currency)]);
  update_percentage_based_prices ();
  calculate_total ();
}

function on_quantity_changed (component_type_id) {
  require ("component exists", components[selected_component (component_type_id)]);
  var new_quantity = $F("q-" + component_type_id);
  var price = $("cprice-" + component_type_id);
  price.innerHTML = EJAX.Currency.as_currency (new_quantity * component_price ([selected_component (component_type_id)]));
  update_percentage_based_prices ();
  calculate_total ();
  update_slots ();
}


/* AC/DC power */

function set_ac_power () {
  ac_dc_power.each (function (pair) {
    Element.show ("v-" + pair.key);
    Element.hide ("v-" + pair.value);
    c = $("c-" + pair.value);
    if (c.checked) {
      c.checked = false;
      $("c-" + pair.key).checked = true;
      set_selection (pair.key);
    }
  });
}

function set_dc_power () {
  var c, type_id;
  ac_dc_power.each (function (pair) {
    Element.hide ("v-" + pair.key);
    Element.show ("v-" + pair.value);
    c = $("c-" + pair.key);
    if (c.checked) {
      c.checked = false;
      $("c-" + pair.value).checked = true;
      set_selection (pair.value);
    }
  });
}


/* slots */

function update_slots () {
  var component_type_id, slot, slot_id, type, type_selected_component;
  for (slot_id in slots) {
    if (slots[slot_id].used) {
      slots[slot_id].used = 0;
    }
  }
  for (component_type_id in types) {
    type = types[component_type_id];
    if (type) {
      slot = type.slot;
      if (slot) {
        type_selected_component = selected_component (component_type_id);
        if (type_selected_component) {
          slots[slot.id].used += slot.required * component_quantity (component_type_id);
        }
        if (slots[slot.id].used > slots[slot.id].available) {
          Element.show("slot-" + slot.id);
        }
        else {
          Element.hide("slot-" + slot.id);
        }
      }
    }
  }
}


/* form validation */

function validate_form (event) {
  try {
    var success = EJAX.FORM.validate(system_quote_parameters);
    if (success) {
      var password2 = $F("password2");
      success = (password2 == "") || password2 == $F("password");
      if (!success) {
        alert ("Both your passwords are not equal.");
        var e = $("password");
        e.focus();
        e.select();
      }
    }
    return success;
  }
  catch (err) {
    console.debug (err);
    return false;
  }
}

/* when page is reloaded (or back-button pressed), we need to present
   the proper view, because the values of the input controls might not
   reflect what is shown. */

function fixup_reloaded_page () {
  show_rows_based_on_selections ();
  var price_will_change = $("price-" + component_to_check_for_currency_recalculate).innerHTML != (components [component_to_check_for_currency_recalculate].price * currencies[$F("currency")]);
  if (price_will_change) {
    recalculate_prices (currencies[$F("currency")]);
  }
  calculate_total ();
}

function show_rows_based_on_selections () {
  var component_type_id, type, type_selected_component;
  for (component_type_id in types) {
    type = types[component_type_id];
    if (! type.is_percentage) {
      type_selected_component = selected_component (component_type_id);
      if (type_selected_component) {
        set_selected_row (component_type_id, type_selected_component);
        set_price_differentials (component_type_id, type_selected_component);
      }
    }
  }
}

/* country change */

var selected_country;

function country_changed () {
  var country = $F("country");
  if (country != selected_country) {
    var state = $("state-control");
    if (states[country]) {
      var s = '<select name="state" id="state" title="Enter Province/State" class="reqinput">';
      states[country].each (function (name) {
        s += '<option>' + name + '</option>';
      });
      s += '</select>';
    }
    else {
      s = '<input type="text" name="state" id="state" title="Enter Province/State" class="reqinput" maxlength="256"/>';
    }
    state.innerHTML = s;
    selected_country = country;
  }
}

/* shipping costs */

function set_shipping_options () {
  var country = $F("country");
  if ((country == "United States") || (country == "Canada")) {
    Element.show ("optFEDEXGROUND");
    Element.show ("optFEDEX2DAY");
    Element.show ("optPRIORITYOVERNIGHT");
    Element.hide ("optFIRSTOVERNIGHT");
    Element.hide ("optFEDEX1DAYFREIGHT");
    var v = EJAX.FORM.checked_value ("system-quote", "shipping-method");
    if (v == "FIRSTOVERNIGHT" && v == "FEDEX1DAYFREIGHT") {
      $("FEDEXGROUND").checked = true;
    }
    else {
      calculate_shipping_costs();
    }
  }
  else {
    Element.hide ("optFEDEXGROUND");
    Element.hide ("optFEDEX2DAY");
    Element.hide ("optPRIORITYOVERNIGHT");
    Element.show ("optFIRSTOVERNIGHT");
    Element.show ("optFEDEX1DAYFREIGHT");
    var v = EJAX.FORM.checked_value ("system-quote", "shipping-method");
    if (v != "FIRSTOVERNIGHT" && v != "FEDEX1DAYFREIGHT") {
      $("FIRSTOVERNIGHT").checked = true;
    }
    else {
      calculate_shipping_costs();
    }
  }
}

function calculate_shipping_costs () {
  if ($F("zip")) {
    var selected_components = "";
    var selected_quantities = "";
    for (component_type_id in types) {
      type = types[component_type_id];
      type_selected_component = selected_component (component_type_id);
      if (type_selected_component) {
        if (selected_components != "") {
          selected_components += ",";
          selected_quantities += ",";
        }
        selected_components += type_selected_component;
        selected_quantities += component_quantity (component_type_id);
      }
    }
    EJAX.RESPONSE.get ("shipping-cost", { values: ["zip", "state", "country", "quantity", "shipping-method", "currency"], query: "components=" + selected_components + "&component-quantities=" + selected_quantities, failure: calculate_shipping_cost_failure});
    Element.Methods.update ("shipping-cost", "calculating, please wait...<img src='/images/indicator.white.gif' alt=''/>");
  }
  else {
    Element.Methods.update ("shipping-cost", "<span style='color: red'>please supply a zip code for the shipping address.</span>");
  }
}

function calculate_shipping_cost_failure (request) {
  Element.Methods.update ("shipping-cost", "Sorry, failed to retrieve shipping cost.");
}
