/**
 * Manages the user's shopping cart.
 * Data stores as cookie of the user's browser.
 *
 * @requires        jquery.cookie.js
 * @requires        json2.min.js
 */
var ShoppingCart = new Object();
var ShoppingCartHelper = new Object();

(function() {
    // Settings of the shopping cart.
    var settings = {
        // The cookie settings. 1 year as default
        cookie: { expires: 365, name: 'sc' },
        // Product quantity limitations.
        productQuantity: { maximum: 99, minimum: 1 }
    }
    // Products in the user's shopping cart.
    var products;
    // Function to be call when the user deletes a product.
    ShoppingCart.onDeleteProduct = null;
    
    /**
     * Auxiliary Functions
     */
    var auxiliaryFunctions = new Object();
    (function () {
        /**
         * Gets a product (that is in the cart) by its ID.
         *
         * @param       number      a product ID
         * @return      object      information about requested product
         *
         * If a product isn't in the cart, returns null.
         */
        auxiliaryFunctions.getProduct = function(productId) {
            // Convert the product ID to an integer number.
            productId = parseInt(productId);
            // A product ID must be a number that is greater than zero.
            if (!productId > 0)
                return null;
            // The product must be in the cart.
            if (!ShoppingCart.isProductInCart(productId))
                return null;
            // Find and return a copy of the product.            
            var product = new Object();
            jQuery(products).each(function() {
                if (productId == this.id) {
                    product = this;
                    return false;
                }
            } );            
            return product;        
        }; // END auxiliaryFunctions.getProduct = function( productId )
    })(); // END Auxiliary Functions
    
    /**
     * Shopping Cart
     */
    (function () {
        /**
         * Adds a product in the user's shopping cart.
         *
         * @param       number      a product ID
         */
        ShoppingCart.addMultiproduct = function(productId) {
            // Convert the product ID to an integer number.
            productId = parseInt(productId);
            // A product ID must be a number that is greater than zero.
            if (!productId > 0)
                return;
            // Skip the product if it's already in the cart.
            if (ShoppingCart.isProductInCart(productId))
                return;
            // Add the product to the cart.
            products.push({ 'id' : productId, 'quantity' : 1 });
            // Rewrite the cookie.
            ShoppingCart.rewriteCookie();
        }; // END ShoppingCart.addProduct = function( productId )
        
        /**
         * Adds a product in the user's shopping cart.
         *
         * @param       number      a product ID
         */
        ShoppingCart.addProduct = function(productId) {
            // Convert the product ID to an integer number.
            productId = parseInt(productId);
            // A product ID must be a number that is greater than zero.
            if (!productId > 0)
                return;
            // Skip the product if it's already in the cart.
            if (ShoppingCart.isProductInCart(productId))
                return;
            // Add the product to the cart.
            products.push({ 'id' : productId, 'quantity' : 1 });
            // Rewrite the cookie.
            ShoppingCart.rewriteCookie();
        }; // END ShoppingCart.addProduct = function( productId )
        
        // ---------------------------------------------------------------------
        
        /**
         * Calculates the total price of the order.
         *
         * @return      number
         */
        ShoppingCart.calculateTotalPrice = function() {
            var totalPrice = 0;
            // Calculate the total price.
            jQuery(products).each(function() {
                // Check whether the all needed data is correct.
                var isCorrect =
                    typeof(this) == 'object'
                    && 'price' in this && Number(this.price) > 0
                    && 'quantity' in this && Number(this.quantity) > 0;
                if (isCorrect)
                    totalPrice += this.price * this.quantity;
            });
            return totalPrice;
        
        };  // END ShoppingCart.calculateTotalPrice = function ()
        
        // ---------------------------------------------------------------------
        
        /**
         * Decreases quantity of a product (that is in the cart) by 1.
         *
         * @param       number      a product ID
         */
        ShoppingCart.decreaseProductQuantity = function(productId) {
            // Convert the product ID to an integer number.
            productId = parseInt(productId);
            // A product ID must be a number that is greater than zero.
            if (!(productId > 0))
                return;
            // Get the product.
            var product = auxiliaryFunctions.getProduct(productId);
            // Don't continue if the product isn't found in the cart.
            if (product == null)
                return;
            // Decrease the product quantity by 1 and rewrite the cookie.
            if (product.quantity > settings.productQuantity.minimum) {
                product.quantity--;
                ShoppingCart.rewriteCookie();
            }
        }; // END ShoppingCart.decreaseProductQuantity = function (productId)
        
        /**
         * Deletes all products from the shopping cart.
         */
        ShoppingCart.deleteAllProducts = function () {
            // Delete all products from the shopping cart if it's not empty.
            if (products.length > 0) {
                products = new Array();
                // Rewrite the cookie.
                ShoppingCart.rewriteCookie();
            }
        }; // END ShoppingCart.deleteAllProducts = function ()
        
        /**
         * Deletes a product from the shopping cart.
         *
         * @param       number      a product ID
         */
        ShoppingCart.deleteProduct = function(productId) {
            // Convert the product ID to an integer number.
            productId = parseInt(productId);
            // A product ID must be a number that is greater than zero.
            if (!(productId > 0))
                return;
            // Skip the product if it's not in the cart.
            if (!ShoppingCart.isProductInCart(productId))
                return;
            // Delete the product from the cart.
            jQuery(products).each(function(index, value) {
                if (productId == value.id) {
                    products.splice(index, 1);
                    return false;
                }
            });
            // Rewrite the cookie.
            ShoppingCart.rewriteCookie();
            // Invoke the onDeleteProduct event handler
            if ("onDeleteProduct" in ShoppingCart && typeof(ShoppingCart.onDeleteProduct) == "function")
                ShoppingCart.onDeleteProduct();
        }; // END ShoppingCart.deleteProduct = function ()
        
        /**
         * Gets quantity of a product.
         *
         * @param       number      a product ID
         * @return      number      quantity of a product
         *
         * If a requested product is not in the cart, returns null.
         */
        ShoppingCart.getProductQuantity = function(productId) {
            // Convert the product ID to an integer number.
            productId = parseInt(productId);
            // A product ID must be a number that is greater than zero.
            if (!productId > 0)
                return null;
            // Get the product.
            var product = auxiliaryFunctions.getProduct(productId);
            // Don't continue if the product isn't found in the cart.
            if (product == null)
                return null;
            // Return the product quantity.
            return product.quantity;
        }; // END ShoppingCart.getProductQuantity = function (productId)
        
        /**
         * Increases quantity of a product (that is in the cart) by 1.
         *
         * @param       number      a product ID
         */
        ShoppingCart.increaseProductQuantity = function(productId) {
            // Convert the product ID to an integer number.
            productId = parseInt(productId);
            // A product ID must be a number that is greater than zero.
            if (!(productId > 0))
                return;
            // Get the product.
            var product = auxiliaryFunctions.getProduct(productId);
            // Don't continue if the product isn't found in the cart.
            if (product == null)
                return;
            // Increase the product quantity by 1 and rewrite the cookie.
            if (product.quantity < settings.productQuantity.maximum) {
                product.quantity++;
                ShoppingCart.rewriteCookie();
            }
        }; // END ShoppingCart.increaseProductQuantity = function(productId)
        
        /**
         * Checks whether a product is in the user's shopping cart.
         *
         * @param       number      a product ID
         * @return      boolean
         */
        ShoppingCart.isProductInCart = function(productId) {
            // Convert the product ID to an integer number.
            productId = parseInt(productId);
            // A product ID must be a number that is greater than zero.
            if (!productId > 0)
                return false;
            // Check whether the product in the user's shopping cart.
            var isProductInCart = false;
            jQuery(products).each(function() {
                if (productId == this.id) {
                    isProductInCart = true;
                    return false;
                }
            });
            // Return the result.
            return isProductInCart;        
        }; // END ShoppingCart.isProductInCart = function (productId)
        
        // ---------------------------------------------------------------------
        
        /**
         * Obtains the list of products in the user's shopping cart.
         */
        ShoppingCart.reloadFromCookie = function() {
            // Read the encoded value from the cookie. 
            var encodedValue = jQuery.cookie(settings.cookie.name);
            // Process the encoded value.
            if (encodedValue) {
                // If the cookie value is set, it must be a JSON encoded array.
                try {
                    // Try to decode the JSON encoded value.
                    decodedValue = JSON.parse( encodedValue );                    
                    if (decodedValue instanceof Array) {
                        // Filter the array.
                        products = new Array();
                        jQuery(decodedValue).each(function() {
                            // Check whether the array element represents a correct information about a product.
                            var isCorrect = (typeof(this) == 'object' && 'id' in this && 'quantity' in this);
                            // Add the product to the shopping cart, if the data is correct.
                            if ( isCorrect )
                                products.push(this);
                        });
                    } else {
                        products = new Array();
                    }
                } catch ( e ) {
                    products = new Array();
                }
            } else {
                products = new Array();
            }
            // Rewrite the cookie.
            ShoppingCart.rewriteCookie();
        }; // END ShoppingCart.reloadFromCookie = function ()
        
        /**
         * Rewrites the cookie that holds information about products in the
         * user's shopping cart.
         */
        ShoppingCart.rewriteCookie = function() {
            // The cookie options.
            var options = { expires: settings.cookie.expires, path: '/' };
            // Rewrite the cookie.
            if (products && products.length > 0) {
                jQuery.cookie(settings.cookie.name, JSON.stringify(products), options);
            } else {
                jQuery.cookie(settings.cookie.name, null);
                jQuery.cookie(settings.cookie.name, null, { domain: 'gojoy.com.ua' } );
                jQuery.cookie(settings.cookie.name, null, { domain: 'gojoy.ru' } );
                jQuery.cookie(settings.cookie.name, null, { domain: 'test-ver.gojoy.ru' } );
                jQuery.cookie(settings.cookie.name, null, { domain: 'www.gojoy.com.ua' } );
                jQuery.cookie(settings.cookie.name, null, { domain: 'www.gojoy.ru' } );
            }
        }; // END ShoppingCart.rewriteCookie = function ()        
    })(); // END Shopping Cart
    
    // Obtains the list of products in the user's shopping cart.
    ShoppingCart.reloadFromCookie();
    
    /**
     * Shopping Cart Helper
     */
    (function($) {
        /**
         * Refreshes the counter of products in the shopping cart.
         */
        ShoppingCartHelper.refreshCounter = function() {
            // Refresh the counter.
            $('#number-of-products-in-cart').text(products.length);
            // Update the link to the favorites.
            if (products.length > 0) {
                $('#link-to-cart').removeClass('no-items').addClass('has-items');
            } else {
                $('#link-to-cart').removeClass('has-items').addClass('no-items');
            }
        }; // END ShoppingCartHelper.refreshCounter = function ()
        
        /**
         * Refreshes the product list of the shopping cart.
         */
        ShoppingCartHelper.refreshList = function() {
            $('#shopping-cart-products > li').each(function() {
                var listItem = jQuery(this);
                // Get the product ID.
                var productId = listItem.attr('id');
                // Removes the product from the cart.
                $('a.remove-from-shopping-cart', this).click(function() {
                    // Delete the list item.
                    listItem.remove();
                    // Delete the product from the cart.
                    ShoppingCart.deleteProduct(productId);
                    // Update the number of products.
                    ShoppingCartHelper.refreshCounter();
                    // Recalculate the total price.
                    ShoppingCartHelper.refreshTotalPrice();
                });
                // Show the current number of the product.
                var quantityInput = $('input.quantity-value', this);
                quantityInput.val(ShoppingCart.getProductQuantity(productId));
                // Increases the product quantity.
                $('a.increase', this).click(function() {
                    // Increase the product quantity.
                    ShoppingCart.increaseProductQuantity(productId);
                    // Show the current number of the product.
                    quantityInput.val(ShoppingCart.getProductQuantity(productId));
                    // Recalculate the total price.
                    ShoppingCartHelper.refreshTotalPrice();
                });
                // Decreases the product quantity.
                $('a.decrease', this).click(function() {
                    // Decrease the product quantity.
                    ShoppingCart.decreaseProductQuantity(productId);
                    // Show the current number of the product.
                    quantityInput.val(ShoppingCart.getProductQuantity(productId));
                    // Recalculate the total price.
                    ShoppingCartHelper.refreshTotalPrice();
                });
            });
            // Recalculate the total price.
            ShoppingCartHelper.refreshTotalPrice();
        };  // END ShoppingCartHelper.refreshList = function ()
        
        /**
         * Refreshes the total price of the order.
         */
        ShoppingCartHelper.refreshTotalPrice = function() {
            // Calculte the total price and show it.
            $('#total-price-value').text(ShoppingCart.calculateTotalPrice());
        }; // END ShoppingCartHelper.refreshTotalPrice = function ()
    })(jQuery); // END Shopping Cart Helper    
})(); // END Shopping Cart and Shopping Cart Helper

