/**
 * 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 = new Object();

    // The cookie settings.
    settings.cookie =
    {
        'expires' : 365,    // 1 year as default
        'name' : 'sc'
    };
    
    // Product quantity limitations.
    settings.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;
            }
            
            
            // The product must be in the cart.
            if ( ! ShoppingCart.isProductInCart(productId))
            {
                return;
            }
            
            
            // 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.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 isDataCorrect =
                    typeof(this) == 'object'
                    && 'price' in this
                    && Number(this.price) > 0
                    && 'quantity' in this
                    && Number(this.quantity) > 0
                ;
                
                if (isDataCorrect)
                {
                    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;
            }
            
            
            if (product.quantity > settings.productQuantity['minimum'])
            {
                // Decrease the product quantity by 1.
                product.quantity--;
                
                // Rewrite the cookie.
                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();
            
            
            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;
            }
            
            
            if (product.quantity < settings.productQuantity['maximum'])
            {
                // Increase the product quantity by 1.
                product.quantity++;
                
                // Rewrite the cookie.
                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;
            }
        
        
            // 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 isCorrectData =
                                typeof(this) == 'object'
                                && 'id' in this
                                && 'quantity' in this
                            ;
                        
                            // Add the product to the shopping cart, if the data
                            // is correct.
                            if (isCorrectData)
                            {
                                products.push(this);
                            }
                        });
                    }
                    else
                    {
                        // No products specified.
                        products = new Array();
                    }
                }
                catch (e)
                {
                    // No products specified.
                    products = new Array();
                }
            }
            else
            {
                // No products specified.
                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.
            jQuery.cookie
            (
                settings.cookie['name'],
                JSON.stringify(products),
                options
            );
        
        };  // 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.
            jQuery('#number-of-products-in-cart').text(products.length);
            
            // Update the link to the favorites.
            if (products.length > 0)
            {
                jQuery('#link-to-cart')
                    .removeClass('no-items')
                    .addClass('has-items')
                ;
            }
            else
            {
                jQuery('#link-to-cart')
                    .removeClass('has-items')
                    .addClass('no-items')
                ;
            }
        
        };  // END ShoppingCartHelper.refreshCounter = function ()
        
        // ---------------------------------------------------------------------
        
        /**
         * Refreshes the product list of the shopping cart.
         */
        ShoppingCartHelper.refreshList = function ()
        {
            jQuery('#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.
                jQuery('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 = jQuery('input.quantity-value', this);
                quantityInput.val
                (
                    ShoppingCart.getProductQuantity(productId)
                );
                
                // Increases the product quantity.
                jQuery('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.
                jQuery('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.
            jQuery('#total-price-value').text
            (
                ShoppingCart.calculateTotalPrice()
            );
        
        };  // END ShoppingCartHelper.refreshTotalPrice = function ()
    
    })();   // END Shopping Cart Helper
    
})();   // END Shopping Cart and Shopping Cart Helper
