/*
**************************************************
- DOCUMENT READY
**************************************************
*/

//Subscribe to jQuery's document ready
jQuery(function () {
  
  /*
  Cart step 2 - Need to hide or show the shipping address information
  If the checkbox is not checked
  */
  var differentShippingAddress = jQuery("#differentShippingAddress");
  if (differentShippingAddress[0]) {
    showHideShippingInformation(differentShippingAddress[0].checked);
  }
  
  /*
  The currency drop down shoul control the current country of the order.
  OnChange we will change the orders current country.
  */
  jQuery('select#currency').change(function () {
    var jQEle = jQuery(this), currencyId = jQEle.val();

    //Send the new currency Id to the server
    TeaCommerce.setCurrentCurrency(currencyId, true, function () {
      /*
      Allmost the whole page must be updated now as all prices has
      changed to the new currency. We could reload the page... But why
      not do it the nice way.
      The cart will be automatically updated  when the OnCartUpdated
      event is fired just after this one!
      */
      //Shipping and payment info is updated
      updateShippingAndPayment();
      //Our product list is updated
      updateProducts();
    });
  });
  
   /*
  Cart step 2 - Subscribe to country dropdowns onchange events
  and update the current country on the server
  */
  jQuery('select#country, select#shipping_country').change(function () {

    //Get the chosen country id
    var jQEle = jQuery(this), countryId = jQEle.val();
    /*
    If shipping address is chosen only the shipping country dropdown can
    change the current country
    */
    if (jQEle.attr("id") === "shipping_country" || (jQEle.attr("id") === "country" && !jQuery("#differentShippingAddress")[0].checked)) {

      /*
      Use the Tea Commerce javascript API to send the new country id to the server
      We subscribe to the success event of the server call
      */
      TeaCommerce.setCurrentCountry(countryId, true, function () {
        //On success
        /*
        If the triggering dropdown is the normal country select
        we change the shipping country dropdown as well to keep them in sync
        */
        if (jQEle.attr("id") === "country") {
          jQuery("select#shipping_country").val(countryId);
        }

        /*
        If the page contains shipping and payment information these have to be updated.
        The reason for this is that shipping and payment are hooked up on the countries
        and may change when we change the current country
        */
        var shippingAndPayment = jQuery("#shippingAndPayment");
        if (shippingAndPayment[0]) {
          /*
          TeaCommerce.invokeXSLT is used to fetch the paymentAndDelivery.xslt html from the server.
          The new html will be based on the new current country.
          The html replaces the old.
          */
          shippingAndPayment.after(TeaCommerce.invokeXSLT('paymentAndDelivery.xslt', _nodeId, false, null, null));
          shippingAndPayment.remove();
          Cufon.replace('#shippingAndPayment .cufonReplace');
        }
      });
    }
  });
  
  
});

/*
**************************************************
- GLOBAL VARIABLES
**************************************************
*/

//Declare some global variables.
var topCartCufonSelect = '#TopCart *',
    cartCufonSelect = 'ul#cartStepProgress li, div#cart h1, div#cart td#leftColumn table th, div#cart td#leftColumn table td h2, div#cart td#rightColumn div#orderTotal td, div#cart div#cartBottom a#next, div#cart div#cartBottom a#back',
    productCufon = 'div.product *, div#featuredProduct *',
    updateCounter = 0,
    submitTimer = null;

/*
**************************************************
- SUBSCRIBE TO THE TEA COMMERCE GENERAL EVENTS
**************************************************
*/

/*
We hook on to the onCartUpdated event.
This way we can change the UI everytime the Cart/order has been changed
*/
TeaCommerce.subscribeToOnCartUpdated(function (data) {

  //Update the carts of the site
  updateCarts(data);
});

/*
We hook on to the onCartUpdating event.
*/
TeaCommerce.subscribeToOnCartUpdating(function () {
  /*
  Set the start time of the submitTimer if it has not yet been set.
  This way we only set it on the first call in a series off calls
  */
  if (submitTimer === null) {
    submitTimer = new Date();
  }

  //Set the cart to updating mode
  jQuery('#TopCart').addClass('updating');
  jQuery('#cart').addClass('updating');

  //Increment the updatecounter
  updateCounter++;
});

/*
We hook on to the onCartUpdateError event.
*/
TeaCommerce.subscribeToOnCartUpdateError(function (error) {
  /*
  The errortext is thrown right at the user in the
  ugliest possible way.
  It is only called when something went very wrong
  and the server through an exception. This should
  never happen as the system is perfect ;)
  */
  alert("Cart Error: \n" + error.responseText);

  //The update counter is decremented as this call has returned.
  updateCounter--;
});

/*
**************************************************
- JQUERY LIVE EVENTS
**************************************************
*/

/*
When an add to cart button is clicked
*/
jQuery(".productAddToCart").live("click", function () {
  var jQEle = jQuery(this);

  /*
  If the product allready have a pending add to cart running
  we do not want to make another one.
  in principle you could easily make the call again. This
  is just for demo purposes. You can make as many calls to
  the server as you like.
  */
  if (!jQEle.hasClass('updating')) {
    jQEle.addClass('updating');

    //Get the various elements and variables
    var product = jQEle.closest('.product'),
        quantityInput = product.find('input.productQuantity'),
        quantity = quantityInput[0] ? quantityInput.val() : 1,
        variantSelect = product.find('select.chooseVariant'),
        nodeId = variantSelect[0] ? variantSelect.val() : jQEle.attr('nodeid');

    //If no node id has been selected we return and alert the user
    if (nodeId === '0') {
      alert('Husk at vælge en variant');
      jQEle.removeClass('updated');
      jQEle.removeClass('updating')
      return;
    }

    /*
    Add orderline is called using the Tea Commerce javascript API
    We subscribe to the return events to be able to update the
    css class of the button.
    */
    TeaCommerce.addOrderLine(nodeId, quantity, true, function () {

      //A timeout is set to show the user that the product has been added
      jQEle.removeClass('updating').addClass('updated');
      window.setTimeout(function () {
        jQEle.removeClass('updated');
      }, 1500);
      //Reload page to update variant
      location.reload();
    }, function () {
      //Something went wrong. We should handle it here
      jQEle.removeClass('updating');
    });
  }
  return false;
});

/*
The empty cart event
*/
jQuery('a#emptyCart').live('click', function () {

  //call the removeAllOrderLines which does just that
  TeaCommerce.removeAllOrderLines();
  window.setTimeout(function () {
    //Reload page to update variant
    location.reload();
  }, 1000);
  return false;
});

/*
The increment and decrement funktionality of the main cart
*/
jQuery('td#leftColumn a.minus, td#leftColumn a.plus').live('click', function () {
  var jQEle = jQuery(this),
      orderLine = jQEle.closest('.item'),
      quantityInput = orderLine.find('input.productQuantity'),
      nodeId = orderLine.attr('nodeid'),
      quantity = 1;

  //If the clicked button is minus the quantity is likewise
  if (jQEle.hasClass('minus')) {
    quantity = -1;
  }

  /*
  We increment/decrement the input field to let the
  user know somthing has happened
  */
  quantityInput.val(parseInt(quantityInput.val(), 10) + quantity);

  /*
  Again we use the versatile addOrderLine method to
  change the quantity.
  This also means that if the user adds a product
  to the cart several times the quantity will be
  added to the orderline.
  */
  TeaCommerce.addOrderLine(nodeId, quantity);
  return false;
});

/*
Change quantity is changed in the cart
*/
jQuery('#cart input.productQuantity').live("blur", function () {
  var jQEle = jQuery(this),
      nodeId = jQEle.closest(".item").attr('nodeId'),
      quantity = jQEle.val();

  //The quantity is overwritten
  TeaCommerce.overwriteQuantity(nodeId, quantity);
});

/*
The remove item event
*/
jQuery('a.remove').live('click', function () {
  var jQEle = jQuery(this),
      orderLine = jQEle.closest('.item'),
      nodeId = orderLine.attr('nodeid');

  //Remove a specific orderline
  TeaCommerce.removeOrderLine(nodeId);
  return false;
});

/*
The change shipping method event
*/
jQuery('#shippingMethods input').live("click", function () {
  var shippingMethodId = jQuery(this).val();

  //We call the server and sends the new shipping id
  TeaCommerce.setShippingMethod(shippingMethodId);
});

/*
The change payment method event
*/
jQuery('#paymentMethods input').live("click", function () {
  var paymentMethodId = jQuery(this).val();

  //We call the server and sends the new payment id
  TeaCommerce.setPaymentMethod(paymentMethodId);
});

/*
The next step event on step 2 of the cart
*/
jQuery('#cart.stepProgress02 a#next').live("click", function () {
  var personalInformation = jQuery("#personalInformation"), differentShippingAddress = jQuery("#differentShippingAddress")[0].checked;

  /*
  We fetch the information from the form and creates
  an object that can be sent to the server as a form
  POST submit
  */
  var formObj = {
    "firstName": personalInformation.find("#firstName").val(),
    "lastName": personalInformation.find("#lastName").val(),
    "city": personalInformation.find("#city").val(),
    "zipCode": personalInformation.find("#zipCode").val(),
    "streetAddress": personalInformation.find("#streetAddress").val(),
    "country": personalInformation.find("#country option:selected").text(),
    "phone": personalInformation.find("#phone").val(),
    "email": personalInformation.find("#email").val(),
    "differentShippingAddress": jQuery("#differentShippingAddress")[0].checked,
    "comments": jQuery("#comments").val()
  };
  if (differentShippingAddress) {
    var shippingInformation = jQuery("#shippingInformation");
    formObj["shipping_companyName"] = differentShippingAddress ? shippingInformation.find("#shipping_companyName").val() : "";
    formObj["shipping_firstName"] = shippingInformation.find("#shipping_firstName").val();
    formObj["shipping_lastName"] = shippingInformation.find("#shipping_lastName").val();
    formObj["shipping_city"] = shippingInformation.find("#shipping_city").val();
    formObj["shipping_zipCode"] = shippingInformation.find("#shipping_zipCode").val();
    formObj["shipping_streetAddress"] = shippingInformation.find("#shipping_streetAddress").val();
    formObj["shipping_country"] = shippingInformation.find("#shipping_country option:selected").text();
  }
  //Validation
  var pageValidateText = '';
  if (formObj.firstName == '') {
    pageValidateText += '\nFirst name';
  }
  if (formObj.lastName == '') {
    pageValidateText += '\nLast name';
  }
  if (formObj.email == '') {
    pageValidateText += '\nE-mail';
  }
  if (!jQuery('[name=shippingMethod]:checked')[0]) {
    pageValidateText += '\nShipping method';
  }
  if (!jQuery('[name=paymentMethod]:checked')[0]) {
    pageValidateText += '\nBetalingsmetode';
  }
  if (pageValidateText != '') {
    pageValidateText = 'Husk at udfylde:' + pageValidateText;
    alert(pageValidateText);
    return false;
  }

  /*
  The properties is sent to the server with a syncronous call
  This way we lock the UI and can redirect the user.
  */
  TeaCommerce.updateOrderProperties(formObj, false);
  window.location.href = "/bestillingsliste/gennemse-ordre-trin-3.aspx";
  return false;
});

/*
The next step event on step 3 of the cart
*/
jQuery("#cart.stepProgress03 #next").live("click", function () {

  /*
  TeaCommerce.GoToPayment fetches the payment method from the server
  and redirects the user to the payment provider.
  If the provider is a creditcard-thingy a form is returned from the
  server and the Tea Commerce javascript API submits the form.
  */
  TeaCommerce.goToPayment();
});


/*
The very advanced print event
*/
jQuery("#cart.stepProgress05 #next").live("click", function () {
  window.print();
});

/*
The shipping address should be different to the billing address
*/
jQuery('input#differentShippingAddress').live("click", function () {
  showHideShippingInformation(jQuery(this)[0].checked)
});



/*
**************************************************
- CUFON STUFF
**************************************************
*/
Cufon.replace(topCartCufonSelect + ',' + productCufon + ', .cufonReplace, ' + cartCufonSelect);

/*
**************************************************
- SERVICE METHODS
**************************************************
*/
  
/// <summary>
/// Updates all carts on the page.
/// </summary>
function updateCarts(data) {

  /*
  We use a timer to secure that the user will see our update graphics.
  The caching on the server makes the server calls very fast and
  the user might just se the page blink and will not realise that
  something changed.
  It's important for me to say that i have not yet tested this on
  a live shop. It does though work very well on our test setup.
  */
  submitTimerEnd = (new Date()).getTime() - submitTimer.getTime();

  //Check the timeout to see if it took at least half a second
  if (submitTimerEnd < 500) {

    //If the return call was too fast we delay the call for
    window.setTimeout(function () {
      updateCarts(data);
    }, submitTimerEnd);
    return false;
  }

  /*
  We keep track of the updates made with a counter.
  This way we only need to update the carts when all
  changes have taken place.
  */
  updateCounter--;
  if (updateCounter < 1) {
    //All calls have returned. Now we can start the update of the UI

    var topCart = jQuery('#TopCart'), cart = jQuery('#cart.stepProgress01'), cufonSelect = topCartCufonSelect;
    /*
    The data object holds the return data from the server.
    In these general events the return data will allways be a javascript object.
    */
    //If the data holds an order object, we can update the top cart
    if (data.Order) {

      //Information in the order object is used to update det UI
      topCart.find(".orderTotal").html(data.Order.TotalPriceFormatted);
      topCart.find(".itemsInCart").html(data.Order.TotalQuantity);

      //If the Total quantity has changed we may need to change the class of the top cart
      if (data.Order.TotalQuantity < 1) {
        topCart.addClass('isEmpty');
      } else {
        topCart.removeClass('isEmpty');
      }

      //If there is a cart on the page we can update that
      if (cart[0]) {
        updateCartHtml(cart);
        cufonSelect += ', ' + cartCufonSelect;
      }
      Cufon.replace(cufonSelect);
    }

    //All updates have been made and we can now remove the "updating" class on the top cart.
    topCart.removeClass("updating");

    //the timer is reset and is now ready for the next run
    submitTimer = null;
  }
}

/// <summary>
/// Updates the main cart
/// </summary>
function updateCartHtml(cart) {

  //Check to see if the cart exists
  if (cart[0]) {

    //Fetch the new cart html with invokeXSLT and update the UI
    var cartJqHtml = jQuery(TeaCommerce.invokeXSLT('cartStep01.xslt', _nodeId, _languageId, false, null, null));
    cart.after(cartJqHtml);
    cart.remove();
  }
}

/// <summary>
/// Fetches the html for shipping and payment selection from the server.
/// </summary>
function updateShippingAndPayment() {
  var shippingAndPayment = jQuery("#shippingAndPayment");

  //Check to see that we need to do the update
  if (shippingAndPayment[0]) {

    //Use invokeXSLT to get the new html from the database.
    shippingAndPayment.after(TeaCommerce.invokeXSLT('paymentAndDelivery.xslt', _nodeId, _languageId, false, null, null));
    shippingAndPayment.remove();
    Cufon.replace('#shippingAndPayment .cufonReplace');
  }
}

/// <summary>
/// Fetches the html for the product list from the server.
/// </summary>
function updateProducts() {
  var productList = jQuery("#productList"), featuredProduct = jQuery('#featuredProduct');

  //Check to see  that we have a featured product
  if (featuredProduct[0]) {

    //Use invokeXSLT to get the new html from the database.
    featuredProduct.after(TeaCommerce.invokeXSLT('featuredProduct.xslt', _nodeId, _languageId, false, null, null));
    featuredProduct.remove();
  }

  //Check to see  that we have a product list
  if (productList[0]) {

    //Use invokeXSLT to get the new html from the database.
    productList.html(TeaCommerce.invokeXSLT('productList.xslt', _nodeId, _languageId, false, null, null));
  }
  Cufon.replace(productCufon);
}

/// <summary>
/// Simple method to show or hide the shipping information on cart step 2
/// </summary>
function showHideShippingInformation(show) {
  var shippingInformation = jQuery("#shippingInformation");
  if (show) {
    shippingInformation.css("display", "block");
  } else {
    shippingInformation.css("display", "none");
  }
}
