/*
 * model.js
 *   Javascript Datamodel
 */

var ec;
if (!ec) { ec = new Object(); }

/***********************************
 *  Address Class
 *   name
 **********************************/
ec.Address = function(attrs) {
    for (var a in attrs) {
        this[a] = attrs[a];
    }
};

ec.Address.prototype.isUS = function() {
    return this.country.code == 'us';
};

/***********************************
 * CartItem Class
 *   NOTE: this does not match the ECE model exactly -
 *   this has shipping info on a per-item basis, not a per-shipping segment basis.
 *
 *   price
 *   quantity
 *   product_id
 *   product_name
 *   product_variant_id
 *   product_variant_name
 *   product_instance_id  (opt)
 *   shipping_address
 *   shipping_method_id
 *   shipping_address_id
 **********************************/

ec.CartItem = function(attrs) {
    for (var a in attrs) {
        this[a] = attrs[a];
    }
    this.changeListeners = new Array();
    this.shippingChangeListeners = new Array();
};

ec.CartItem.prototype.addChangeListener = function(cb) {
    this.changeListeners.push(cb);
};

ec.CartItem.prototype.notifyChangeListeners = function() {
    var me = this;
    this.changeListeners.foreach(function(cb) {
        cb.call(null, me);
    });
};

ec.CartItem.prototype.setAddress = function(addy, silent) {
    this.shipping_address = addy;
    this.shipping_address_id = addy ? addy.address_id : undefined;
    if (!silent) { this.notifyShippingChangeListeners(); }
};

ec.CartItem.prototype.addShippingChangeListener = function(cb) {
    this.shippingChangeListeners.push(cb);
};

ec.CartItem.prototype.notifyShippingChangeListeners = function() {
    var me = this;
    this.shippingChangeListeners.foreach(function(cb) {
        cb.call(null, me);
    });
};


/***********************************
 *  Cart Class
 *
 **********************************/

ec.Cart = function(items, discounts) {
    this._items = items || new Array();
    this._discounts = discounts || new Array();
    this.changeListeners = new Array();
};

ec.Cart.prototype.addChangeListener = function(cb) {
    this.changeListeners.push(cb);
};

ec.Cart.prototype.notifyChangeListeners = function() {
    var me = this;
    this.changeListeners.foreach(function(cb) {
        cb.call(null, me);
    });
};

ec.Cart.prototype.itemTotal = function() {
    var total = 0;
    this._items.foreach(function (i) {
        total = total + Number((i.price || 0));
    });
    return total;
};

ec.Cart.prototype.shippingTotal = function() {
    var total = 0;
    this._items.foreach(function (i) {
        total = total + Number((i.shipping_cost || 0));
    });
    return total;
};

ec.Cart.prototype.taxTotal = function() {
    var total = 0;
    this._items.foreach(function (i) {
        total = total + Number((i.taxes || 0));
    });
    return total;
};

ec.Cart.prototype.grandTotal = function() {
    var total = 0;
    this._items.foreach(function (i) {
        total = total + Number((i.shipping_cost || 0))
                      + Number((i.price || 0))
                      + Number((i.taxes || 0));
    });
    this._discounts.foreach(function (d) {
        total = total - Number(d.amount || 0);
    });
    return total;
};

ec.Cart.prototype.foreach = function(f) {
    this._items.foreach(f);
};

ec.Cart.prototype.grep = function(f) {
    return this._items.grep(f);
};

ec.Cart.prototype.count = function() {
    return this._items.length;
};

ec.Cart.prototype.addItem = function(item) {
    this._items.push(item);
    this.notifyChangeListeners();
};

ec.Cart.prototype.removeItemById = function(id) {
    if (id instanceof Array) {
        this._items = this._items.grep(function(i) { return !id.member(i.order_item_id); });
    } else {
        this._items = this._items.grep(function(i) { return i.order_item_id != id; });
    }
    this.notifyChangeListeners();
};

ec.Cart.prototype.getItemById = function(id) {
    return this._items.grep(function(i) { return i.order_item_id == id; })[0];
};

ec.Cart.prototype.setDiscounts = function(d) {
    this._discounts = d;
};

/**************************************************
 *    AppliedDiscount Class
 **************************************************/

ec.AppliedDiscount = function(attrs) {
    for (var a in attrs) {
        this[a] = attrs[a];
    }
};
