/**
 * This file contains functions which can and should be modified in order to
 * facilitate integration with the backend system
 */

/**
 * When the user tries to add a product to the basket, this function is called to validate the form
 * This function is also called every time the user makes a change to select boxes within the form
 * If the form is not valid, the submit button will appear greyed out. As soon as the form becomes valid, this should be return to it's original state
 * @param object form
 *   The form object from which the user pressed "add to basket"
 * @param bool highlightErrors
 *   if this is set to TRUE, add 'has_errors' class to surrounding fieldset so the field can be styled from the CSS
 */
function check_product_form(form, highlightErrors, resetErrors) {
  // loop through the fieldsets in a form, finding out if any are valid.
  // We need at least 1 valid fieldset in order to let the product be bought
  var
  hasQuantity = false,
  totalQuantity = 0,  // Keep track of the total number of products to be added - used to prevent suits being added with no components
  $requiredFieldsets = jQuery('fieldset.required-group', form);

  // Fire a custom event after validation for use elsewhere
  $requiredFieldsets.trigger('beforeValidate').addClass('valid');

  jQuery('select', form).each(function(index, select) {
    var 
    $select = jQuery(select),
    $fieldset = $select.closest('fieldset'),
    $requiredFieldset = $select.parents('fieldset.required-group');

    if ($requiredFieldset.is('*') && resetErrors) {
      $requiredFieldset.removeClass('has_errors');
    }

    var quantitySelect = ($select.attr('name').match(/quantity$/));

    // Keep track of the total quantity of this product
    if (quantitySelect) {
      hasQuantity = true;
      totalQuantity += parseInt($select.val());
    }

    if ($requiredFieldset.length > 0) {

      // Find out if the selected item is unavailable by checking for the presence of the "sold_out" span inside the associated sSelect
      var $unavailable = jQuery('a.tooltip_link[href=#' + $select.attr('name') + '] span.sold_out').length === 1;

      if ((quantitySelect && $select.val() == 0) || $select.val().length === 0 || $unavailable) {
        $requiredFieldset.removeClass('valid');

        if (highlightErrors) {
          $fieldset.addClass('has_errors');
        }
      } else {
        $fieldset.removeClass('has_errors');
      }
    }
  });

  // Validate fieldset with radio buttons (mainly used on Suits grid)
  (function(){

    var
    $radio = jQuery('input[type=radio]', form),
    isChecked = $radio.is(':checked'),
    $fieldset = $radio.closest('fieldset').eq(0),
    $requiredFieldset = $radio.parents('fieldset.required-group');

    if ($requiredFieldset.is('*') && resetErrors) {
      $requiredFieldset.removeClass('has_errors');
    }

    if ($requiredFieldset.length > 0) {

      if (!isChecked) {
        $requiredFieldset.removeClass('valid');

        if (highlightErrors) {
          $fieldset.addClass('has_errors');
        }
      } else {
        $fieldset.removeClass('has_errors');
      }
      
    $fieldset.trigger('afterValidate');
    
    }
    
  }());
  

  if (resetErrors)
    jQuery('fieldset.required-group .has_errors', form).removeClass('has_errors');

  var $fieldsets = jQuery('fieldset.required-group', form);

  // Fire a custom event after validation for use elsewhere
  $requiredFieldsets.trigger('afterValidate');

  // If the user hasn't selected anything at all, highlight the quantity drop downs to indicate that you can't add a "null" suit to the basket
  if(highlightErrors && (totalQuantity === 0)) {
    jQuery('fieldset.quantity', form).addClass('has_errors');
  }

  // Check that none of the fieldsets contain errors, and that there is at least one valid fieldset
  if ((jQuery('.has_errors', $fieldsets).length == 0 && ($fieldsets.filter('.valid').length > 0 || $fieldsets.length == 0))) {
//    jQuery('#ctl00_contentBody_ctl01_submit', form).fadeTo(500, 1);
    jQuery('#submit', form).fadeTo(500, 1);
    return false;
  } else {
//    jQuery('#ctl00_contentBody_ctl01_submit', form).fadeTo(500, 1);
    jQuery('#submit', form).fadeTo(500, 0.5);
    return true;
  }
}

/**
 * After adding a product is added to the basket, this function is called if the server returns a
 * URL in the JSON data using the show_lightbox variable
 * @param string url
 *   The URL which of the content with will be displayed within the lgihtbox
 */
function post_basketadd_lightbox(url) {
  jQuery.get(url, function (data) {
    lightbox = jQuery(data);
    lightbox.addClass('modal');

    jQuery('body').append(lightbox);

    lightbox.overlay({
      mask: {
        color: '#1a263f',
        loadSpeed: 200,
        opacity: 0.34
      },
      top: 'center',
      close: '.close',
      load: true,
      onLoad: function() {
        var overlay = this.getOverlay(),
            overlay_api = this;
        overlay.data('initalScrollLocation', jQuery(overlay).offset().top);

        // Check form on modal load
        check_product_form(jQuery('.modal form.prod_opts'), false);
        
        jQuery('.modal form.prod_opts').submit(function (e) {
          var $form = jQuery(this);
          // Check to see if the product form is valid, passing highlightErrors as true so that errors are visually flagged
          if (!check_product_form($form, true)) {
            if ($form.hasClass('ajaxify')) {
              
              // Update contents of lightbox following successful form submit
              // (should this DOM manupulation stuff go in ctshirts.js?)
              
              // Define English and German messages and image paths
              var page = jQuery('#page');
              if (page.hasClass('de')) {
              
                // @James, add German header text here
                var $modal_h2_txt = 'German header';
                // Insert language component into button path
                var $btn_path = '/DE';

              } else {
                var $modal_h2_txt = 'Your free [product name] has been added';
                var $btn_path = '/GB'; 
              }
              
              // Update header, hide product options and offer button to Checkout
              var $modal_h2 = jQuery('.modal .grid_5 .header h2,.modal .grid_4 .header h2');
              $modal_h2.text($modal_h2_txt);
              jQuery('.modal .grid_4 .header p').remove();
              $form
                .before('<div class="bt"><a href="checkout_checkout.html" id="submit"><img alt="Pay for other items" src="static/img/ui' + ($btn_path) + '/bt_pay_4_other_items.png" /></a></div>')
                .addClass('hidden');

              // When user adds a free product to basket, disable/hide any other visible products so they can't also be submitted
              if (jQuery('.modal').hasClass('free_product_list')) {
                var $selected_mod = $form.parents('.mod'); // Get container for this product
                var $other_mods = $selected_mod.siblings(); // Get the other product containers in this window
                jQuery($other_mods).each(function () {
                    jQuery(this).remove(); // Remove them so users can't easily submit more products
                });
              }

              if (jQuery('.modal .carousel').length) {

                var $current_item = $form.parents('.article'), // Get the current item of the carousel
                    carousel_api = jQuery('.modal .carousel').data('scrollable'); // Get the scrollable API
                     
                   // Get all the carousel items
                  carousel_api.getItems()
                    // that aren't current item 
                    .not($current_item)
                      // and remove them from DOM.
                      .remove();
                      
                  // Now, get the arrows
                  carousel_api.getNaviButtons()
                    // and make them invisible
                    .css('visibility','hidden');

                  carousel_api.getItemWrap().css('left','0');
              }

              // Prevent the form from being submitted
              e.preventDefault();

            }
            return true;
          }

          // Prevent the form from being submitted
          e.preventDefault();
        });
        
        jQuery('.modal .tooltip_link').each(function (i) {
          var $link = jQuery(this);
          var $menu = jQuery($link.attr('href'));

          // Escape if menu doesn't exist
          if (!$menu.is('*')) return;

          var trigger_width  = $link.width();
          var trigger_height = $link.height();

          // Move menu to document
          $menu
            .data('link', $link)
            .appendTo(document.body)
            .addClass('closed')
            .hide();

          // Hide the real html form
          jQuery('#' + $menu.attr('id') + '_selected').hide();

          $link.click(function (e) {
            if ($menu.hasClass('closed')) {
              // Position the menu
              $menu.css({ "position": "absolute", "top": $link.offset().top, "left": $link.offset().left });
              // Open the menu
              $menu.removeClass('closed').addClass('open').fadeIn('fast', function () {
                // Hide tooltips on click-out
                jQuery(document).one('click.tooltips', function(e) {
                  jQuery('.select_details.open').each(function () {
                    jQuery(this).data('link').click();
                  });
                });
              });
            }
            else if ($menu.hasClass('open')) {
              // Close the menu
              $menu.removeClass('open').addClass('closed').fadeOut('fast', function () {
                // Reenable document clicks
                jQuery(document).unbind('click.tooltips');
              });
            }

            e.preventDefault();
          });

          // Turn every link into a clickable item
          jQuery('li a, dd a', $menu).live('click', function(e) {
            jQuery.CT.common.setSelectedFormItem(this);
            jQuery(document).trigger('click.tooltips');
            e.preventDefault();
          });

          // When the page is loaded, if there is anything in hidden select boxes, populate the fake select boxes with the value
          jQuery('form.prod_opts select').each(function (index, item) {
            value = jQuery(item).val();
            if (value.length > 0) {
              jQuery('#' + jQuery(item).attr('name') + ' a[href=#' + value + ']').click();
            }
          });
        });

        jQuery('.modal select:not([name=sleeve_length]):not([name=collar_size]):not([name=jckt_chest]):not([name=slv_lngth]):not([name=trsrs_waist]):not([name=trsrs_leg]):not([name=wcoat_chest]):not([name^=shoe_size])').sSelect();
        jQuery('.modal .carousel').scrollable({speed: 1200});
        jQuery('.modal input:checkbox, .modal input:radio').uniform({
          checkboxClass: 'control',
          radioClass: 'control'
        });
        
      },
      onClose: function() {
        lightbox.remove();
      }
    });
  });
}

/**
 * Return the DOM object for a product as it appears in the mini basket
 * @see generate_product()
 *   If the format of the product object is changed in generate_product(), this function may need to be updated
 */
function theme_basket_product(product) {
  output = jQuery('<dd></dd>');
  output.append(jQuery('<a href="' + product.href + '" class="img"><img src="' + product.img + '" width="104" height="104" alt="' + product.title + '" /></a>'));
  output.append(jQuery('<h3><a href="' + product.href + '">' + product.title + '</a></h3>'));
  output.append(jQuery('<p class="meta price"><strong>' + product.price + '</strong></p>'));

  return output;
}

/**
 * This function can be used to add a product to the basket
 * This function is called when the user submits a product form, provided that form has passed validation
 * and provided a lightbox hasn't blocked the submission.
 * N.B. THIS FUNCTION IS INCOMPLETE. This function should make an AJAX call in order to add the product
 * @see check_product_form()
 * @param object product
 *   An object representing the product to be added. use "console.log(product)" to see an example in firebug
 *   This object will look something like this:
 *      product = {
 *        sku: 'abc123',
 *        title: 'title of product',
 *        href: '/path/to/product',
 *        img: '/url/to/product/image.jpg',
 *        price: '&pound;100',
 *        data: {[
 *          0: { name: 'cuff_type', value: 'double' },
 *          1: { name: 'foo', value: 'bar' },
 *        ]}
 *      };
 */
var animate_basket = true;
var basket_up_timer;
function basket_add(product, form) {
    // Remove empty class
    jQuery('#bsk_contents dl.teasers').removeClass('empty');

    jQuery('#bsk_contents').one('add_item', function(event, product) {
      // Add the item to the basket
      product_html = theme_basket_product(product);
      jQuery('dl', this).append(product_html);

      // Highlight the item that was added
      product_html.fadeIn('fast', function() {
        jQuery(this).effect('highlight', { color: '#F2F2F2' }, 3000);
      });

      // Update the basket quantity
      basket_quantity = jQuery('#bsk_contents dd:not(.empty)').size();
      jQuery('.bskt_items .qty').text(basket_quantity);

      /* ------------------------------------------------------- */
      /* MAKE AJAX CALL HERE, TO ADD PRODUCT TO BASKET ON SERVER */
      /* ------------------------------------------------------- */
      //_ajax_to_server(form, "basket=true&basket_quantity=" + basket_quantity);
      //CT
      //Ajax call to add to basket
      AddBasketItem();
    })

    if (jQuery('#bsk_contents.open').is('*')) {
      // Just add the item as the basket overlay is open
      jQuery('#bsk_contents').trigger('add_item', product);
    }
    else {
      // Hide all items it the basket
      jQuery('#bsk_contents dd').hide();

      // Add the new item to the basket
      jQuery('#bsk_contents').trigger('add_item', product);

      if (!animate_basket) return;

      if(jQuery.browser.msie && jQuery.browser.version < 7) {
        jQuery('html, body').scrollTop(0);
      } else {
        // Fix basket_nav to the top of the 'viewport'
        jQuery('#basket_nav')
          .before('<div id="basket_nav_spacer" />')
          .wrap('<div id="basket_nav_wrap" />');

        // Basket wrap close animation
        jQuery('#basket_nav_wrap').bind('close', function () {
          jQuery(this).animate(
            { top: '-=' + (jQuery('#basket_nav').offset().top - 24) }, 'fast', 'linear',
            function () {
              if (jQuery('#basket_nav_wrap').is('*')) jQuery('#basket_nav').unwrap();
              jQuery('#basket_nav_spacer').remove();
              basket_close();
            }
          );
        })
      }

      // Slide down the basket overlay
      jQuery('#bsk_contents')
        .addClass('open')
        .slideDown('fast', function () { jQuery.UTIL.fire('ie', 'sync_shadow_stop'); });
      jQuery.UTIL.fire('ie', 'sync_shadow');
    }

    // After 3 seconds slide basket overlay back up again
    clearTimeout(basket_up_timer);
    basket_up_timer = setTimeout(function() { basket_close(); }, 3000);
}

function basket_close() {
  if (jQuery('#basket_nav_wrap').is('*')) jQuery('#basket_nav_wrap').trigger('close');
  else {
    jQuery('#bsk_contents').removeClass('open').slideUp('fast', function () { jQuery.UTIL.fire('ie', 'sync_shadow_stop'); }); // Basket close animation
    jQuery.UTIL.fire('ie', 'sync_shadow');
  }
}

/**
 * This function is used to make an AJAX call to the serve and update parts of the current page.
 * E.G. totals and titles
 * This function is called when product options are updated or when an item is added to the basket.
 * N.B. THIS FUNCTION WILL PROBABLY NEED MODIFYING. Currently _update_totals.html returns a JSON formatted array
 * with values to be updated - depending on how the server side basket works this function might need to change
 */
function _ajax_to_server(form, extra_data) {

  // Put the form data onto an array
  data = jQuery(form).serializeArray();

  // Loop over the data we're about to pass
  // For jackets, trousers and waistcoats, test to see if they are a "valid" item (i.e. no elements are sold out)
  // If any part of them is sold out, we lie and send a zero quantity for that item, to force the server side
  // script to return the default message which is displayed when you haven't chosen that product yet (E.g. Add Trousers 29.95 each)
  // The alternative method to this (not implemented), would be to pass the sold out status to the server and perform this logic there instead
  jQuery(data).each(function(index, element){
    // Jackets
    if(element.name === 'jckt_quantity') {
      if(jQuery('a[href=#jckt_chest] span.sold_out', form).length > 0 || jQuery('a[href=#slv_lngth] span.sold_out', form).length > 0) {
        element.value = 0;
      }
    }

    // Trousers
    if(element.name === 'trsrs_quantity') {
      if(jQuery('a[href=#trsrs_waist] span.sold_out', form).length > 0 || jQuery('a[href=#trsrs_leg] span.sold_out', form).length > 0) {
        element.value = 0;
      }
    }

    // Waistcoats
    if(element.name === 'wcoat_quantity') {
      if(jQuery('a[href=#wcoat_chest] span.sold_out', form).length > 0) {
        element.value = 0;
      }
    }
  });

  // Serialise the data ready for use as a query string
  data = jQuery.param(data);

  // Add any extra data onto the query string
  if (extra_data) data = data + '&' + extra_data;

  // Make the ajax call
  jQuery.ajax({
    async:    false,
    url:      'http://www.develop.ct.shopfrontui.com/_update_totals.php',
    type:     'POST',
    dataType: 'json',
    data:     data,
    success:  function(data) {
      // Depending on what is returned by the server, we update the titles of the relevant fieldsets

      //jacket
      if (typeof(data.jacket_title) !== 'undefined')
        jQuery('#jckt a.target_link strong').text(data.jacket_title);

      if (typeof(data.jacket_selected_title) !== 'undefined')
        jQuery('#jckt a.target_link .slct_opt').text(data.jacket_selected_title);
      if (typeof(data.jacket_total) !== 'undefined') {
        jQuery('#jckt')
          .addClass('has_slct')
          .find('a.target_link .price').text(data.jacket_total);
      } else {
        jQuery('#jckt')
          .removeClass('has_slct')
          .find('a.target_link .price').text(data.jacket_base_price + ' each');
      }
      jQuery('#jckt .quantity_gt0').toggle((data.jacket_quantity > 0));

      //trousers

      if (typeof(data.trousers_title) !== 'undefined')
        jQuery('#trsrs a.target_link strong').text(data.trousers_title);
      if (typeof(data.trousers_selected_title) !== 'undefined')
        jQuery('#trsrs a.target_link .slct_opt').text(data.trousers_selected_title);
      if (typeof(data.trousers_total) !== 'undefined') {
        jQuery('#trsrs')
          .addClass('has_slct')
          .find('a.target_link .price').text(data.trousers_total);
      } else {
        jQuery('#trsrs')
          .removeClass('has_slct')
          .find('a.target_link .price').text(data.trousers_base_price + ' each');
      }
      jQuery('#trsrs .quantity_gt0').toggle((data.trousers_quantity > 0));

      //waistcoat
      if (typeof(data.waistcoat_title) !== 'undefined')
        jQuery('#wcoat a.target_link strong').text(data.waistcoat_title);
      if (typeof(data.waistcoat_selected_title) !== 'undefined')
        jQuery('#wcoat a.target_link .slct_opt').text(data.waistcoat_selected_title);
      if (typeof(data.waistcoat_total) !== 'undefined') {
        jQuery('#wcoat')
          .addClass('has_slct')
          .find('a.target_link .price').text(data.waistcoat_total);
      } else {
        jQuery('#wcoat')
          .removeClass('has_slct')
          .find('a.target_link .price').text(data.waistcoat_base_price + ' each');
      }
      jQuery('#wcoat .quantity_gt0').toggle((data.waistcoat_quantity > 0));

      //product total
      if (data.product_total) {
        jQuery('.total strong').html(data.product_total);
      }

      //basket total
      if (data.basket_total) {
        jQuery('.bskt_total a').html(data.basket_total);
        Cufon.set('fontFamily', 'Avenir');
        Cufon.replace('.bskt_total');
      }

      // If the object returned by the server contains a "show_lightbox" property then a lightbox will be shown
      // This should contain a url which returns the html contents of the lightbox
      if (typeof(data.show_lightbox) !== 'undefined') {
        post_basketadd_lightbox(data.show_lightbox);
        animate_basket = false;
      } else
        animate_basket = true;
    }
  });
}

/**
 * Simple callback function to generate a product from a given product form
 * This function should be modified to provide real data
 * @see theme_basket_product()
 *   If the format of the product object is changed, theme_basket_product() may need to be updated to compensate
 */
function generate_product(prod_form) {
  // To simulate different images on different product categories
  /*
  var img = '/content/img/products/shirt_thumb_104px.jpg';
  if (jQuery('body').is('.shirts')) {
   var img = '/content/img/products/shirt_thumb_104px.jpg';
  } else if (jQuery('body').is('.suits')) {
   var img = '/content/img/products/suit_thumb_104px.jpg';
  } else if (jQuery('body').is('#simple.sale')) {
   var img = '/content/img/products/tie_thumb_104px.jpg';
  }
  */

  //CT
  //Get the image from web server
  return {
    sku: jQuery('#prod_id .sku').text(),
    title: jQuery('#prod_id h1').text(),
    href: window.location,
    //img: img,
    //price: '&pound;29.95',
    img: '/Proimages/' + jQuery('#prod_id .sku').text() + '_13.jpg',
    price: jQuery('#prod_price .price').text(),
    data: jQuery(prod_form).serializeArray()  /* Serialize the form fields onto the product object to allow for processing */
  };
}

/**
 * Update pseudo selects with a new set of options
 * @param object selector
 *   jQuery object targeting the actual <select> element
 * @param object options
 *   Object containing the new contents of the select elements
 */
function update_select($select, options) {
	// Store the current value
	var old_value = $select.val();

	// Find the pseudo select associated with the real select
	$pseudo_select = jQuery('#' + $select.attr('name'));

	// Clear out the old elements and replace them with the new ones
	$select
		.find('option')
			.remove()
		.end()
		.append(options.d[0]);

	$pseudo_select
		.find('dt, dd')
			.remove()
		.end()
		.append(options.d[1]);

	// Check to see whether the previously selected value is still present in the new options
	// If it is, then reselect it
	// If not, reset the value to "Please select"
	$old_pseudo_item = jQuery('a[href=#' + old_value + ']', $pseudo_select);

	if($old_pseudo_item.length > 0) {
		$old_pseudo_item.click();
	} else {
		$select
			.prev('h3')
			.find('a.tooltip_link strong')
			.text(t('Please select'));
	}
}

// For a given input string, attempt to find a translation in the localised_strings object
// If none is found, the original string is returned
function t(inputString) {
   if(localised_strings[inputString][jQuery('meta[http-equiv=content-language]').attr('content')]) {
     return localised_strings[inputString][jQuery('meta[http-equiv=content-language]').attr('content')];
   } else {
     return inputString;
   }
}

// This object contains localised strings, keyed by the original string and then target language
// <meta http-equiv="content-language" content="" />
var localised_strings = {
  'Gift message must not be longer than 120 characters': {
    'fr': 'Add translation here'
  },
  '<p>Gift message <em>Allow 2 days for boxing</em></p>': {
    'de': '<p>Add translation <em>here</em></p>'
  },
  'Choose from my address book': {
    'de': 'Aus Adressbuch ausw&auml;hlen'
  },
  'Please add some initials': {
    'de': 'Geben Sie die Buchstaben ein, aus denen Ihr Monogramm bestehen soll'
  }
  
  
}

function pageReadyAgain()
{
	jQuery(document).ReadyAgain();
}

//CT
//For Live Chat Popup
function LiveChat(inLocation) {

  var NewPopWin = null;
  if (NewPopWin != null) {
    if (!NewPopWin.closed) {
      NewPopWin.close();
    }
  }
  NewPopWin = window.open(inLocation, null, 'menubar=no,width=930,height=600,toolbar=no,scrollbars=yes', true);
}


// This function saves the selected address picked from the address list in the lightbox to the database
function update_address_from_list(addressNo, shippingType) {

  UpdateAddressFromList(addressNo, shippingType);

}


// The user has clicked on the radio option to deliver all items together for out of stock items.
// Toggle display the delivery methods according to customer shipping address or the selected country in dropdown
function update_delivery_together_shipping() {

  UpdateDeliveryTogetherShipping();

}
