// ------------------------------------
// ---------- jquery.basket -----------
// ------------------------------------
// Controls the shopping basket
// ------------------------------------

; (function ($, window, document, undefined) {

    var pluginName = "basket";

    function basket(element, options) {
        this.element = element;
        this._name = pluginName;
        this._defaults = $.fn.basket.defaults;
        this.options = $.extend({}, this._defaults, options);

        this.init();
    }

    function htmlEncode(value){
        return $("<div/>").text(value).html();
    }

    function htmlDecode(value){
        return $("<div/>").html(value).text();
    }

    function refresh() {
        setTimeout(function () {
            location.reload();
        }, 100);
    }

    $.extend(basket.prototype, {

        init: function () {
            this.buildCache();

            this.bindEvents();
        },
        
        destroy: function () {
            this.unbindEvents();

            this.$element.removeData();
        },

        buildCache: function () {
            this.$element = $(this.element);

            this.$basketCounter = $(this.options.basketCounterId);
            this.$basketTotal = $(this.options.basketTotalId);
            this.$basketLoadingSection = $(this.options.basketLoadingId);
            this.$basketMessage = $(this.options.basketMessageId);            
            this.$itemRemoveButtons = $(this.options.itemRemoveSelector);
            this.$basketCounter = $(this.options.basketCountId);
            this.$basket = $(this.options.basketPanelId);            
            this.$grandTotalContainer = $(this.options.grandTotalContainerId);
            this.$checkoutButton = $(this.options.checkoutBtnId);

            this.basketCounter = parseInt(this.$basketCounter.html());
            this.basketTotal = parseFloat(this.$basketTotal.html());

            if (isNaN(this.basketTotal) === true) {
                this.basketTotal = 0.0;
            }

            if (isNaN(this.basketCounter) === true) {
                this.basketCounter = 0;
            }
        },
        
        bindEvents: function () {
            var plugin = this;
            
            plugin.$itemRemoveButtons.on("click", function (event) {
                event.preventDefault();

                plugin.$basketMessage.hide();
                plugin.$basketLoadingSection.hide();

                var $btn = $(this);

                var itemId = parseInt($btn.data("cartitem"));
                var price = parseFloat($btn.data("itemprice"));
                var $parent = $btn.parent().parent();

                if ($parent.length === 1) {
                    $parent.after(plugin.$basketLoadingSection);
                    $parent.after(plugin.$basketMessage);                    
                }

                if (isNaN(itemId) === true || isNaN(price) === true) {
                    plugin.setBasketMessage("An error has occurred whilst trying to remove the item.", true);
                    return;
                }

                plugin.removeFromBasket($parent, itemId, price);
            });

        },

        unbindEvents: function () {
            var plugin = this;

            plugin.$itemRemoveButtons.off("click");
        },

        setBasketMessage: function (message, showPermanent) {
            var plugin = this;

            plugin.$basketMessage.html(message);
            plugin.$basketMessage.show();

            if (showPermanent === true) {
                return;
            }

            // delaying 5 seconds
            plugin.$basketMessage.delay(3200).fadeOut(300);            
        },

        removeFromBasketTotal: function(priceToRemove) {
            
            var plugin = this;

            if (isNaN(plugin.basketTotal) === true || isNaN(priceToRemove) === true) {
                plugin.$basketTotal.html("");
                return;
            }

            plugin.basketTotal = this.basketTotal - priceToRemove;

            if (plugin.basketTotal < 0) {
                plugin.basketTotal = 0;
            }

            plugin.$basketTotal.html(plugin.basketTotal.toFixed(2));
        },

        decreaseBasketCounter: function() {

            var plugin = this;

            plugin.basketCounter--;

            if (plugin.basketCounter <= 0) {
                plugin.basketCounter = 0;
            }

            plugin.$basketCounter.html(plugin.basketCounter);
            plugin.$basketCounter.attr("title", "You have " + plugin.basketCounter + " item/s to checkout");

            if (plugin.basketCounter === 0) {
                plugin.$checkoutButton.hide();
                plugin.$grandTotalContainer.hide();                
            }

        },

        removeFromBasket: function($itemContainer, itemId, itemPrice) {
          
            var plugin = this;

            $itemContainer.hide();
            plugin.$basketLoadingSection.show();

            if (plugin.options.removeFromBasketUrl === null) {
                plugin.setBasketMessage("No remove from basket url has been set", true);
                return;
            }

            var itemData = {
                cartItemId: itemId
            };
            
            $.ajax({
                type: "POST",
                url: plugin.options.removeFromBasketUrl,
                data: JSON.stringify(itemData),
                dataType: "json",
                contentType: "application/json; charset=utf-8",
                cache: false,
                success: function (data) {
                    if (data === null) {
                        $itemContainer.show();
                        plugin.setBasketMessage("An error has occurred removing the item", true);
                        return;
                    }

                    $itemContainer.remove();

                    plugin.setBasketMessage("Item has been removed", false);


                    if (plugin.options.reloadPageOnRemove) {
                        refresh();
                        return;
                    }

                    plugin.removeFromBasketTotal(itemPrice);
                    plugin.decreaseBasketCounter();

                },
                error: function (jqXHR, textStatus, errorThrown) {

                    $itemContainer.show();
                    plugin.setBasketMessage("An error has occurred whilst trying to remove the item: " + textStatus, true);
                    
                },
                complete: function () {

                    plugin.$basketLoadingSection.hide();
                    
                }
            });
        }

    });

    $.fn.basket = function (options) {
        this.each(function () {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new basket(this, options));
            }
        });

        return this;
    };

    $.fn.basket.defaults = {
        basketCounterId: "#basketCount",
        itemRemoveSelector: ".removeCartItem",        
        basketTotalId: "#basketTotal",
        basketLoadingId: "#basketLoading",
        basketMessageId: "#basketMessage",
        basketCountId: "#basketCount",
        basketPanelId: "#panel",        
        grandTotalContainerId: "#grandTotalDiv",
        checkoutBtnId: "#checkoutBtn",
        removeFromBasketUrl: "/shoppingbasket/removeCartItem/",
        reloadPageOnRemove: false
    };

})(jQuery, window, document);
