var el = el || {};
el.productView = el.productView || {};
el.rb = el.rb || {};
el.rb.language = el.rb.language || generic.rb("language");
var RENUTRIV = RENUTRIV || "";
// default popup settings
el.productView.DEFAULT_POPUP_WIDTH = 751;

el.productView.getTopPosition = function() {
    var scrolledY = (generic.env.isSafari) ? document.body.scrollTop : document.documentElement.scrollTop;
    // this var is set in
    // sites/esteelauder/locale/re-nutriv/includes/base/head_start.tmpl
    //Adjusting the popup to show 75px - need to fix it in correct way post launch
    var heightFromTop = (RENUTRIV) ? 86 : 60;
    return scrolledY + heightFromTop;
}

el.productView.getLeftPosition = function() {
    var width = 816;//actual size is 786 with a 15px padding... el.productView.DEFAULT_POPUP_WIDTH;
    //var windowWidth = (generic.env.isIE) ? document.documentElement.clientWidth : window.innerWidth;
	var windowDimensions = document.viewport.getDimensions();
	var windowScrollOffsets = document.viewport.getScrollOffsets();
    var left = ((windowDimensions.width - width)/2) + windowScrollOffsets.left;
    return Math.round(left);
}

// Flag images for mpp/spp
// Example usage: el.productView.flagImages.get(productData)
el.productView.flagImages = {
    _images: function() {
        return {
            1:{
                "mppimg":'/products/images/common/note_new.gif',
                "sppimg":'/products/images/common/note_new.gif',
                "alt"   : el.rb.language.get("alt.flag_image_new"),
                "text"  : el.rb.language.get("alt.flag_image_new")
            },
            2:{
                "mppimg":'/products/images/common/note_limited_edition.gif',
                "sppimg":'/products/images/common/note_limited_edition.gif',
                "alt"   : el.rb.language.get("alt.flag_image_limited_edition"),
                "text"  : el.rb.language.get("alt.flag_image_limited_edition")
            },
            3:{
                "mppimg":'/products/images/common/note_new_shades.gif',
                "sppimg":'/products/images/common/note_new_shades.gif',
                "alt"   : el.rb.language.get("alt.flag_image_new_shades"),
                "text"  : el.rb.language.get("alt.flag_image_new_shades")
            },
            4:{
                "mppimg":'/products/images/common/note_holiday.gif',
                "sppimg":'/products/images/common/note_holiday.gif',
                "alt"   : el.rb.language.get("alt.flag_image_holiday"),
                "text"  : el.rb.language.get("alt.flag_image_holiday")
            },
            5:{
                "mppimg":'/products/images/common/note_online_exclusive.gif',
                "sppimg":'/products/images/common/note_online_exclusive.gif',
                "alt"   : el.rb.language.get("alt.flag_image_online_exclusive"),
                "text"  : el.rb.language.get("alt.flag_image_online_exclusive")
            },
            6:{
                "mppimg":'/products/images/common/note_bestseller.gif',
                "sppimg":'/products/images/common/note_bestseller.gif',
                "alt"   : el.rb.language.get("alt.flag_image_bestseller"),
                "text"  : el.rb.language.get("alt.flag_image_bestseller")
            },
            7:{
                "mppimg":'/products/images/common/note_25_value.gif',
                "sppimg":'/products/images/common/note_25_value.gif',
                "alt"   : el.rb.language.get("alt.flag_image_25_value"),
                "text"  : el.rb.language.get("alt.flag_image_25_value")
            },
            15:{
                "mppimg":'/products/images/common/note_pre-order.gif',
                "sppimg":'/products/images/common/note_pre-order.gif',
                "alt"   : el.rb.language.get("alt.flag_image_preorder"),
                "text"  : el.rb.language.get("alt.flag_image_preorder")
            }
        }
    },
    get: function(productData) {
        return this._images()[productData.MISC_FLAG];
    }
};

/* Get message for inventory status from resource bundle */
el.productView.inventoryStatusMessage = function(status) {
    var statusMessage;
    switch (status) {
        case 2:  statusMessage = el.productView.tempOutOfStock; break;
        case 3:  statusMessage = el.productView.comingSoon; break;
        case 5:  statusMessage = el.productView.inactive; break;
        case 7:  statusMessage = el.productView.soldOut; break;
        default: statusMessage = "";
    }

    return statusMessage;
};

el.productView.reportProductView = function(args){
    params = args;
    var sync = false;

    if (params['URL_CLICK']){
        sync = true;
    }
    var id = generic.jsonrpc.fetch({
        "method" : 'prodcat.viewc',
        "sync" : sync,
        "params" : [params]
/*
        "onSuccess": function(jsonRpcResponse){
          var data = jsonRpcResponse.getData();
            onSuccess(jsonRpcResponse);
        },
        "onFailure": function(jsonRpcResponse){
            onFailure(jsonRpcResponse);
         }
*/
   });



};

el.productView.addRegimenButton = function(args) {
    var progressNode = args.progressNode;
    var addButtonNode = args.addButtonNode;
    var regimenPaths = args.paths;
    var itemType = args.itemType || 'cart';
 
    var skuIds = regimenPaths.map(function(s) {
        var re = new RegExp("SKU([0-9]+)$");
        re.exec(s);
        var skuId = RegExp.$1;
        return parseInt(skuId);
    });
    
    addButtonNode.observe("click", function(clickEvt) {
        clickEvt.preventDefault();
                
        var item_params = {
            skus: skuIds,
            itemType: 'cart',
            INCREMENT: 1
        };
            
        if (progressNode) {
            progressNode.style.display = "block";
            addButtonNode.style.display = "none";
        }
        var revertButton = function() {
            if (progressNode) {
                progressNode.style.display = "none";
                addButtonNode.style.display = "block";
            }
        };
        generic.checkout.cart.updateCart({
            	params: item_params,
		onSuccess: function(r) {
                var resultData = r.getData();
                //update global util nav if this was add to bag
                var cartCount = resultData.trans_data.items_count;
                $('shoppingbag_count').update(cartCount);
                revertButton();
                
                addButtonNode.fire("cartButton:success", resultData);
            },
            onFailure: function(r) {
                revertButton();
            }
        });
    });
    
    return {
        getItemType: function() {
            return itemType;
        },
        setSkuBaseId: function (newSkuBaseId) {
            skuBaseId = newSkuBaseId;
        },
        setSkuData: function (data) {
            skuData = data;
            this.setSkuBaseId(data.SKU_BASE_ID);
        },
        setShoppable: function() {
            addButtonNode.removeClassName("hidden");
        }
    };
};

el.productView.cartID = '';

el.productView.addButton = function (args) {
//    var skuBaseId = args.skuBaseId;
    var progressNode = args.progressNode;
    var addButtonNode = args.addButtonNode;
    var skuData = args.skuData;

    //preserve current cat in cart
    var cat_base_id; 
    if (args.skuData && typeof args.skuData.PARENT_CAT_ID != "undefined"){
        cat_base_id = args.skuData.PARENT_CAT_ID;
        cat_base_id = cat_base_id.match("[0-9]+")[0];
    }

    var skuBaseId;
    if (args.skuData && args.skuData.SKU_BASE_ID) {
        skuBaseId = args.skuData.SKU_BASE_ID;
    } else if (args.skuBaseId) {
        skuBaseId = args.skuBaseId;
    } else {
        return null;
    }
    var itemType = args.itemType || 'cart';
    var alt_params = '';
    addButtonNode.observe("click", function(clickEvt) {
        clickEvt.preventDefault();
        var item_params = {};
        if (progressNode) {
            progressNode.style.display = "block";
            addButtonNode.style.display = "none";
        }
        var revertButton = function() {
            if (progressNode) {
                progressNode.style.display = "none";
                addButtonNode.style.display = "block";
            }
        };
        
        var updateFavoritesText = function(msg) {
            addButtonNode.innerHTML = msg;
            revertButton();
        };

        // Send individual parameters based on type
        if (itemType == 'favorites') {
            item_params = {
                skus: [skuBaseId],
                itemType: 'favorites',
                CAT_BASE_ID: cat_base_id,
                action: 'add'
            }
        } 
	else if (itemType == 'replenishment') {
            item_params = {
                skus: [skuBaseId],
                action: 'add',
                add_to_cart: 1,
                itemType: 'replenishment',
                CAT_BASE_ID: cat_base_id,
                INCREMENT: 1
            }
        }else {
            item_params = {
                skus: [skuBaseId],
                itemType: 'cart',
                CAT_BASE_ID: cat_base_id,
                INCREMENT: 1
            }
        }
	//var alt_params = el.productView.addButton.altParams;
	var params = item_params;
        if (alt_params) {
            params = Object.extend(alt_params, params);
        }
        generic.checkout.cart.updateCart({
            //params: alt_params || item_params,
	     params: params,
	     onSuccess: function(r) {
                var resultData = r.getData();
                //update global util nav if this was add to bag
                if (resultData.trans_data) {
                    var cartCount = resultData.trans_data.items_count;
                    $('shoppingbag_count').update(cartCount);
                    revertButton();
                    
                    el.productView.cartID = resultData.cart_id;
                } else {
                    var msg = el.productView.favoritesMessageDisplay.getMessage(r);
                    updateFavoritesText(msg.text || msg.key);
                }
                
                addButtonNode.fire("cartButton:success", resultData);
            },
            onFailure: function(r) {
                revertButton();
                var error = r.getError();
                var message = error.data.messages[0];
                var text = message.text;
                text = text.replace(/\\/g, "");
                if (message && message.key === 'cart.qty_limit') {
                    generic.templatefactory.get({path:'/templates/add-to-cart-error-overlay.tmpl'}).evaluateCallback({
                        object: { errorText: text },
                        callback: function(html) {
                            var width = 350;
                            var windowWidth = (generic.env.isIE) ? document.documentElement.clientWidth : window.innerWidth;
                            var x = ((windowWidth / 2) - (width/2));
                            var scrolledY = (generic.env.isSafari) ? document.body.scrollTop : document.documentElement.scrollTop;
                            var heightFromTop = 200;
                            var y = scrolledY + heightFromTop;
                            
                            generic.overlay.launch({
                                content: html,
                                includeBackground: true,
                                lockPosition: true,
                                center: false,
                                cssStyle: {
                                    left: x + "px",
                                    top: y + "px",
                                    padding: "15px",
                                    width: width + "px"
                                }
                            });
                            
                            var containerNode   = $$(".overlay-container")[0];
                            var continueShoppingBtn = containerNode.select(".continue-shopping")[0];
                            $(continueShoppingBtn).observe("click", function(evt) {
                                evt.preventDefault();
                                generic.overlay.hide();
                            });
                        }
                    });
                }
            }
        });
    });
    return {
        getItemType: function() {
            return itemType;
        },
	setItemType: function(args) {
            // you can just change the item type or also add additional params
            if (!args.itemType) {
                return null;
            }
            itemType = args.itemType;
            alt_params = args.altParams;
        },
        setSkuBaseId: function (newSkuBaseId) {
            skuBaseId = newSkuBaseId;
        },
        setSkuData: function (data) {
            skuData = data;
            this.setSkuBaseId(data.SKU_BASE_ID);
        },
        setShoppable: function() {
            if (!skuData) {
                return null;
            }
            if (el.productData.isShoppable(skuData)) {
                addButtonNode.removeClassName("hidden");
            } else {
                addButtonNode.addClassName("hidden");
            }
        }
    };
};

el.productData = {
    isShoppable : function(skuData) {
        return skuData.INVENTORY_STATUS && skuData.INVENTORY_STATUS == 1;
    },
    isTempOutOfStock: function(skuData) {
        return skuData.INVENTORY_STATUS && skuData.INVENTORY_STATUS == 2;
    },
    isComingSoon: function(skuData) {
        return skuData.INVENTORY_STATUS && skuData.INVENTORY_STATUS == 3;
    },
    isInactive: function(skuData) {
        return skuData.INVENTORY_STATUS && skuData.INVENTORY_STATUS == 5;
    },
    isSoldOut: function(skuData) {
        return skuData.INVENTORY_STATUS && skuData.INVENTORY_STATUS == 7;
    },
    isPreOrder: function(skuData){
        return skuData.INVENTORY_STATUS && skuData.MISC_FLAG && skuData.INVENTORY_STATUS == 1 && skuData.MISC_FLAG == 15
    },
    /*
     * Check if all skus in a product have same status of CS/TOS/OOS. If so,
     * return integer of status, else return -1; This method has to potentially
     * process a lot of skus, so some pre-processing is being done to attempt
     * to weed out obvious cases that don't meet this condition
     */
    isNonShoppableProduct: function(productData) {
        var skus = productData.skus;

        /* no skus */
        if (skus.length == 0) { return -1; }

        /* check if first sku is shoppable */
        if (el.productData.isShoppable(skus[0])) { return -1; }

        // check if first two skus have same inventory status if there is more
        // than one sku
        if (skus.length > 1 && (skus[0].INVENTORY_STATUS != skus[1].INVENTORY_STATUS)) {
            return -1;
        }

        var firstStatus = skus[0].INVENTORY_STATUS;

        for (var i = 0;i < skus.length; i++) {
            if (skus[i].INVENTORY_STATUS != firstStatus) { return -1; }
        }

        // We made it through without returning.
        // All skus have same non-Active status
        return firstStatus;
    }
};

// EL skintypes are stored differently than clinique. 
// Parsing the types as Clinique does is not necessary
el.productData.parseSkinTypes = function(skinTypeStr, args) {
    return;
};

el.productData.getSkinTypeLabel = function(sku) {
    if (!sku || !sku.SKIN_TYPE) { return; }
    
    var type = sku.SKIN_TYPE;
    var label;
    
    switch(type) {
        case 1 : label = el.rb.language.get("skin_type_very_dry"); break;
        case 2 : label = el.rb.language.get("skin_type_dry"); break;
        case 3 : label = el.rb.language.get("skin_type_normal_combination"); break;
        case 4 : label = el.rb.language.get("skin_type_oily"); break;
        case 5 : label = el.rb.language.get("skin_type_sensitive"); break;
        case 6 : label = el.rb.language.get("skin_type_dry_normal"); break;
        case 7 : label = el.rb.language.get("skin_type_normal_oily"); break;
        case 8 : label = el.rb.language.get("skin_type_all_skintypes"); break;
        default: label = "";
    }
    
    return label;
}

el.productView.cartOverlay = {
    getMessage: function(cartMethod) {
        if (!cartMethod) {
            return null;
        }
        var msgs = {
            "add": "The following items have been added to your cart" // replace with RB
        };
        if (msgs[cartMethod]) {
            return msgs[cartMethod];
        } else {
            return null;
        }
    },
    setShippingMessage: function(args) {
        var node = args.node;
        var cartSubTotal = args.cartSubTotal;
        var appliedShippingPrice = generic.checkout.cart.order.ORDER_SHIPPING_APPLIED_PRICE;
        var freeShippingMet = ((4000 - cartSubTotal)  <= 0 || appliedShippingPrice == 0);
        
        var shippingKey = (freeShippingMet) ? 'free_shipping_met' : 'free_shipping_not_met';
        
        shippingMessage = generic.rb('language').get(shippingKey);
        
        if (!freeShippingMet) {
            var difference = 4000 - cartSubTotal;
            shippingMessage = shippingMessage.replace("[#]", difference);
        }
        
        node.update(shippingMessage);
    },
    
    launch: function(cartResponseObj) {
        var self = this;
        
        if (typeof cartResponseObj.getItem !== "function") {
            return;
        }
        
        var cartItems = cartResponseObj.getItems();
        var obj = {
            items: cartItems
        };
        
        // place www skus from response in page data to avoid redundant request
        // for them when rendering 
        if (!page_data.catalog) {
            page_data.catalog = {};
        }
        
        page_data.catalog.cart = {};
        page_data.catalog.cart.recommendedProducts = cartItems[0].www;

        //var cartItem = cartItems[0];
        obj.totalCartItems = generic.checkout.cart.getTotalShoppedItems(); // this will return 0 until response to cart JSON-RPC is modified to include user transaction data
        var cartMethod = cartResponseObj.getMethod();
        obj.cartMessage = this.getMessage(cartMethod);
        var cart = generic.checkout.cart;
        obj.cartSubtotal = cart.data.subtotal;
        // get product subtotal
        var product_subtotal = 0;
        var free_shipping_calc_total = 0;
        cartItems.each(function(item) {
            if (item.itemType != null){ 
                product_subtotal += (item.product.sku.PRICE * item.ITEM_QUANTITY);
            }
            
            if (item.itemType != 'DonationItem'){   
                free_shipping_calc_total += (item.product.sku.PRICE * item.ITEM_QUANTITY);
            }
        });
        obj.formattedProductSubtotal = el.productView.formatPrice(product_subtotal);

        var renderSwatch = function(args) {
            var url = args.url;
            var hexValues = args.hexValues;
            var swatchNode = args.swatchNode;

            hexValues.each(function(hv) {
                var outer_span = new Element("span");
                var a = new Element("a");
                var inner_span = new Element("span");

                /* style the nodes */
                outer_span.className = "swatch qv_swatch";
                outer_span.setStyle({
                    width: "19px",
                    height: "19px",
                    padding: "0 1px"
                });

                a.href = url;
                inner_span.className = "swatch_ico";

                inner_span.setStyle({
                    background: hv,
                    cursor: "pointer",
                    width: "19px",
                    height: "19px"
                });

                /* place the nodes */
                a.appendChild(inner_span);
                outer_span.appendChild(a);
                swatchNode.appendChild(outer_span);
            });
        };

        var renderCartItem = function(args) {
            var containerNode = args.container;
            var item = args.item;
            var itemNumber = args.itemNumber;
            // TODO: there are more conditions for this that need ported
            item.shaded = item.product.sku.SHADENAME;
            item.skinTypeDisplay = (item.product.sku.SKIN_TYPE && !item.shaded) ? "block" : "none";
            item.skinTypeLabel = el.productData.getSkinTypeLabel(item.product.sku);
            item.sizeDisplay = (item.product.sku.PRODUCT_SIZE) ? "block" : "none";
            item.currentformattedPrice = el.productView.formatPrice(item.product.sku.PRICE * item.ITEM_QUANTITY);
            
            if (item.product.sku.isQuantityLimited && item.product.sku.quantityLimit == 1) {
                item.dropDownDisable = "disabled";
            }
            generic.templatefactory.get({path:"/templates/quickshop-cart-item.tmpl"}).evaluateCallback({
                object: item,
                callback: function(html) {
                    containerNode.insert(html);
                    var removeLink     = containerNode.select("span.remove")[itemNumber];
                    var quantitySelect = containerNode.select("select.productSubtotalSelect")[itemNumber];

                    // process shades, skintype, etc.
                    var shadedNode = containerNode.select(".shadedNode")[itemNumber];
                    if (!item.shaded) {
                        shadedNode.setStyle({
                            display: "none"
                        });
                    } else {
                        // attach mini swatch(es) here
                        renderSwatch({
                            url: item.product.url,
                            hexValues: item.product.sku.HEX_VALUE_STRING.split(','),
                            swatchNode: containerNode.select(".swatchNode")[itemNumber]
                        });
                        shadedNode.setStyle({
                            display: "block"
                        });
                    }

                    if (el.productData.isTempOutOfStock(item.product.sku)) {
                        var tos_message = containerNode.select(".InventoryStatusNode")[0];
                        tos_message.setStyle({ display: "block" });
                    }

                    if (el.productData.isPreOrder(item.product.sku)) {
                        var preorder_message = containerNode.select(".preOrderInventoryStatusNode")[0];
                        preorder_message.setStyle({ display: "block" });
                    }

                    removeLink.observe("click", function(evt) {
                        var qty = 0;
                        var skuBaseId = item.product.sku.SKU_BASE_ID;
                        // set qty of product in cart
                        var item_params = {
                            skus: [skuBaseId],
                            itemType: 'cart',
                            cart_id: el.productView.cartID || item.CART_ID,
                            QTY: qty
                        };
                        el.productView.cartID = '';
                        
                        generic.checkout.cart.updateCart({
                            params: item_params,
                            onSuccess: function(r) {
                                console.log("Successful cart update");
                                var resultData = r.getData();
                                var cartCount = resultData.trans_data.items_count;
                                var cartContainer = $$(".quickshop-cart-container")[0];
                                var subtotal = resultData.trans_data.subtotal;
                                // set product product total line item to 0
                                var productTotalNode = containerNode.select("span.productTotalNode")[0];
                                productTotalNode.update(el.productView.formatPrice(0));
                                
                                var productSubTotalNode = cartContainer.select(".productSubtotalNode")[0];
                                productSubTotalNode.update(el.productView.formatPrice(0));
                                
                                // update cart subtotal
                                var cartSubtotalNode = cartContainer.select(".cartSubtotalNode")[0];
                                cartSubtotalNode.update(el.productView.formatPrice(resultData.trans_data.subtotal));
                                
                                // update global nav qty
                                $('shoppingbag_count').update(cartCount);
                                
                                // update shopping_bag_qty
                                var shoppingBagText = cartContainer.select(".shopping_bag_qty")[0];
                                var resourceName = (cartCount == 1) ? "iteminbag" : "itemsinbag";
                                var bagMsg = generic.rb('language').get(resourceName);
                                bagMsg = bagMsg.replace("[#]", cartCount);
                                shoppingBagText.update(bagMsg);
                                
                                // update header to 'item has been removed ...'
                                var headerImgNode = cartContainer.select(".headerImgNode")[0];
                                headerImgNode.src = "/images/headers/h_item_removed.png";

                                // set the quantity dropdown to 0
                                quantitySelect.options[quantitySelect.options.length] = 
                                    new Option(0, 0, true, true);

                                quantitySelect.value = 0;
                                
                                // hide the remove link
                                $(removeLink).setStyle({ "visibility" : "hidden"});
                                
                                // update shipping message
                                // set shipping message
                                
                                var shippingMsgNode = cartContainer.select(".shippingNoteNode")[0];
                                
                                self.setShippingMessage({
                                    node: shippingMsgNode,
                                    cartSubTotal: subtotal
                                });
                            },
                            onFailure: function(r) {
                                console.error("Update cart fail");
                                revertButton();
                            }
                        });
                    });

                    quantitySelect.observe("change", function(evt) {
                        var index = this.options.selectedIndex;
                        var qty = this.options[index].value;
                        var skuBaseId = item.product.sku.SKU_BASE_ID;

                        // set qty of product in cart
                        var item_params = {
                            skus: [skuBaseId],
                            itemType: 'cart',
                            QTY: qty
                        };
                        // REFACTOR
                        generic.checkout.cart.updateCart({
                            params: item_params,
                            onSuccess: function(i, r) {
                                console.log("Successful cart update");
                                var resultData = r.getData();
                                var cartCount = resultData.trans_data.items_count;
                                //update global util nav
                                $('shoppingbag_count').update(cartCount);
                                
                                var container = $('quickshop-cart-overlay-container');
                                var dd = container.select(".productSubtotalSelect")[0];
                                dd.selectedIndex = i;
                            }.curry(index),
                            onFailure: function(r) {
                                console.error("Update cart fail");
                                revertButton();
                            }
                        });
                    });

                    // set select/option to reflect current amount
                    // of item in cart
                    var currentQty = item.ITEM_QUANTITY;
                    
                    // set to 1 item added
                    //quantitySelect.selectedIndex = 0;
                    quantitySelect.selectedIndex = currentQty - 1;
                }
            });
        };

        var renderWWW = function(args) {
            var containerNode = args.container;
            var product = args.product;
            var www = product.skus[0];
            www.skinTypeLabel = el.productData.getSkinTypeLabel(www);
            www.INVENTORY_STATUS_MESSAGE = (www.INVENTORY_STATUS == "1" && www.MISC_FLAG == "15") ?
                "PRE-ORDER"
                :
                '';

            var index = args.index;
            var object = { product: product, sku:www };
            generic.templatefactory.get({path:"/templates/quickshop-cart-www.tmpl"}).evaluateCallback({
                object: object,
                callback: function(html) {
                    containerNode.insert(html);
                    var skinTypeNode = containerNode.select(".skintypeNode")[index];
                    var shadedNode   = containerNode.select(".shadedNode")[index];
                    var swatchNode   = containerNode.select(".swatchNode")[index];
                    var prodSizeNode = containerNode.select(".prod_size")[index];
                    var buttonNode   = containerNode.select("a.description-add-link")[index];
                    var itemNode     = containerNode.select(".item")[index];
                    var node = Analytics.assignLocEvents( itemNode,'loctmpl');

                    if (!parseInt(object.product.shaded)) {
                        shadedNode.setStyle({
                            visibility: "hidden"
                        });
                    } else {
                        renderSwatch({
                            url: object.product.url,
                            hexValues: object.sku.HEX_VALUE_STRING.split(','),
                            swatchNode: swatchNode
                        });
                    }

                    if (!object.sku.SKIN_TYPE || object.product.shaded) {
                        skinTypeNode.setStyle({
                            visibility: "hidden"
                        });
                    }
                    
                    if (!object.sku.PRODUCT_SIZE) {
                        prodSizeNode.setStyle({
                            display: "none"
                        });
                    }

                    // a2b button
                    if (buttonNode) {
                        if (object.sku) {
                            var btn = el.productView.addButton({
                                skuData: object.sku,
                                addButtonNode: buttonNode
                            });
                            var cartItems = obj.items;
                        }
                    }
                }
            });
        };


        if (cartMethod === "delete") {
            // do not re-display popup.
        } else {
            generic.templatefactory.get({path:"/templates/cart-overlay.tmpl"}).evaluateCallback({
                object: obj,
                callback: function(html) {
                    var cartItems = [];
                    obj.items.each(function(item, i) {
		                if (item.itemType != null){ // parse out AR items
		                    cartItems.push(item);
		                } 
		            });
		            
                    generic.overlay.launch({
                        content: html,
                        includeBackground: true,
                        lockPosition: true,
                        center: false,
                        cssStyle: {
                            left: el.productView.getLeftPosition() + "px",
                            top: el.productView.getTopPosition() + "px",
                            width: el.productView.DEFAULT_POPUP_WIDTH + "px",
                            background: "#ffffff url(/images/common/bg_shd_v.png) repeat-y scroll 541px center"
                        }
                    });

                    var containerNode   = $$(".overlay-container")[0];
                    containerNode.id = "quickshop-cart-overlay-container";
                    var cartItemNode    = containerNode.select(".cartItemNode")[0];
                    var cartCenterNode  = containerNode.select(".cart_center")[0];
                    var xsNode          = containerNode.select(".xsNode")[0];
                    var qtyNode         = containerNode.select(".shopping_bag_qty")[0];
                    var shippingMsgNode = containerNode.select(".shippingNoteNode")[0];
                    // render cart item
                    
                    /* Regimen(virtual sku) sku items processed here */
		            if (cartItems.length > 1) {
		                cartItems.each(function(item, i) {
                            renderCartItem({
                                container: cartItemNode,
                                item: item,
                                itemNumber: i
                            });                    
                        });
                        
                        xsNode.setStyle({"display" : "none"});
                        cartCenterNode.setStyle({"display" : "none"});
                    } else {
                    
                        renderCartItem({
                            container: cartItemNode,
                            item: cartItems[0],
                            itemNumber: 0
                        });

                    }

                    cartItems.each(function(cartItem) {
                        // render www
                        var renderCrossSellPanes = function(responseData) {
                            if (!responseData){
                                return null;
                            } 
                            
                            if (Object.isArray(responseData.products) && responseData.products.length > 0) {
                                // grab first two products
                                var xsellProducts = responseData.products.splice(0,2);

                                for (var i = 0; i < xsellProducts.length; i++) {
                                    renderWWW({
                                        container: xsNode,
                                        product: xsellProducts[i],
                                        index: i
                                    });
                                    // record as product views. 
                                    params = {};
                                    params['TYPE_LOCATION'] = "XSELL~CART";
                                    params['PRODUCT_KEY'] = xsellProducts[i].DEFAULT_CAT_ID + '~' + xsellProducts[i].PRODUCT_ID;
                                    // this would be a nice to have at some point. 
                                    // params['cm_prodview_tag'] = 1;
                                    el.productView.reportProductView(params);
                                }
                            }
                        };

                        if (Object.isArray(cartItem.product.sku.worksWith)) {
                            var xSellArgs = {
                                productIds : [cartItem.product.PRODUCT_ID],
                                sku: cartItem.product.sku,
                                pageContext: 'cart',
                                callback: renderCrossSellPanes
                            };
                            brx.productView.crossSell.init(xSellArgs);
                        }
                    });

                    // 'Continue Shopping' button
                    var continueShoppingBtn = containerNode.select(".continue_shopping")[0];
                    $(continueShoppingBtn).observe("click", function(evt) {
                        generic.overlay.hide();
                    });

                    // update item count
                    var order = generic.checkout.cart.data.order;
                    var samples_count = (order.samples) ? order.samples.length : 0;
                    var resourceName = (obj.totalCartItems == 1) ? "iteminbag" : "itemsinbag";
                    var bagMsg = generic.rb('language').get(resourceName);
                    bagMsg = bagMsg.replace("[#]", obj.totalCartItems + samples_count);
                    qtyNode.update(bagMsg);

                    // set shipping message
                    self.setShippingMessage({
                        node: shippingMsgNode,
                        cartSubTotal: obj.cartSubtotal
                    });
                }
            });
        }
    }
};

document.observe("cart:updated", function(cartEvt) {
    var cartResponseObj = cartEvt.memo;
    el.productView.cartOverlay.launch(cartResponseObj);
    //setTimeout("generic.overlay.hide()",10000);
});


el.productView.favoritesMessageDisplay = {
    getMessage: function(jsonRpcResponse) {
        if (!jsonRpcResponse) {
            return null;
        }

        var rbLanguageHash = generic.rb('language');
        var messages = jsonRpcResponse.getMessages();

        var msgHash = {
            text: messages[0].text,
            key: messages[0].key
        }
       
        return msgHash;
    }
};

document.observe("favorites:updated", function(cartEvt) {
    // EL is not supposed to display the popup when a product
    // is added to favorites. 
});

el.productView.filterTable = function (args) {
    var initFilterChangeEvent = function(selectNode){
        var self = this;
        selectNode.observe('change', function (evt) {
            // evt.target.fire("table:filter", evt.target);
            that.filter(evt.target);
        });
    };
    var filterNodes = new Hash();
    var sortNode = null;
    var tableData;
    var that = {};
    /**
     * This method builds the HTML select menu node.
     * @methodOf el.filter
     * @param {Node} args.filterMenuContainerNode the node where the filter menus will be inserted
     */
    that.createMenus = function(args) {
        var self = this;
        var options = Object.extend({
            filterMenuContainerNode: null,
            tableData: null,
            menuMetaData: null,
            menuWidth: 130 }, args || {});
        for (var i in options) {
            if (options[i] === null) {
                return null;
            }
        }
        tableData = options.tableData;
        var getMenuElements = function(){
            var menus = [];
            options.menuMetaData.filters.each(function(filterObj){
                var slct = initFilterMenu({
                    field: filterObj.field,
                    label: filterObj.label
                });
                if (slct) {
                    menus.push({label: "" + filterObj.label + el.rb.language.filterBy + ':', node: slct});
                }
            });
            return menus;
        };
        var initFilterMenu = function(menuArgs){
            //args.tableData args.field args.label args.menuWidth
            var fields = menuArgs.field.split('::');
            var menuOptions = getMenuOptions(fields);
            if (menuOptions) {
                return buildFilterMenu({
                    menuOptions: menuOptions,
                    fieldName: menuArgs.field,
                    menuLabel: menuArgs.label });
            } else {
                return null;
            }
        };
        var buildFilterMenu = function(buildArgs) {
            var slct = new Element("select", {
                'class' : "width_" + options.menuWidth,
                id : buildArgs.fieldName,
                name : buildArgs.fieldName
            });
            var opt = new Element("option", { value : "" });
            opt.insert( el.rb.language.all );
            slct.insert(opt);
            buildArgs.menuOptions.each( function(val) {
                opt = new Element("option", {
                    value : val
                })
                opt.insert(val);
                slct.insert(opt);
            });
            return slct;
        };
        var getMenuOptions = function(fields){
            var menuOptions = [];
            for (var i = 0, len = fields.length; i<len; i++) {
                var fieldName = fields[i];
                options.tableData.each(function(record){
                    var menuVal = record[fieldName];
                    if (menuVal) {
                        menuOptions.push(menuVal);
                    }
                });
                menuOptions = $A(menuOptions).uniq();
                if (menuOptions.length < 2) {
                    return null;
                }
                return menuOptions;
            }
        };

        var filterMenuObjects = getMenuElements();

        if (filterMenuObjects.length > 0) {
            filterMenuObjects.each(function(record){
                var lbl = new Element('label', {'class':'filterby'});
                lbl.insert(record.label);
                options.filterMenuContainerNode.insert(lbl);
                var slct = record.node;
                options.filterMenuContainerNode.insert(slct);
                self.addFilterNode(slct, slct.name);
            });
        }
    }; // createMenus
    that.addFilterNode = function (selectNode, field) {
      // if (this.validateSelectNode(selectNode)) {
        filterNodes.set(field, selectNode);
        // }
        initFilterChangeEvent(selectNode);
    };

    /**
     * This function registers a select menu as a Sort control for the table.
     * @param {Node} selectNode the select node
     * @param {string} field the name of the field on which this menu will filter.
     * The field must be the name of a top-level property of a tableData item. For example,
     * a table displaying Product items might sort on a field Product.PROD_RGN_NAME.
     * The parameter passing in this case would be "PROD_RGN_NAME".
     * @methodOf productPage.FilterTable
     */
    that.addSortNode = function (selectNode, field) {
        sortNode = selectNode;
        initFilterChangeEvent(selectNode);
    };

    /**
     * This method creates an HTML select menu node, add options, and insert the select menu
     * in the DOM.
     * @param {Node} args.containerNode the node into which the sort menu will be inserted
     * @param {number} args.menuWidth width in pixels of a custom menu to be rendered
     * the select menu takes this number and assigns the node a class of that width.
     * @param {string} args.selectNodeID the ID that will be given to the the select menu node
     * @param {Array} args.sortMenuArray an array of JS Hash objects. These objects define the options that
     * are inserted into the menu - the format must be { field: *string*, label: *string* } where
     * field is the sorting property and label is the text displayed in the menu.
     * @methodOf productPage.FilterTable
     * @returns {Node} the select menu
     */
    that.buildSortMenu = function(args) {
        if (!args.containerNode) {
            return;
        }
        options = Object.extend({
            menuWidth: 100,
            selectNodeID: "sort-menu"
        }, args || {});
        var slct = new Element("select", {
            'class': "width_" + options.menuWidth,
            id: options.selectNodeID,
            name: options.selectNodeID });
        options.sortMenuArray.each(function(sortMenuRecord){
            slct.insert(new Element("option", {
                value: sortMenuRecord.field,
                selected: "selected" }).insert(sortMenuRecord.label));
        });
        options.containerNode.insert(slct);
        return slct;
    };



    /**
     * This function reads the values from filtering and sorting menus, puts the
     * requested items into an array and then passes that array to the build function.
     * It is called when the user changes a filter or sort criteria menu.
     * @methodOf productPage.FilterTable
     */
    that.filter = function() {
        var self = this;
        var filterFunctions = function(field){
            return function(valueToFind, valueToSearch){
                return valueToSearch === valueToFind;
            };
        };
        //
        // iterate through the data and filter out non-matching items
        tableData.each(function(item){
            item.display = false;
            //
            // the keys of the filter_node hash are the names of the fields
            // we are going to filter
            filterNodes.keys().each(function(menuName){
                //
                // menuName can contain multiple field names separated by '::'
                var fields = menuName.split('::');
                var menuValue = $F(filterNodes.get(menuName));
                for (var i=0, len=fields.length; i<len; i++) {
                    var field = fields[i];
                    //
                    // if the data fails the test and if the menu option value
                    // is a non-empty string, do not display the item
                    if (menuValue.length < 1 || filterFunctions(field)(menuValue, item[field])) {
                        item.display = true;
                        break;
                    } else {
                        item.display = false;
                    }
                }
                if (!item.display) {
                    throw $break;
                }
            });
        });
        // Sort data. The menu option value is the name of a product field.
        if (sortNode) {
            var sortCriteria = $F(sortNode);
            if (tableData[0].hasOwnProperty(sortCriteria)) {
                tableData = tableData.sortBy(function(p){
                    return p[sortCriteria];
                });
            }
        }
        this.build(tableData);
    };

    return that;
};

el.productView.formatPriceRange = function(prod) {
    var price_string = '';
    if (generic.productData.validateSkusArray(prod.skus)) {
        var prod_skus_length = prod.skus.length;
        var uniquePricesCount = prod.skus.pluck('PRICE').uniq().length;
        if (uniquePricesCount > 1)  {
            var sortedSkus = prod.skus.sortBy(function(s){return s.PRICE;});
            price_string = sortedSkus[0].formattedPrice;
            price_string += " - " + sortedSkus[prod_skus_length-1].formattedPrice;
        } else {
            price_string = prod.skus[0].formattedPrice;
        }
        return price_string;
    } else {
        return '';
    }
};

el.productView.formatPrice = function(number) {
    // move $ to a rb
    return number + ' ' + 'руб';
};

// TOS treated as 'nonshoppable' here
el.productView.nonShoppableSkusLast = function(skus) {
    var temp = skus.findAll(function(s) {
        return el.productData.isShoppable(s) 
            && !el.productData.isTempOutOfStock(s);
    });
    
    var nonshoppable = skus.findAll(function(s) {
        return !el.productData.isShoppable(s)
            || el.productData.isTempOutOfStock(s);
    });
    
    nonshoppable.each(function(nsSku) {
        temp.push(nsSku);
    });
    
    return temp;
};

el.productView.formatFacebookLink = function(cat, prod, url) {
    var parts = url.split('#');

    if ( ! cat.toString().match(/^CAT/) ) {
        cat = "CAT" + cat;
    }
    
    if ( ! prod.toString().match(/^PROD/) ) {
        prod = "PROD" + prod;
    }

    var tmplurl = [
        'http://www.esteelauder.com/product/facebook.tmpl?CATEGORY_ID=',
        cat,
        '&PRODUCT_ID=',
        prod,
        '&refresh_url=',
        parts[0]
    ].join('');

    if ( parts[1] ) {
        tmplurl += encodeURIComponent( '#' + parts[1]);
    }

    var result = [
        "http://www.facebook.com/sharer.php?u=",
        encodeURIComponent(tmplurl)
    ].join('');

    return( result );
}

