/*
 * @class   Cart
 * @author  EtienneLem
 * @company Hatem+D
 */

var Cart = function() { this.initialize.apply(this, arguments) };
Cart.prototype = (function() { var pro = {};
  
  // public ----------------------------------------------
  pro.initialize = function(opts) {
      initialize();
  };
  
  pro.cart = function() { return cart };
  
  
  //  private --------------------------------------------
  var articles      =  null,
      cart          = [],
      drinksQty     = 0,
      table         = $('#commander table tbody'),
      priceElem     = table.find('.total .price span');
      qtyElem       = table.find('.total .value'),
      drinksElem    = table.find('.breuvages .value'),
      drinks        = $('.breuvage'),
      linkCommander = $('#btn-commander > a'),
      btnSubmit     = $('#btn-submit'),
      formEnabled   = false,
      hiddenInput   = $('#cart');
  
  //  Initialisation
  var initialize = function()
  {
      initArticles();
      initDrinks();
  };
  
  // Object management
  var updateObjectValue = function ( id, value )
  {
      getObject(id).qty = value;
      calculatePrice();
  };
  
  var getObject = function ( id )
  {
      var object = null;
      for ( var i=0, l=cart.length; i < l; i++ ) {
        var obj = cart[i];
        if (obj.id == id) {
          object = obj;
          break;
        }
      }
      
      return object;
  };
  
  //  Articles management
  var initArticles = function()
  {
      articles = $('article').map(function(i){
        $(this).data('id', i);
        return ($(this).find('.checkbox').size() > 0) ? this : null;
      });
      
      articles.find('a').bind('click', onArticleClick);
      articles.find('input').bind('change', onArticleChange);
  };
  
  var onArticleClick = function ( e )
  {
      var article = $(this).parents('article');
      
      article.toggleClass('selected');
      if (article.hasClass('selected')) addArticle(article);
      else removeArticle(article);
  };
  
  var addArticle = function ( article )
  {
      var input = article.find('input'),
          obj   = {};
      
      obj.id          = article.data('id');
      obj.elem        = article;
      obj.title       = article.children('h5').html();
      obj.price       = article.children('span').html();
      obj.dessert     = (article.parents('.chaude').size() > 0);
      obj.hasDessert  = false;
      
      var minQty = ( obj.dessert ) ? 5 : 3;
      if ( input.val() < minQty ) input.val(minQty);
      obj.qty = input.val();
      
      cart.push(obj);
      addToRecap(obj);
      calculatePrice();
      triggerLink();
  };
  
  var triggerLink = function()
  {
      linkCommander.addClass('hover');
      setTimeout(function(){
        linkCommander.removeClass('hover');
      }, 750);
  };
  
  var removeArticle = function ( article )
  {
      var obj = getObject(article.data('id'));
      removeFromRecap(obj.id);
      cart.splice(cart.indexOf(obj), 1);
      calculatePrice();
  };
  
  var onArticleChange = function ( e )
  {
      var input   = $(this),
          value   = input.val(),
          article = input.parents('article'),
          id      = article.data('id'),
          chaud   = (article.parents('.chaude').size() > 0),
          minQty  = ( chaud ) ? 5 : 3;
      
      if ( value == 0 ) article.find('a').trigger('click');
      else {
        if ( value < minQty ) {
          input.val(minQty)
          value = minQty;
          alert('Minimum de '+minQty+' boîtes à lunch de ce type.');
        }
        updateObjectValue(id, value);
        updateRecapValue(id, value);
        triggerLink();
      }
  };
  
  var updateArticleValue = function ( id, value )
  {
      var article = getArticle(id)
      article.find('input').val(value);
  };
  
  var getArticle = function ( id )
  {
      var article = null;
      articles.each(function(i){
        var elem = $(this);
        if ( elem.data('id') == id ) article = elem;
      });
      
      return article;
  };
  
  // Recap management
  var addToRecap = function ( obj )
  {
      var tr      = document.createElement('tr'),
          title   = document.createElement('td'),
          price   = document.createElement('td'),
          qty     = document.createElement('td'),
          action  = document.createElement('td'),
          article = getArticle(obj.id);
      
      title.className = 'title';
      title.innerHTML = obj.title;
      
      price.className = 'price';
      price.innerHTML = obj.price;
      
      qty.className = 'qty';
      $(qty).append('<span class="label">Qté:</span> <input type="text" value="'+obj.qty+'" />');
      $(qty).find('input').bind('change', onRecapChange);
      
      action.className = 'action';
      $(action).append('<a href="#">+</a>');
      $(action).children('a').bind('click', onDeleteRecapClick);
      
      $(tr).append(title, price, qty, action).data('id', obj.id);
      table.find('.breuvages').before(tr);
      
      if ( obj.dessert ) {
        var trDessert     = document.createElement('tr'),
            titleDessert  = document.createElement('td'),
            priceDessert  = document.createElement('td'),
            qtyDessert    = document.createElement('td'),
            actionDessert = document.createElement('td');
        
        titleDessert.className = 'title';
        $(titleDessert).append('<a href="#"><div class="checkbox"></div><span>desserts (spécialité du chef)</span></a>');
        $(titleDessert).children('a').bind('click', function(e){
          e.preventDefault();
          var link = $(this);
          link.toggleClass('checked');
          obj.hasDessert = ( link.hasClass('checked') );
          calculatePrice();
        });
        
        priceDessert.className = 'price';
        priceDessert.innerHTML = '1,75';
        
        qtyDessert.className = 'qty';
        actionDessert.className = 'action';
        
        trDessert.className = 'dessert';
        $(trDessert).append(titleDessert, priceDessert, qtyDessert, actionDessert);
        
        tr.className = 'chaud';
        $(tr).after(trDessert);
      }
  };
  
  var onDeleteRecapClick = function ( e )
  {
      e.preventDefault();
      
      var id = $(this).parents('tr').data('id');
      getArticle(id).find('a').trigger('click');
  };
  
  var onRecapChange = function ( e )
  {
      var input   = $(this),
          value   = input.val(),
          tr      = input.parents('tr'),
          id      = tr.data('id'),
          chaud   = tr.hasClass('chaud'),
          minQty  = ( chaud ) ? 5 : 3;
      
      if ( value == 0 ) getArticle(id).find('a').trigger('click');
      else {
        if ( value < minQty ) {
          input.val(minQty)
          value = minQty;
          alert('Minimum de '+minQty+' boîtes à lunch de ce type.');
        }
        updateObjectValue(id, value);
        updateArticleValue(id, value);
      }
  };
  
  var removeFromRecap = function ( id )
  {
      var tr  = getTr(id),
          obj = getObject(id);
      
      if ( obj.dessert ) tr.next('tr').remove();
      tr.remove();
  };
  
  var updateRecapValue = function ( id, value )
  {
      var tr    = getTr(id),
          input = tr.find('input');
      
      input.val(value);
  };
  
  var getTr = function ( id )
  {
      var allTr = table.find('tr'),
          tr    = null;
      
      allTr.each(function(i){
        if ( $(this).data('id') == id ) tr = $(this);
      });
      
      return tr;
  };
  
  // Drinks management
  var initDrinks = function()
  {
      drinks.each(function(i){
        var drink = $(this),
            input = drink.children('input'),
            link  = drink.children('a');
        
        input.bind('keyup', function(){
          var elem = $(this);
          if ( isNaN(elem.val()) ) elem.val(0);
          drinksQty = 0;
          
          drinks.each(function(i){
            drinksQty += Number($(this).children('input').val());
          });
          
          drinksElem.html(drinksQty);
          calculatePrice();
        });
        
        link.bind('click', function(){
          input.val(Number(input.val())+1);
          input.trigger('keyup');
        });
      });
  };
  
  // Price management
  var calculatePrice = function()
  {
      var totalPrice  = 0,
          totalQty    = 0,
          formated    = '',
          minQty      = 6;
      
      for ( var i=0, l=cart.length; i < l; i++ ) {
        var obj       = cart[i],
            price     = Number(obj.price.replace(',', '')),
            qty       = Number(obj.qty),
            subtotal  = (price * qty);
        
        totalPrice  += subtotal;
        if ( obj.hasDessert ) totalPrice += (175 * qty);
        if ( obj.dessert ) minQty = 10;
        
        totalQty += qty;
      }
      
      totalPrice += (150 * drinksQty);
      
      if ( totalQty >= minQty ) enableForm();
      else disableForm(minQty, totalQty);
      
      formated = (totalPrice / 100).toFixed(2);
      formated = formated.replace('.', ',');
      priceElem.html(formated);
      qtyElem.html(totalQty);
      
      var qtyHtml = ( totalQty > 0 ) ? ' ('+totalQty+')' : '';
      linkCommander.html('Commander'+qtyHtml);
      updateCartInput();
  };
  
  var updateCartInput = function()
  {
      var cartString = '';
      
      // Articles
      for (var i=0; i < cart.length; i++) {
        var object = jQuery.extend(true, {}, cart[i]);
        delete object.id;
        delete object.elem;
        delete object.dessert;
        object.price = object.price.replace(',','').toString();
        object.hasDessert = object.hasDessert.toString();
        
        var item = JSON.stringify(object);
        if ( i > 0 )  cartString += '#' + item;
        else          cartString = item;
      };
      
      // Drinks
      var indexDrink = 0;
      drinks.each(function(i){
        var drink = $(this);
            input = drink.children('input'),
            qty   = input.val(),
            label = drink.children('label').html();
            
        if ( qty > 0 ) {
          var sep = ( indexDrink == 0 ) ? '|' : '#';
          cartString += sep + JSON.stringify({title:label, qty:qty});
          indexDrink++;
        }
      });
      
      hiddenInput.val(cartString);
  };
  
  var enableForm = function()
  {
      if ( formEnabled ) return;
      formEnabled = true;
      btnSubmit.removeAttr('disabled');
      btnSubmit.val('Commander');
  };
  
  var disableForm = function ( minQty, totalQty )
  {
      var diff          = minQty - totalQty,
          articleLabel  = (diff == 1) ? 'article' : 'articles';
      formEnabled = false;
      btnSubmit.attr('disabled', 'disabled');
      btnSubmit.val('Il vous manque ' + diff + ' ' + articleLabel);
  };
  
return pro })();
