generic.checkout = {};

/**
 * generic.checkout.cart 
 * - depends on: generic.cookie, generic.jsonrpc
 */ 
generic.checkout.cart = ( function() {

    return {
        setCookie: false, 

        // transaction-level items
        orders: new Array (),
        payments: new Array(),
        carts: new Hash(), 
     
        totalShoppedItems: 0, 
        totalItems: 0,
        subtotal: 0,
     
        transactionParams: {
            transactionFields: {
        		"trans_fields" : ["TRANS_ID", "payments", "orders"]
    		},
    	    paymentFields: {
        		"payment_fields" : ["address", "PAYMENT_TYPE", "PAYMENT_AMOUNT", "TRANS_PAYMENT_ID"]
    		},
    	    orderFields: {
        		"order_fields" : ["items", "samples", "address", "TRANS_ORDER_ID", "items_count", "subtotal", "default_cart_id"]
    		}
        },
	
        itemTypes: { 
        	"cart" : {
        		"id": "SKU_BASE_ID",
        		"_SUBMIT" : "cart"
        	},
        	"giftcard" : {
        		"id": "CART_GIFTCARD_ID",
        		"_SUBMIT" : "giftcard"
        	},
        	"collection" : {
        		"id": "SKU_BASE_ID",
        		"_SUBMIT" : "collection.items"
        	},
        	"favorites" : {  
        		"id": "SKU_BASE_ID",
        		"_SUBMIT" : "alter_collection"
        	},
          "kit" : {
        		"id": "SKU_BASE_ID",
        		"_SUBMIT" : "alter_collection"
        	}
        },

        initialize: function(args) { 
        	Object.extend(this, args); // copy args to obj
        },
    
        getCartTotals: function() {
    	    var cookie = generic.cookie("cart");
    	    if (cookie && cookie!==null) {
    	        // console.log("generic.cart.getCartTotals cookie: "+Object.toJSON(cookie)); 
    	        Object.extend(this, cookie);	   
    	        generic.events.fire({event:'cart:countsUpdated'});
    	    } else {
    	        // console.log("generic.cart.getCartTotals !cookie");  
    	        this.getCart();
    	    }  
        },
    
        setCookie: function() { 
        	// console.log("generic.cart.setCookie "+this.totalItems);
        	var s  = {
        		totalItems: this.totalItems 
        	}
        	s = Object.toJSON(s);
        	generic.cookie("cart",s, {path:"/"}); 
        },
    
        // should be getTransaction not getCart
        getCart: function(args) {
            //console.log("generic.cart.getCart");
            var self = this; 

            if (args != null && args.pageDataKey) {
                var pageData = generic.page_data(args.pageDataKey);
                if (pageData.get("rpcdata")) {
                    console.log( "cart page data found!" );
                    self._updateCartData(pageData.get("rpcdata"));
                    return;
                }
            }

            var params = {};
            params = Object.extend ( params, self.transactionParams.transactionFields );
            params = Object.extend ( params, self.transactionParams.paymentFields);
            params = Object.extend ( params, self.transactionParams.orderFields);

            var id = generic.jsonrpc.fetch({
                method : 'trans.get',
                params: [params],
                onSuccess:function(jsonRpcResponse) {
                    self._updateCartData(jsonRpcResponse.getValue()); 
                },
                onFailure: function(jsonRpcResponse){
                	//jsonRpcResponse.getError();
                	console.log('Transaction JSON failed to load');
                }
            });
            return id;
        },
   
        //sets up internal representation of cart state
        //will establish the set of carts
        // should be _updateTransactionData not _updateCartData
        _updateCartData: function(data){
            // console.log("generic.checkout.cart._updateCartData");
            var self = this;
            this.data = data;
            this.totalItems = data.items_count;
            this.payments = (data.trans && data.trans.payments) ? $A(data.trans.payments) : null;
            this.orders = (data.trans && data.trans.orders) ? $A(data.trans.orders) : null;

            //this.defaultCartId = data.default_cart_id;
            //this.order = data.order; 

            this.totalShoppedItems = 0;
            this.subtotal = 0;
            if (this.orders != null) {
                this.orders.each(function(order){
                    if (!order) { return; }
                    // contents and sample_contents mirror the order_sku_by_qty and order_sample_sku_by_qty hashes
                    order.contents = new Hash();
                    order.sample_contents = new Hash();

                    if (order.items != null) {
                        order.items = order.items.reject(function(item){// filter out nulls
                            return item === null;
                        });
                    }

                    var items = order.items || null;
                    order.orderShoppedItems = 0;
                    if (items != null) {
                        items.each(function(item){
                            if (!item) { return; }

                            var itemQty = item.ITEM_QUANTITY || item.CART_QUANTITY;
                            if (itemQty == null || !itemQty) {
                                itemQty = 1;
                            }

                            var unitPrice  = item.UNIT_PRICE || item.basePrice;
                            var appliedTax = item.APPLIED_TAX || 0;

                            self.totalShoppedItems+=itemQty;

                            // set up contents by cart hashes 
                            var cartID = item.CART_ID;
                            var cart = self.carts.get(cartID);
                            if (!cart) {
                                self.carts.set(cartID, new Hash());
                                var contents = new Hash();
                                contents.set('TRANS_ORDER_ID', order.TRANS_ORDER_ID);
                                contents.set('TRANS_ID', self.data.trans.TRANS_ID);
                                cart = self.carts.get(cartID);
                                cart.set('contents', contents);
                            } 
                            var id = item['sku.SKU_BASE_ID'] ? item['sku.SKU_BASE_ID'] : item.COLLECTION_ID; 
                            cart.get('contents').set(id, itemQty);

                            // compute per-unit tax (replace this with field from JSONRPC result when available)
                            
                            var unitTax = appliedTax/itemQty;
                            item.UNIT_TAX = unitTax;

                            // set up order contents hash (spans carts)
                            if (item.itemType.toLowerCase() == 'skuitem') {
                                var key = item['sku.SKU_BASE_ID'];
                                var qty = itemQty;
                                //error self.order.contents.set(key, qty);
                                order.contents.set(key,qty);
                            } else if (item.itemType.toLowerCase() == 'kititem') {
                                var key = item.COLLECTION_ID;
                                var qty = itemQty;
                                order.contents.set(key,qty);
                            } else {
                                // FUTURE: other cart item types (e.g. kits)
                            }    
                            
                            self.subtotal+=(unitPrice + item.UNIT_TAX) * itemQty;            
                        });
                    }
                    self.totalShoppedItems += order.orderShoppedItems;
        
                    var samples = order.samples;
                    if (samples != null) {
                        samples.each(function(item){
                            // set up contents by cart hashes
                            var cartID = item.CART_ID;
                            var cart = self.carts.get(cartID);
                            if (!cart) {
                                self.carts.set(cartID, new Hash());
                                var contents = new Hash();
                                contents.set('TRANS_ORDER_ID', order.TRANS_ORDER_ID);
                                contents.set('TRANS_ID', self.data.trans.TRANS_ID);
                                cart = self.carts.get(cartID);
                                cart.set('contents', contents);
                            }

                            var id = item['sku.SKU_BASE_ID'] ? item['sku.SKU_BASE_ID'] : item.COLLECTION_ID;
                            cart.get('contents').set(id, item.ITEM_QUANTITY);

                            // set up order contents hash (spans carts)
                            if (item.itemType.toLowerCase() == 'sampleitem') {
                                var key = item['sku.SKU_BASE_ID'];
                                var qty = item.ITEM_QUANTITY;
                                order.sample_contents.set(key,qty);
                            } else {
                                // other item types (are likely errors)
                            }
                        });
                    }
                });
            }

            // if (self.setCookie) self.setCookie();
            generic.events.fire({event:'cart:countsUpdated'});
            // generic.events.fire({event:'cart:updated'});
        },
   
        /* args is a hash
        required keys: args.params.skus array, either args.params.INCREMENT or args.QTY with args.INCREMENT overriding args.QTY
        optional keys: args.itemType, args.OFFER_CODE, args.CART_ID*/ 
        updateCart: function(args){
            // console.log("cart.updateCart: "+Object.toJSON(args.params));
            if (!args.params) return null;

            var self = this;
            var onSuccess = args.onSuccess || Prototype.emptyFunction;
            var onFailure = args.onFailure || Prototype.emptyFunction;
            var itemType = args.params.itemType || "cart"; //e.g. cart, collection, giftcard etc
            var id = self.itemTypes[itemType].id;

            var params = {
                '_SUBMIT': self.itemTypes[itemType]["_SUBMIT"]
            };

            //id
            params[id] = (args.params.skus.length == 1) ? args.params.skus[0] : args.params.skus; //MK collections array syntax correct?

            //qty
            if (args.params.INCREMENT && args.params.INCREMENT>=0) {
                //currently +1 will be added regardless of INCREMENT's actual value
                //backend requires QTY property to exist but it will not be used
         	    params["INCREMENT"] = args.params.INCREMENT;
         	    params["QTY"] = 1;
            } else if (args.params.INCREMENT && args.params.INCREMENT<0) {
            	//decrements qty by -1
            } else if (args.params.QTY && args.params.QTY>=0) { 
            	params["QTY"] = args.params.QTY;
            }

            //offer code
            if (args.params.OFFER_CODE && args.params.OFFER_CODE.length>0) {
                params['OFFER_CODE'] = args.params.OFFER_CODE;
            }

            //favorites
            if (args.params.action && args.params.action.length > 0) {
            	params['action'] = 'add';
            }

            // targeting of the correct cart is still missing (and important to get right)
            // cart id if we are adding to something other than the default cart
            if (args.params.cart_id && (args.params.cart_id != self.defaultCartId)) {
                params['CART_ID'] = args.params.cart_id;
            }

            if (args.params.COLLECTION_TYPE && args.params.COLLECTION_TYPE.length > 0) {
                params['COLLECTION_TYPE'] = args.params.COLLECTION_TYPE;
                params['COLLECTION_SUBTYPE'] = args.params.COLLECTION_SUBTYPE;
                params['COLLECTION_NAME'] = args.params.COLLECTION_NAME;
                params['COLLECTION_ID'] = args.params.COLLECTION_ID;
                //params['cmode'] = args.params.cmode;
                params['action'] = args.params.action;
            }

            var id = generic.jsonrpc.fetch({
                "method" : 'rpc.form',
                "params" : [params],
                "onSuccess": function(jsonRpcResponse){
                    var data = jsonRpcResponse.getData();
                    //load data
                    if (data && data["trans_data"]) {
                        self._updateCartData(data["trans_data"]);
                    }
                    if (args.params.itemType == 'cart') {
                    	var cartResultObj = jsonRpcResponse.getCartResults();
	                    document.fire("cart:updated", cartResultObj);
	                  };
                    if (args.params.itemType == 'kit') {
                      self.getCart();
                    	var cartResultObj = jsonRpcResponse.getCartResults();
	                    document.fire("cart:kit_updated", cartResultObj);
	                  };
	                  if (args.params.itemType == 'favorites') {
	                	  document.fire("favorites:updated", jsonRpcResponse);
	                  };
                    onSuccess(jsonRpcResponse);
                },
                "onFailure": function(jsonRpcResponse){
                    onFailure(jsonRpcResponse);
                }
            });

            return id;
        }, 
    
        getItemQty : function(baseSkuId) {
            if (!this.order.items) return 0;
            var lineItem = this.order.items.find( function (line) {
                return line['sku.SKU_BASE_ID'] ==  baseSkuId;
            });
            if (!lineItem) {
                return 0;
            }
            return lineItem.ITEM_QUANTITY;
        },
    
        getBaseSkuIds: function() {  //MK: what is this used for?
            //console.log("generic.cart.getBaseSkuIds: "+this.order.items);
            if (!this.order.items) return new Hash();
            var baseSkuIds = this.order.items.pluck( 'sku.SKU_BASE_ID' ); //MK what about giftcards/collections?
            return baseSkuIds;
        },
    
        getSubtotal: function() {
            /*var lineItems = this.order.items;
            if (!this.order.items) return 0;
            var subtotal = 0;
            for (var i=0, len = lineItems.length; i<len; i++) {
                var lineItem = lineItems[i];
                subtotal += (lineItem.UNIT_PRICE + lineItem.UNIT_TAX) * lineItem.ITEM_QUANTITY;
            }*/
            return this.subtotal;
        },
     
        getTotalShoppedItems: function(){ //products and gift cards
            return this.totalShoppedItems;
        },         
        
        getTotalSamples: function() {
             var ttl = 0;
             var samples = this.order.samples;
                if (samples != null) {
                    samples.each(function(item){
                        ttl += item.ITEM_QUANTITY;
                    });
            } 
            return ttl;
        }, 
    
        getTotalItems: function(){ 
           // return this.getTotalShoppedItems() + this.getTotalSamples();
           return this.totalItems;
        },

        // Obtain address records associated with payments and orders (i.e., packages).
        getPaymentAddresses: function(){
            var addresses;
            if (this.payments) {
                addresses = this.payments.pluck( 'address' );
            }
            return addresses;
        },

        getOrderAddresses: function(){
            var addresses;
            if (this.payments) {
                addresses = this.orders.pluck( 'address' );
            }
            return addresses;
        }
    };
}() );

document.observe("cart:countsUpdated", function() {
    generic.checkout.rb = generic.rb('language');

    //Update cart count.
    var item_count = generic.checkout.cart.getTotalShoppedItems();
    item_count = (item_count == 0 || item_count > 1) ? item_count + " " + generic.checkout.rb.get('items')
        : item_count + " " + generic.checkout.rb.get('item');

    if( $('basketcount') ) {
        $$('#basketcount a')[0].update(item_count);
    }
    if( $('subtotal') ) {    
        var x = $$("#subtotal .amount")[0]
        x.update( item_count );    
    }
});


