var ShoppingCart = {
  isReady: false,

  items: {},
  coupons: {},

  onReadyCallbacks: [],

  onReady: function(on_ready_callback) {
    if (this.isReady) {
      on_ready_callback.call(this);
    } else {
      this.onReadyCallbacks.push(on_ready_callback);
    }
  },

  beforeUpdateCallbacks: [],

  beforeUpdate: function(before_update_callback) {
    this.beforeUpdateCallbacks.push(before_update_callback);
  },

  onUpdateCallbacks: [],

  onUpdate: function(on_update_callback) {
    this.onUpdateCallbacks.push(on_update_callback);
  },

  load: function(options) {
    ShoppingCart.isReady = false;

    $.ajax({
      url: "/cart/get",
      success: function (data) {
        ShoppingCart.items    = data.items;
        ShoppingCart.coupons  = data.coupons;
        ShoppingCart.subtotal = data.subtotal;
        ShoppingCart.shipping = data.shipping;
        ShoppingCart.total    = data.total;

        ShoppingCart.isReady = true;
        
        if (options && options.success) {
          options.success(data);
        }

        while (ShoppingCart.onReadyCallbacks.length > 0) {
          ShoppingCart.onReadyCallbacks.pop().call(ShoppingCart);
        }
      }
    });
  },

  update: function(options) {
    $.each(this.beforeUpdateCallbacks, function(i, f) {
      f.call(ShoppingCart);
    });

    var request_data = {item_quantities: {}, coupon_codes: []};

    for (product_id in this.items) {
      request_data.item_quantities[product_id] = this.items[product_id].quantity;
    }

    for (code in this.coupons) {
      request_data.coupon_codes.push(code);
    }

    $.ajax({
      url: "/cart/update",
      type: 'post',
      data: request_data,
      success: function (data) {
        ShoppingCart.items    = data.items;
        ShoppingCart.coupons  = data.coupons;
        ShoppingCart.subtotal = data.subtotal;
        ShoppingCart.shipping = data.shipping;
        ShoppingCart.total    = data.total;

        if (options && options.success) {
          options.success(data);
        }

        $.each(ShoppingCart.onUpdateCallbacks, function(i, f) {
          f.call(ShoppingCart);
        });
      }
    });
  },

  addItem: function(options) {
    options.quantity = parseInt(options.quantity);

    this.onReady(function() {
      if (this.items[options.product_id] == undefined) {
        this.items[options.product_id] = {quantity: options.quantity};
      } else {
        this.items[options.product_id].quantity += options.quantity;
      }

      this.update({success: options.success});
    });
  },

  setItemQuantity: function(options) {
    options.quantity = parseInt(options.quantity);

    this.onReady(function() {
      if (this.items[options.product_id] == undefined) {
        this.items[options.product_id] = {quantity: options.quantity};
      } else {
        this.items[options.product_id].quantity = options.quantity;
      }

      this.update({success: options.success});
    });
  },
  
  removeItems: function(options) {
    var self = this;
    this.onReady(function() {
      $.each(options.product_ids, function(i, id) {
        delete self.items[id];
      })

      this.update({success: options.success});
    });
  },

  removeItem: function(options) {
    this.onReady(function() {
      delete this.items[options.product_id];

      this.update({success: options.success});
    });
  },

  getTotalCount: function(options) {
    var total_count = 0;

    jQuery.each(ShoppingCart.items, function(product_id, item) {
      total_count += item.quantity;
    });

    return total_count;
  },
  
  itemsArray: function() {
    var items = [];
    
    $.each(this.items, function(i, item) {
      items.push(item);
    });
    
    return items;
  }
};

jQuery(ShoppingCart.load);

