/*
 * buyNow.js -- utilitiy functions to process orders for buying PyMOL
 *
 * AUTHOR: Jason Vertrees, Herc Silverstein
 * LICENSE: ...
 * COPYRIGHT: ...
 * DATE: 01/04/2010
 */
$(function(){ 
 
  /*
   * initialize the page
   */
  $("#zip").bind( "blur", zip_callback );
  $("#phone").bind( "blur", set_paypal_phone_variables_callback);
  $("#state").bind( "blur",  state_callback );
  $("#country").bind("change", updateCountry );
 
  // if the user modified the select at all
  $("#os0").bind("change", updateTotals );
  $("#os0").bind("keyup", updateTotals );
  $("#tax_rate").bind("change", updateTotals );
  
  // Force a tax recalculation.  This is done to make sure the tax
  // is calculated when the user presses buynow.  Otherwise,
  // if a user fills things out and has tax, clicks on buynow
  // to go to paypal, and clicks back, the tax is set to zero.
  // If they then click on buynow again, a tax of 0.0 is sent to paypal.
  // Triggering the blur event will cause the tax to be calculated based
  // on the zip.
  $("#zip").trigger("blur");      

  updateTotals();

});


var zip_state_match = false;
var zip_state_mismatch_message = "The zip for the State you entered is not valid.\nPlease fix either the zip code or the 2-letter state name.";
var zip2tax_done = false;

/* Pause for the given number of milliseconds */
function pause_milliseconds(duration)
{
    var date = new Date();
    var start = date.getTime();
    var cur_date = null;
    do {
         cur_date = new Date();
         cur_time = cur_date.getTime();
    } while( (cur_time - start) < duration);

//    alert ("leaving pause_milliseconds " + start + ", " + cur_time);

}

/* Wait for up to 5 seconds for the tax calculation to complete.
   Firefox 3.0.6 has a maximum run time of 10 seconds for javascript scripts. 
   Experiments with pause loops of 8 seconds also seems to hit the 10 second 
   max (due to overhead).
*/
function wait_for_tax()
{

   // Maximum of roughly 6 seconds at rougly 1/2 second intervals
   for (i=0;i<=12;i++)
   {
      if (zip2tax_done == true) {
         break;
      }
      pause_milliseconds(500);
   }
   
}

function  state_callback(e)
{
     the_form.zip.value = "";
}

function  zip_callback(e)
{
    zip2tax_done = false;  // checked by the form validator
    zip2tax();
}

function  set_zip_state_match(state)
{
    zip_state_match = state;
}

// So user cannot hit enter and have form submitted.
// They have to click on Buy Now
function disableEnterKey(e)
{
     var key;     
     if(window.event)
          key = window.event.keyCode; //IE
     else
          key = e.which; //firefox     

     return (key != 13);
}

// User chose different item in the country menu
function updateCountry() {
    the_form = document.forms["pymol order"];
    country = getCountry(the_form);
    if (country != "US") {
        // Set tax to zero
        $("#tax_rate").html(0.0);
        $("#tax_rate").trigger("change");      
        the_form.state.maxLength = 30;
    }
    else {
        // Recalculate the tax
        the_form.state.maxLength = 2;
        zip2tax();
    }
}

  function getBasePrice() {
  /* getBasePrice -- read the product base price from the DOM
   * PARAMS : None
   * RETURNS: (float to two decimal places) value presented from the selected product
   * UPDATES: None
   */
    var optionIndex = $('#os0 option').index($("#os0 option:selected"));
    optAmt = "input[name='option_amount" + optionIndex + "']";
    var val = parseFloat($(optAmt).val()).toFixed(2);
    if (isNaN(val) || val==0){
      return (0.00).toFixed(2);
    }
    else
      return val;
  }
    
  function isTaxable() {
    /* isTaxable -- grabs country, state and zip from the form and determines 
     *              if this needs to be taxed.
     * PARAMS: None
     * RETURNS: (boolean) true if we can tax, false otherwise
     * UPDATES: None
     */
      var country = $("select#country option:selected").val().toUpperCase();
      var taxableStates = [ "CT", "IA", "MA", "NC", "NY", "RI", "WA"];
      
      if (country == "US") {
        var state = document.forms["pymol order"].state.value;
        state = state.toUpperCase();
        if (contains(taxableStates, state)) {
          return true;
        }
      }
    return false;
  }

  function setTaxRate(data) {
    /* setTaxRate -- sets the tax rate to the parameter
     * PARAMS : data the JSON object returned from PHP/AJAX query to 
     *          zip2tax, which is an JSON object with "tax_rate" defined.
     * RETURNS: None
     * UPDATES: #tax_rate
     */

    // JSON object is coming back in the form
    // {"tax_rate":{"0":"8.875"},"status":0,"state":{"0":"NY"}}
      /*
       for (var k in data) {
         alert(k + '=' + data[k]);
       }
      */

    zip2tax_done = true;
    if (data && data["status"] == 0) {
        var country = $("select#country option:selected").val().toUpperCase();
        if (country == "US") {
           var state = document.forms["pymol order"].state.value;
           state = state.toUpperCase();
           if (state != data["state"][0]) {
                // Zip and state do no match
                alert(zip_state_mismatch_message);
                // Set global to indicate not OK to proceed to paypal
                zip_state_match = false;
                $("#tax_rate").html(0.0);
                $("#tax_rate").trigger("change");      
                return;
           }

           // Zip and state match. 
           var tax_states = [ "CT", "IA", "MA", "NC", "NY", "RI", "WA"];
           var state = document.forms["pymol order"].state.value;
           state = state.toUpperCase();
           if (contains(tax_states, state)) {
              $("#tax_rate").html(data["tax_rate"][0]);
           }
           else {
              $("#tax_rate").html(0.0);
           }
           $("#tax_rate").trigger("change");      
           // Set global to indicate OK to proceed
           zip_state_match = true;
           return;
        }

        // Country is not US 
        $("#tax_rate").html(0.0);
        $("#tax_rate").trigger("change");      
        zip_state_match = true;
    }
    else if ( data==undefined ) {
      $("#tax_rate").html(data["tax_rate"]);
      $("#tax_rate").trigger("change");      
    }
    else {
        // Assume this is because of initial page load where
        // state and zip won't be set.
        $("#tax_rate").html(0.0);
        $("#tax_rate").trigger("change");      
       zip_state_match = false;
    }

/*
    if ( data==undefined || data["status"] == 0 ){
      // Error handling for tax rate errors should be done.
      // It could be done in the php code
      $("#tax_rate").html(data["tax_rate"]);
      $("#tax_rate").trigger("change");      
    }
    else {
       alert("Error setting tax_rate. Please contact help@schrodinger.com.");
    }
*/
  }
   
  function getTaxRate() {
  /* getTaxRate -- reads the tax rate from the DOM in PERCENT
   * PARAMS: None
   * RETURNS: (float to two decimal places) tax rate
   * UPDAES: None
   */
    return parseFloat($("#tax_rate").html());
  }
 
  function calcSubtotal() {
  /* calcSubtotal -- calculates the product price + any taxes
   * PARAMS: None
   * RETURNS: (float to two decimal places) value of the product + applicable tax
   * UPDATES: None
   */
    var rVal = getBasePrice() * (1.0+(getTaxRate()/100.0));
    if (isNaN(rVal)) {
      return 0.00;
    }
    else {
      // Make sure rounds correctly.  Without this 272.655 rounds
      // to 272.65 when it should round to 272.66.
      var result=Math.ceil(rVal*100)/100
      return result.toFixed(2);
    }
  }
  
  function calcTax() {
  /* calcTax -- determines the DOLLAR amount of the taxable item
   * PARAMS: None
   * RETURNS: (float) to 2 decimal places
   * UPDATES: None
   */
    var base_price = getBasePrice(); 
    var tax = getTaxRate();
    var itmp = base_price * tax;
    var val = parseFloat (Math.ceil(itmp)/100);
    if (isNaN(val))
      return 0.00;
    else return val.toFixed(2);
  }

  function updateTotals() {
  /* updateTotals -- change prices if necessary
   * PARAMS: None
   * RETURNS: None
   * Updates: #tax, #subtotal
   */
     var tax_amount = calcTax();
     $("#tax").html(tax_amount);
     $("#subtotal").html(calcSubtotal());
     $("#base_price").html(getBasePrice());

     // Set this so that it gets carried over to paypal
     the_form = document.forms["pymol order"];
     the_form.tax.value = tax_amount;
  }
  
  function zip2tax(data) {
  /* zip2tax -- perform the AJAX call to zip2tax
   * PARAMS: default event
   * RETURNS: None; calls setTaxRate
   * UPDATES: None
   */
    var baseLink = "getTax_v3.php";
    // fetch the tax rate and pass it to displayTaxRate
    //alert($("#zip").val());
/*
      $.getJSON(baseLink,
        { zip : $("#zip").val() },
        function(data){ setTaxRate(data); }
       );
*/
    the_form = document.forms["pymol order"];
    country = getCountry(the_form);
    if (country != "US") {
    //alert("NOT US");
        // Country is not US 
        $("#tax_rate").html(0.0);
        $("#tax_rate").trigger("change");      
        zip2tax_done = true;
    }
    else {
      // US
    //alert("US");
      $.getJSON(baseLink,
        { zip : $("#zip").val() },
        function(data){ setTaxRate(data); }
       );
    //("did json call");

    }
  }

// Check to see if object is in the given array
// return true if a is an element of obj 
function contains(a, obj)
{
  for(var i = 0; i < a.length; i++) {
    if(a[i] === obj){
      return true;
    }
  }
  return false;
}


// Make sure the string is a valid 2-character state code
function validate_state(state)
{
   if (state.length != 2)
   return false;

   // Make an array with all the statecodes
   // Also ncludes territories, freely associated states, etc.
   arr = [ "AL", 
  "AK",  
  "AS",  
  "AZ",  
  "AR",  
  "CA", 
  "CO", 
  "CT", 
  "DE",  
  "OF", 
  "FM", 
  "FL", 
  "GA", 
  "GU", 
  "HI", 
  "ID", 
  "IL", 
  "IN", 
  "IA", 
  "KS", 
  "KY", 
  "LA", 
  "ME", 
  "MH", 
  "MD", 
  "MA", 
  "MI", 
  "MN", 
  "MS", 
  "MO", 
  "MT", 
  "NE", 
  "NV", 
  "NH", 
  "NJ", 
  "NM", 
  "NY", 
  "NC", 
  "ND", 
  "MP", 
  "OH", 
  "OK", 
  "OR", 
  "PW", 
  "PA", 
  "PR", 
  "RI", 
  "SC", 
  "SD", 
  "TN", 
  "TX", 
  "UT", 
  "VT", 
  "VI", 
  "VA", 
  "WA", 
  "WV", 
  "WI", 
  "WY"];
  
    state = state.toUpperCase();
    return contains(arr, state);
}

function getCountry(the_form)
{
  var i = the_form.country.selectedIndex;
  country = the_form.country.options[i].value;
  return country.toUpperCase();
}


// Return true for valid zip, false for an invalid one
// Displays alerts when there is an invalid zip
function validate_zip(country, the_form)
{
   if (the_form.zip.value.length < 1 ) {
     alert ("Please enter a zip.");
     return false;
   }

  if (country != "US") {
    return true;
  }

  // If it has a dash, then assume 10 characters
  // Otherwise, only 5 or 9 characters are valid
  if (the_form.zip.value.indexOf("-") > 0) {
    if (the_form.zip.value.length == 10) {
        return true;
    }
    else {
        alert ("Please enter 5 or 9 digits with an optional dash in between.");
        return false;
    }
  }

  // No dash
  if (the_form.zip.value.length == 5 || the_form.zip.value.length == 9) {
     return true;
  }
  else {
     alert ("Please enter 5 or 9 digits with an optional dash in between.");
     return false;
  }

}

// Mail the contact info in so we have a record of it
// Requires jquery library have been loaded.
function mail_contact_info(the_form) 
{
  /* 
   * PARAMS: none
   * RETURNS: none
   * UPDATES: None
   */

   var baseLink = "contactinfo.php";

   // NOTE: If these field names change in the form, then they'll
   // have to be updated here.
   var name = $("#subscriber").val();
   var address1 = $("#address1").val();
   var address2 = $("#address2").val();
   var city =     $("#city").val();
   var state =    $("#state").val();
   var zip =      $("#zip").val();
   var country =  getCountry(the_form);
   var email =    $("#email").val();
   var phone =    $("#phone").val();
   var sub_option_index = $('#os0 option').index($("#os0 option:selected"));
   var sub_option_name ="input[name='option_select" + sub_option_index + "']";
   var subscription = $(sub_option_name).val();

/*    all_vals = name + "\n" +
    address1 + "\n" +
    address2 + "\n" +
    city + "\n" +
    state  + "\n" +
    zip + "\n" +
    country + "\n" +
    email + "\n" +
    phone + "\n" +
    sub_option_index + "\n" +
    sub_option_name + "\n" +
    subscription + "\n";

    alert (all_vals);
*/

   $.post( "contactinfo.php",
     { "name" : name,
       "address1" : address1,
       "address2" : address2,
       "city" : city,
       "state" : state,
       "zip" : zip,
       "country" : country,
       "email" : email,
       "phone" : phone,
       "subscription" : subscription
     }
/*
    ,
    function(data){
     alert("Data Loaded" + data);
   }
*/
   );  
}


// Parse the phone text box value and assign
// the sub-parts to the appropriate paypal variables
function set_paypal_phone_variables_callback(e)
{
   the_form = document.forms["pymol order"];
   var phone =  the_form.phone.value;

   // Clear out in case parsing doesn't work
   the_form.night_phone_a.value = "";
   the_form.night_phone_b.value = "";
   the_form.night_phone_c.value = "";

   if (country == "US") {
     if (phone.indexOf('(') == 0  &&  phone.indexOf(')') == 4) {
        // (xxx)xxx-xxxx
        // (xxx) xxx-xxxx
        the_form.night_phone_a.value = phone.substr(1,3);
        var rest = phone.substr(5)
        var arr = new Array()
        arr = rest.split('-')
        if (arr.length == 2) {
           the_form.night_phone_b.value = arr[0];
           the_form.night_phone_c.value = arr[1];
        }
     }
     else if (phone.indexOf('-') == 3) {
        // xxx-xxx-xxxx
        var arr = new Array()
        arr = phone.split('-')
        if (arr.length == 3) {
           the_form.night_phone_a.value = arr[0];
           the_form.night_phone_b.value = arr[1];
           the_form.night_phone_c.value = arr[2];
        }
     }
   }
   else {
     // Not US
     // +XX - *
     // +XX *
     space_index = phone.indexOf(' ');
     if (space_index == -1) {
         // Could not find a space.  
         the_form.night_phone_a.value = "";
         the_form.night_phone_b.value = phone;
     }
     else {
         the_form.night_phone_a.value = phone.substr(0,space_index);
         the_form.night_phone_b.value = phone.substr(space_index);
     }
     the_form.night_phone_c.value = "";
   }

}

// Validate the information in the form before sending it off
// Return true if OK, false if not
function pymol_form_validation(the_form)
{

/*
   if (zip2tax_done == false) {
    // Tax calculation didn't finish in time.  Try waiting a bit.
    wait_for_tax();
   }
*/
   if (zip2tax_done == false) {
      // Still didn't get tax.  Something is wrong.
      alert("Sorry, there was a problem completing the order.  Please try again or use our FAX order form at http://pymol.org/ccard.html");
      return false;
   }

   // alert("pymol_form_validation()");
   i = the_form.country.selectedIndex;

   country = the_form.country.options[i].value;
   country = country.toUpperCase();

   // Make sure following fields have at least something
   if (the_form.subscriber.value.length < 1) {
     alert ("Please enter a subscriber name.");
     return false;
   }

   if (the_form.address1.value.length < 1) {
     alert ("Please enter an address.");
     return false;
   }
   if (the_form.city.value.length < 1 ) {
     alert ("Please enter a city.");
     return false;
   }

   zip_status = validate_zip(country, the_form);
   if (zip_status == false) {
     return false;
   }

   if (the_form.email.value.length < 1) {
     alert ("Please enter an e-mail address.");
     return false;
   }
   if (the_form.email.value.indexOf("@") < 0) {
     alert ("Please enter a valid e-mail address.");
     return false;
   }


   if (country == "US") {
      // Make sure the state code is valid
      state = the_form.state.value;
      state_status = validate_state(state);
      if (state_status == false) {
          msg = state + " is not a valid 2-letter state code"; 
          alert(msg);
          return false;
      }
 
      // Valid State.  See if code can be recomputed
//      zip2tax();

      if( zip_state_match == false ) {
          alert(zip_state_mismatch_message);
          return false;
      }

   }

   // Make sure some level of pymol support was chosen
   if (the_form.os0.selectedIndex == 0 ) {
       alert ("Please choose a PyMOL support level.");
       return false;
   }

   mail_contact_info(the_form);

   return true;

}
 
