// Author: Entropy 
// Version: 0.8.3

(function ($) {
    function roundTo(value/*:Number*/, digits/*:Number*/) {
        return Math.round(value * Math.pow(10, -digits)) / Math.pow(10, -digits);
    }

    function padWithZeros(value/*:Number*/, digits/*:Number*/)/*:String*/{
        value = value.toString();
        var dotIndex = value.indexOf(".");
        var decimalPartLength;
        if (dotIndex == -1) {
            decimalPartLength = 0;
            value += digits > 0 ? "." : "";
        } else {
            decimalPartLength = value.length - dotIndex - 1;
        }
        var padTotal = digits - decimalPartLength;
        for (var i = 0; i < padTotal; i++) value += "0";
        return value;
    }

    function formatMoney(value) {
        return padWithZeros(value, 2).replace(".", ",") + "р.";
    }

    function ShoppingCart(sender, options) {
        this.options = options;
        this.shoppingCartElement = $(sender);
        this.itemListElement = $("ul:first, ol:first", this.shoppingCartElement);
        this.checkoutButtonElement = $(".checkout:first", this.shoppingCartElement);
        this.cancelButtonElement = $(".cancel:first", this.shoppingCartElement);
        this.totalSumElement = $(".subtotal:first", this.shoppingCartElement);
        $(this.shoppingCartElement).data("cart", this);
        $(this.shoppingCartElement).find("input:reset").bind("click.entropyShoppingCart", function () {
            var cart = $(this).closest(".shopping-cart").data("cart");
            cart.emptyItems();
            cart.saveItems();
        });
    }

    ShoppingCart.prototype = {
        items: {},
        removeItem: function (id) {
            if (typeof id != "number") {
                id = id.id;
            }
            delete (this.items[id]);
            $(this.itemListElement).find("*[data-id='" + id + "']").remove();
            this.update();
            this.saveItems();
        },

        getSubtotal: function () {
            var result = 0;
            for (var key in this.items) {
                var item = this.items[key];
                result += roundTo(item.count * item.price, -2);
            }
            return roundTo(result, -2);
        },

        getItem: function (id) {
            return this.items[id];
        },

        getItems: function () {
            var result = [];
            for (var key in this.items) {
                var item = this.items[key];
                result.push(item);
            }
            return result;
        },

        getItemCount: function () {
            var result = 0;
            for (var key in this.items) result++;
            return result;
        },

        empty: function () {
            return this.items = {};
        },

        _addItem: function (item) {
            item.count = item.count || 1;
            var oldItem = this.items[item.id];
            if (oldItem) {
                item.count = oldItem.count + item.count;
                this.items[item.id] = item;
                return false;
            } else {
                this.items[item.id] = item;
                return true;
            }
        },
        saveItems: function () {
            this.options.saveItems(this.items);
        },

        emptyItems: function () {
            this.itemListElement.empty();
            this.totalSumElement.html(formatMoney(0));
            this.empty();
        },

        update: function () {
            $(this.totalSumElement).html(formatMoney(this.getSubtotal()));
            if (this.getItemCount() == 0) {
                $(this.checkoutButtonElement).attr("disabled", "disabled");
            } else {
                $(this.checkoutButtonElement).removeAttr("disabled");
            }
        },

        addItem: function (item) {
            if (this._addItem(item)) {
                this.addItemElement(item);
            } else {
                var itemElement = $(this.itemListElement).find("*[data-id=" + item.id + "]:first");
                $("input:text:first", itemElement).val(item.count);
            }
        },

        destroy: function () {
            this.itemListElement.empty();
            this.totalSumElement.empty();
            this.shoppingCartElement.unbind(".entropyShoppingCart");
            $(this.options.buttonSelector).unbind(".entropyShoppingCart");
            $(this.shoppingCartElement).find("input:reset").unbind(".entropyShoppingCart");
        },

        addItemElement: function (item) {
            var cart = this;
            var itemElement = $(cart.options.itemTemplate);
            $(itemElement).attr("data-id", item.id);
            $("button, input:reset", itemElement).bind("click.entropyShoppingCart", function () {
                $(this).closest(".shopping-cart").data("cart")._removeItem(this);
            });
            $(".name", itemElement).html(item.name);
            $(".price", itemElement).html(formatMoney(item.price));
            $("input:text", itemElement).val(item.count);
            $("input:text", itemElement).SpinButton({
                min: cart.options.minValue,
                max: cart.options.maxValue,
                _btn_width: cart.options.spinButtonWidth,
                _btn_height: cart.options.spinButtonHeight,
                valueChanged: function (sender, e) {
                    cart.valueChanged(sender, e);
                }
            });
            $("img", itemElement).attr("src", item.image);
            $(this.itemListElement).append(itemElement);
        },

        _removeItem: function (sender) {
            this.removeItem(this.getItemId(sender));
        },

        getItemId: function (sender) {
            return Number($(sender).closest("*[data-id]").attr("data-id"));
        },

        valueChanged: function (sender, e) {
            this.getItem(this.getItemId(sender)).count = e.newValue;
            this.update();
            this.saveItems();
        },

        loadItems: function () {
            var items = this.options.loadItems();
            for (var i = 0; i < items.length; i++) {
                this.addItem(items[i]);
            }
            this.update();
        }
    };

    function getShoppingCart(sender, options) {
        var cart = new ShoppingCart(sender, options);
        $(cart.options.buttonSelector).bind("click.entropyShoppingCart", addToCart); //todo not here?
        cart.emptyItems();
        cart.loadItems();
        function addToCart() {
            var item = cart.options.getItem(this);
            cart.addItem(item);
            cart.update();
            cart.saveItems();
            return false;
        }

        return cart;
    }

    $.fn.shoppingCart = function (options) {
        switch (options) {
            case "destroy":
                return this.each(function () {
                    var cart = $(this).data("cart");
                    if (cart) {
                        cart.destroy();
                    }
                });
            case "models":
                var carts = [];
                this.each(function (index, element) {
                    carts.push($(element).data("cart"));
                });
                return carts;
            default:
                options = $.extend({}, $.fn.shoppingCart.defaults, options);
                return this.each(function () {
                    getShoppingCart(this, options);
                });
        }
    };

    $.fn.shoppingCart.defaults = {
        buttonSelector: ".product input:submit",
        itemTemplate: '<li>'
        + '<img src="" />'
        + '<div class="name"></div>'
        + '<input type="text">'
        + '<div class="price"></div>'
        + '<button>Remove</button>'
        + '</li>',
        minValue: 1,
        maxValue: 100,
        spinButtonWidth: 20,
        spinButtonHeight: 8,
        getItem: function (sender) {
            var itemElement = $(sender).closest("*[data-id]");
            return {
                id: Number($(itemElement).attr("data-id")),
                name: $(itemElement).attr("data-name"),
                price: Number($(itemElement).attr("data-price")),
                image: "/Content/Images/NoImageSmall.png"
            };
        },

        loadItems: function () {
            return loadFromCookies("ShoppingCart");
        },

        saveItems: function (items) {
            if (!navigator.cookieEnabled) return alert("Your browser does not support cookies. Please enable cookies or use another browser.");
            return saveToCookies(items, "ShoppingCart", "/");
        }
    };
})(jQuery);




