
generic.checkout = {

};

/*
generic.checkout.cart 
- depends on: generic.cookie, generic.jsonrpc
*/ 
generic.checkout.cart = Class.create({
    ifSetCookie: false, 
    
    order: new Hash(),
    payments: new Array(),
    carts: new Hash(), 
    items: new Array(),
    samples: new Array(),
     
    totalShoppedItems: 0, 
    totalItems: 0,
     
    transactionParams: {
	transactionFields: {
    			"trans_fields" : ["totals","TRANS_ID", "payments"]
		},
	paymentFields: {
    			"payment_fields" : ["address", "PAYMENT_TYPE", "PAYMENT_AMOUNT", "TRANS_PAYMENT_ID"]
		},
	orderFields: {
    			"order_fields" : ["items", "samples", "address", "TRANS_ORDER_ID"]
		}
    },
	
    itemTypes: { 
    	"product" : {
    		"id": "SKU_BASE_ID",
    		"_SUBMIT" : "cart"
    	},
    	"giftcard" : {
    		"id": "CART_GIFTCARD_ID",
    		"_SUBMIT" : "giftcard"
    	} 
    },

    initialize: function(args) { 
    	 //console.log("generic.cart.updateCartTotals: "+Object.toJSON(args));
    	 generic.updateProperties.apply(this, [args]);
    },
    
    getCartTotals: function() {
	var cookie = generic.cookie("cart");
	if (cookie && cookie!==null) {
	   //console.log("generic.cart.getCartTotals cookie: "+Object.toJSON(cookie)); 
	   generic.updateProperties.apply(this, [cookie]);   
	   generic.events.fire({event:'cart:countsUpdated'});
	} else {
	   //console.log("generic.cart.getCartTotals !cookie");   
	   this.getCart();
	}  
    },
    
    //update Cookie, in case Cart has been updated via form submission instead of generic.cart 
    updateCartTotals: function(args) { 
    	 //console.log("generic.cart.updateCartTotals: "+Object.toJSON(args));
    	 generic.updateProperties.apply(this, [args]);  
    	 if (this.ifSetCookie) this.setCookie();    
    	 generic.events.fire({event:'cart:countsUpdated'});
    },
   
    setCookie: function() { 
    	console.log("generic.cart.setCookie "+this.totalItems);
    	var s  = {
    		totalItems: this.totalItems 
    	}
    	s = Object.toJSON(s);
    	generic.cookie("cart",s, {path:"/"}); 
    },
    
    getCart: function() { 
        //console.log("generic.cart.getCart");
        var self = this; 
        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
    // Assuming one order per transaction
    _updateCartData: function(data){ 
        //console.log("generic.checkout.cart._updateCartData");
        var self = this;
        this.data = data;
        this.totalItems = data.items_count; 
        this.defaultCartId = data.default_cart_id;
        this.payments = (data.trans && data.trans.payments) ? $A(data.trans.payments) : null;  
        this.order = data.order; 
         
        // contents and sample_contents mirror the sku by qty hashes
        this.order.contents = new Hash();
        this.order.sample_contents = new Hash();

        if (this.order.items != null) {
            this.order.items = this.order.items.reject(function(item){ // filter out nulls
                return item === null;
            });
        }
        
        var items = this.order.items || null;
        var totalShoppedItems = 0;
        if (items != null) {  
            items.each(function(item){   
                if (!item) { return; }
                totalShoppedItems+=item.ITEM_QUANTITY;
                
                // 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()); 
                    cart = self.carts.get(cartID); 
                    cart.set('contents', new Hash());
                } 
                var id = item['sku.SKU_BASE_ID'] ? item['sku.SKU_BASE_ID'] : item.COLLECTION_ID; 
                cart.get('contents').set(id, item.ITEM_QUANTITY);
                
                // compute per-unit tax (replace this with field from JSONRPC result when available)
                var unitTax = item.APPLIED_TAX/item.ITEM_QUANTITY;
                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 = item.ITEM_QUANTITY; 
                    //error self.order.contents.set(key, qty);
                    self.order.contents[key] = qty; 
                } else if (item.itemType.toLowerCase() == 'kititem') {
                    var key = item.COLLECTION_ID;
                    var qty = item.ITEM_QUANTITY;
                    self.order.contents.set(key,qty);
                } else {
                    // FUTURE: other cart item types (e.g. kits)
                } 
                
            });
        }
        
        this.totalShoppedItems = totalShoppedItems;
        
        var samples = this.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());
                    cart = self.carts.get(cartID);
                    cart.set('contents', new Hash());
                } 
               
                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;
                    self.order.sample_contents.set(key,qty); 
                } else {
                    // other item types (are likely errors)
                } 
            });
        }
        
        if (self.ifSetCookie) self.setCookie();        
        generic.events.fire({event:'cart:countsUpdated'});
        generic.events.fire({event:'cart:updated'}); 
    },
   
    /** 
    args is a hash
    optional keys: args.params.skus array, either args.params.INCREMENT or args.QTY with args.INCREMENT overriding args.QTY
                   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.itemType || "product"; //e.g. product, giftcard  
        var id = self.itemTypes[itemType].id;
         
        var params = {
            '_SUBMIT': self.itemTypes[itemType]["_SUBMIT"] 
        };  
        
        //id 
        if (args.params.skus) {
        	 params[id] = (args.params.skus.length == 1) ? args.params.skus[0] : args.params.skus; 
        }
         
        //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;
        }
            
        // 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;
        }
        
        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"]);
                } 
                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;
    },
    getLineItemUnitPrice: function(baseSkuId) {
        var lineItem = this.order.items.find( function (line) {
            return line['sku.SKU_BASE_ID'] ==  baseSkuId;
        });
        if (!lineItem) {
            return 0; 
        }                
        return lineItem.UNIT_PRICE;
    },
    getLineItemAppliedPrice: function(baseSkuId) {
        var lineItem = this.order.items.find( function (line) {
            return line['sku.SKU_BASE_ID'] ==  baseSkuId;
        });
        if (!lineItem) {
            return 0; 
        }
        var subtotal = lineItem.UNIT_PRICE * lineItem.ITEM_QUANTITY;
        return subtotal;
    },
    getLineItemUnitTax: function(baseSkuId) {
        var lineItem = this.order.items.find( function (line) {
            return line['sku.SKU_BASE_ID'] ==  baseSkuId;
        });
        if (!lineItem) {
            return 0; 
        }                
        return lineItem.UNIT_TAX;
    },
    getLineItemAppliedTax: function(baseSkuId) {
        var lineItem = this.order.items.find( function (line) {
            return line['sku.SKU_BASE_ID'] ==  baseSkuId;
        });
        if (!lineItem) {
            return 0; 
        }
        return lineItem.UNIT_TAX * 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 subtotal;
    },
     
    getTotalShoppedItems: function(){ //products and gift cards
       /** var ttl = 0;
        var items = this.order.items;
        if (items != null) {
            items.each(function(item){
                if (item && item.ITEM_QUANTITY) {
                    ttl += item.ITEM_QUANTITY;
                }
            });
        } 
        return ttl;**/
        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;
     }    

});
