/* Shopping cart javascript class.
(Based largely on the Smart Cart jQuery plugin - http://www.techlaboratory.net/products.php?product=scat) */
var shoppingcart = $.inherit(Module, {
    __constructor: function(elem) { 
        this.__base(elem);
        this.products = [];
        this.$ol; // the list of products that we are manipulating
        this.lastAddedItemId = 0;
    },

    // This will be called from the published side only
    initialize: function() {
        this.cartInit();
        this.getProductsFromDb(createRef(this, this.setUpCheckOut));
    },

    cartInit: function() {

        var _this = this;

        this.scItemList = $('select', this.container);    // the hidden select element holds the selected product list
        this.scItemAnchors = $('.scItemButton', this.container); // "add to cart" buttons
        this.scCartList = $('#sc_cartlist', this.container); //Cart list elemetn
        this.scMessageBox = $('#sc_message', this.container); //Message display element
        this.$ol = $("<ul></ul>").addClass('scULList').attr('id', 'scULList');

        // Put up the initial "Your Cart is Empty!" message
        this.scCartList.html('<div class="emptymsg"><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Your Cart is Empty!</b></div>');

        // Add Change Event
        var selectChangeEvent = function(e) {
            _this.$ol.empty();

            _this.scItemList.children("option").each(
                function(n) {
                    var $t = $(this);

                    // Mark every entry in the <select> as selected
                    if (!$t.is(":selected")) {
                        $t.attr('selected', true);
                    }

                    var tmpVal = $t.val().split('|');          

                    if (!$t.attr('rel')) { // set the rel if not
                        $t.attr('rel',  tmpVal[0]);     
                    }

                    $t.attr('id', 'sc' + 'option' + n);
                    var id = $t.attr('id'); 

                    if ($t.html()=='') { // set the item name if not
                        var itemName =  $('#prod_name' + tmpVal[0]).html();
                        $t.html(itemName);
                    }

                    // logic for grouping multiple item entries
                    var listRel = $t.attr('rel');
                    var listItems = _this.scItemList.children("option[rel=" + $t.attr('rel') + "]"); 

                    if (listItems.length > 1) {
                        var mulPId = 0;
                        var mulQty = 0;
                        var tmpOption = $t;

                        listItems.each(
                            function(n) {
                                var tmpRel = $(this, _this.scItemList).attr('value');
                                var tmpRelVal = tmpRel.split('|');
                                mulPId = tmpRelVal[0];
                                mulQty = mulQty + (tmpRelVal[1]-0);
                            }
                        );

                        _this.scItemList.children("option[rel=" + $t.attr('rel') + "]").remove();
                        $t.val(mulPId+"|"+mulQty)
                        _this.scItemList.append($t); 
                    }
                }
            ); 

            _this.resetListItem();
            $('#sc_subtotal', _this.container).html(_this.calculateSubTotal());
        }

        this.scItemList.change(selectChangeEvent).addClass('scProductSelect');
        
        // Bind the "Add to cart" button events
        this.scItemAnchors.click(
            function(e) {
                var prodId = _this.lastAddedItemId = $(this).attr('rel');
                var prodName = $('#prod_name' + prodId).html();
                var prodQty = ((isNaN($('#prod_qty' + prodId).val())) ? 1 : $('#prod_qty' + prodId).val());

                if (prodQty) {
                    var $option = $("<option></option>").text(prodName).val(prodId+"|"+prodQty).attr("selected", true);
                    $(_this.scItemList).append($option).change();
                    //$('#prod_qty' + prodId).val('1');         

                    // Show a short highlighting animation on the newly-added product's line
                    $('li[rel='+_this.lastAddedItemId+']', _this.container).effect('highlight', {}, 2000);
                }
                else {
                    alert("Please include a quantity for this product.");
                    $('#prod_qty' + prodId).focus();
                }
            }
        );
    },

    // Handles cart product list updates after the addition or removal of items from the cart
    resetListItem: function() {
        var _this = this;

       // refresh the html list 
       this.$ol.empty();
       this.container.find('.emptymsg').remove();

        if (this.scItemList.children("option").length > 0) {
            var _this = this;

            this.scItemList.children("option").each(
                function(n) {
                    var tmpOpt = $(this);

                    var dropListItem = function(relId, highlightItem) { 
                        var $item = _this.$ol.children("li[rel=" + relId + "]"); 
                        $item.remove();
                        _this.scItemList.children("option[rel=" + relId + "]").remove();
                        _this.scItemList.change();
                    }

                    var $removeLink = $("<a></a>")
                        .attr("href", "#")
                        .addClass('scListItemRemove')
                        .prepend("remove")
                        .click(function() { 
                            dropListItem($(this).parent('li').attr('rel')); 
                            return false; 
                        });

                    var itemVal = $(this, _this.scItemList).val();
                    var tmp = itemVal.split('|');
                    var itemId = tmp[0];
                    var itemQty = tmp[1];
                    var itemPrice =  $('#prod_price' + itemId).html();
                    var itemTotal = itemPrice*itemQty;
                    itemTotal = itemTotal.toFixed(2);
                    var itemText = "<table width='100%'><tr><td>"+tmpOpt.html()+"</td><td width='70px'>"+itemQty+
                        "</td><td width='130px'>"+itemTotal+"</td></tr></table>";
                    var $itemLabel = $("<span></span>")
                        .addClass('scListItemLabel')
                        .html(itemText); 

                   var $item = $("<li></li>")
                       .attr('rel', itemId)
                       .addClass('scCartListItem')
                       .append($itemLabel)
                       .append($removeLink)
                       .hide();

                   _this.$ol.append($item);
                   $(_this.scCartList).prepend(_this.$ol);
                   $item.show();
               }
            );
        }
       else {
           // Cart is empty
           this.$ol.html('<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Your Cart is Empty!</b> You can select items from the product list.');
       }
   },

    // Figure out which currency symbol to use for this cart's products
    getCurrencySymbol: function() {
        switch(this.options.currency) {
            case 'EUR': var currencySymbol = '€'; break;
            case 'JPY': var currencySymbol = '¥'; break;
            case 'GBP': var currencySymbol = '£'; break;
            case 'CAD':
            case 'USD': var currencySymbol = '$'; break;
            default: 
        }

        return currencySymbol;
    },

    // Calculate the value of the products in the cart
    calculateSubTotal: function() {
        var subTotal = 0;

        this.scItemList.children("option").each(
            function(n) {
                var $t = $(this);
                var tmpVal = $t.val().split('|');
                var itemId = tmpVal[0];
                var itemQty = tmpVal[1];
                var itemPrice =  $('#prod_price' + itemId).html();
                subTotal += itemPrice*itemQty;     
            }
        ); 

        subTotal = subTotal.toFixed(2);
        return subTotal;
    },

    // Get the products from the database (needed for checkout functionality)
    getProductsFromDb: function(callbackFunc) {
        var _this = this;
        this.ajaxPost('getProducts', {},
            function(data, textSuccess) {
                // Save products and then possibly perform a callback function
                _this.products = eval('(' + data.response + ')');
                (callbackFunc || $.noop)();
            }
        );
    },

    // This is called as a callback from loadModule.
    loadModuleCallback: function(data) {

        var _this = this;
        this.draghandle.addOptionLink("Manage Products", createRef(this, this.displayProductManagement));

        // We need to use innerHTML here because of the (highly probable)
        // chance that the html we get back has <script> in it.  jQuery 1.4
        // tries to be smart and not insert non-standard code.
        this.container[0].innerHTML = data.html;

        // Add module draghandle, initialize smart cart
        this.addDragHandle(data);
        this.cartInit();

        // Get products from the database (required for checking out)
        this.getProductsFromDb();

        // Set up checkout processing
        this.setUpCheckOut();

        // Set the options coming in from the load process
        this.setOptions(data.options);
    },


    // Set up what happens when user click the Checkout button
    setUpCheckOut: function() {
        var _this = this;

        // Set up checkout button functionality
        $('.checkoutBtn', this.container).click(function() {
            var addedProducts = $('.shoppingForm', _this.container).find('option');

            if (addedProducts.length > 0) {
                var i = 1;

                addedProducts.each(function() {
                    // Split the value of this option tag to get the item id and quantity
                    var id_qty = $(this).val().split('|');
                    var id = id_qty[0];
                    var qty = id_qty[1];
                    var thisProduct = _this.products[id];

                    // Gather data to send to the off-site shopping cart
                    var name = thisProduct.name;
                    var price = thisProduct.price;
                    var amount = thisProduct.price * qty;

                    var itemFields = 
                        '<input type="hidden" name="item_name_' + i + '" value="' + name + '" />\
                        <input type="hidden" name="amount_' + i + '" value="' + price + '" />\
                        <input type="hidden" name="quantity_' + i + '" value="' + qty + '" />';

                    $(itemFields).appendTo('.checkoutform');
                    i++;
                });

                // Submit the checkout form to send this data to PayPal
                $('.checkoutform').submit();
            }
            else {
                alert("Please add at least one product to your cart before checking out.");
            }
        });
    },

    /* Handles the retrieval and display of products associated with this cart */
    displayProductManagement: function() {
        var _this = this;

        var mb = new ModalBox({
            title: "Manage Products",
            onClose: function() { _this.initialize() },
			width : 640
        });

        var loadProducts = function(cb) {
            _this.ajaxPost('getProducts', {}, function(data) {
                _this.products = eval('(' + data.response + ')');
                (cb || $.noop)();
            });
        }

        // Create a product listing and append it to the document so we can use it in the colorbox below
        var displayProductList = function() {
            mb.setTitle("Product List");
            var optionsDiv = $('<div></div>').attr('id', 'productlist_' + _this.id).addClass('productListingHolder');
            var idx = 0;
            var currencySymbol = _this.getCurrencySymbol();

            if (!$.isEmptyObject(_this.products)) {
                $.each(_this.products, function() {
                    var name = (this.name ? this.name : '(Unnamed item)');
                    var price = (this.price ? this.price : '(No price)');
                    var desc = (this.description ? this.description : '(No description)');
                    var isOdd = (idx++ % 2 == 0) ? '' : 'mgrProductOdd';

                    // Messy blob of HTML for the specific product entry.
                    var $productEntryContainer = $("<div></div>").addClass("mgrProductListing " + isOdd).appendTo(optionsDiv);
                    if (this.image) {
                        $productEntryContainer.append($("<img />").addClass("productimage").attr("src", this.image));
                    }

                    var thisProduct = this;

                    var $editLink = $("<a></a>").html(name).attr({
                        "href": "#",
                        "class": "editlink",
                        "id": this.product_oid
                        }).click(function() {
                            editProductPopup(thisProduct);
                        });

                    var $productEntry = $("<div></div>").addClass("productListingInfo float_left");
                    $productEntry.append($editLink);
                    $productEntry.append($('<strong class="pricing">Price: ' + currencySymbol + price + '</strong><p>' + desc + '</p>'));
                    $productEntry.appendTo($productEntryContainer);
                });
            }
            else {
                $('<p class="noproducts">You have no products.</p>').appendTo(optionsDiv);
            }


            mb.setHTML(optionsDiv);
            mb.addButton("Add Product", addProductPopup, 'blue');
            mb.addButton("Close", function() {
                _this.loadModule();
                mb.close();
            });
        }


        var addProductPopup = function() {
            mb.setTitle("Add a New Product");
            // Load a form for adding a product
            var editDiv = $('<div></div>');
            var formHtml = 
                '<form id="editform">\
					<fieldset class="scInputs float_left">\
                    <label for="name">Name:</label> <input type="text" id="name" value="" /><br />\
                    <label for="price">Price:</label> <input type="text" id="price" value="" /><br />\
                    <label for="description">Description:</label> <textarea id="description"></textarea>\
                    </fieldset>\
					<div class="imageEditHolder float_right">\
                    <a href="#" class="mediamgrlink scBtn shoppingRadius shoppingBackground shoppingBorder">Add an image</a>\
					</div>\
					<br class="clr" /><div class="link_image_holder"></div>\
                    <input type="hidden" id="image" value="" />\
                </form>';

            $(formHtml).appendTo(editDiv);

            var onClickSave = function() {
                // Collect form values and save the product 
                var formOptions = {};

                $.each($(':input', '#editform'), function() {
                    formOptions[$(this).attr('id')] = $(this).val();
                });

                _this.ajaxPost('addNewProduct', formOptions, function(data) {
                    // Bring the user back to the product listing
                    loadProducts(displayProductList);
                });
            }

            var onClickCancel = function() {
                displayProductList();
            }

            mb.setHTML(editDiv);
            mb.addButton("Save", onClickSave, "blue");
            mb.addButton("Cancel", onClickCancel);

            // Function to be called on the opening of the add product form
            var onComplete = function() {

                // Hook up media selection functionality
                $('.mediamgrlink', editDiv).click(function() {
                    loadMedia();
                });

                // Display the images the user may select for this product
                var loadMedia = function() {
                    var $imageWindow = $(".link_image_holder");
                    $imageWindow.html('<h3 class="txt_center">Loading...</h3><br /><p class="txt_center"><img src="/adm/images/loading.gif"/></p>');
                    $.getJSON("/adm/userdata.php?site=" + _EDITOR.getSiteId() + "&filter=media", function(data) {
                        $imageWindow.empty();
                        for (i in data.Media.media) {
                            if (data.Media.media[i]._mediaType == 'image') {
                                var thisImage = data.Media.media[i];

                                var $i = $("<img />", {
                                    "src": thisImage._thumb,
                                    "title": thisImage._caption,
                                    "data": {'full-image': thisImage._file },
                                    "class": 'link_image'
                                });

                                $i.click(function() {
                                    // Mark this image as the one to use for this product
                                    var imageUrl = $(this).data('full-image');
                                    $('#image', '#editform').val(imageUrl);

                                    $imageWindow.children().removeClass("link_image_selected");
                                    $("#link-href-media").val($(this).data('full-image'));
                                    $(this).addClass('link_image_selected');
                                });

                                $i.appendTo($imageWindow);
                            }
                        }
                    });
                }
            }

            onComplete();
        }


        // Load a form for individual product editing
        var editProductPopup = function(thisProduct) {
            mb.setTitle("Editing: " + thisProduct.name);
            var editDiv = $('<div></div>');

            var formHtml = 
                '<form id="editform">\
				<fieldset class="scInputs float_left">\
                    <label for="name">Name:</label> <input type="text" id="name" value="' + thisProduct.name   + '" /><br />\
                    <label for="price">Price:</label>' + _this.getCurrencySymbol()  +'<input type="text" id="price" value="' + thisProduct.price   + '" /><br />\
                    <label for="description">Description:</label> <textarea type="text" row="8" id="description">' + thisProduct.description + '</textarea>\
                   </fieldset>\
				    <div class="imageEditHolder float_right">\
                    <a href="#" class="mediamgrlink scBtn shoppingRadius shoppingBackground shoppingBorder">Add an image</a>\
                    <div class="productimagediv" style="display: ' + (thisProduct.image ? 'block' : 'none') + ';">\
                        <br /><img class="productimage" src="' + thisProduct.image  + '" />\
                        <br /><a href="#" class="deleteimagelink">Delete Image</a>\
                    </div>\
					</div>\
					<br class="clr" /><div class="link_image_holder">\
                    </div>\
                    <input type="hidden" id="image" value="' + thisProduct.image  + '" />\
                    <input type="hidden" id="product_oid" value="' + thisProduct.product_oid  + '" />\
                </form>';

            $(formHtml).appendTo(editDiv);

            // Hook up media selection functionality
            $('.mediamgrlink', editDiv).click(function() {
                loadMedia();
            });

             // Hook up media delete funciontality
             $('.deleteimagelink', editDiv).click(function() {
                 $('.productimagediv', editDiv).css('display', 'none');
                 $('#image', editDiv).val('');
             });

            // Display the images the user may select for this product
            var loadMedia = function() {
                var $imageWindow = $(".link_image_holder");
                $imageWindow.html('<h3 class="txt_center">Loading...</h3><br /><p class="txt_center"><img src="/adm/images/loading.gif"/></p>');
                $.getJSON("/adm/userdata.php?site=" + _EDITOR.getSiteId() + "&filter=media", function(data) {
                    $imageWindow.empty();
                    for (i in data.Media.media) {
                        if (data.Media.media[i]._mediaType == 'image') {
                            var thisImage = data.Media.media[i];

                            var $i = $("<img />", {
                                "src": thisImage._thumb,
                                "title": thisImage._caption,
                                "data": {'full-image': thisImage._file },
                                "class": 'link_image'
                            });

                            $i.click(function() {
                                // Mark this image as the one to use for this product
                                var imageUrl = $(this).data('full-image');
                                $('#image', '#editform').val(imageUrl);

                                $imageWindow.children().removeClass("link_image_selected");
                                $("#link-href-media").val($(this).data('full-image'));
                                $(this).addClass('link_image_selected');
                            });

                            $i.appendTo($imageWindow);
                        }
                    }
                });
            }

            var onClickSave = function() {
                // Collect form values and save the product 
                var formOptions = {};

                $.each($(':input', '#editform'), function() {
                    formOptions[$(this).attr('id')] = $(this).val();
                });

                _this.ajaxPost('saveProduct', formOptions, function(data) {
                    // Bring the user back to the product listing
                    loadProducts(displayProductList);
                });
            }

            var onClickDelete = function() {
                var sure = confirm('Are you sure you want to delete this item?')
                if (sure) {
                    // Collect form values and save the product 
                    var formOptions = {};
                    formOptions['product_oid'] = $('#product_oid', editDiv).val();

                    _this.ajaxPost('deleteProduct', formOptions, function(data) {
                        // Bring the user back to the product listing
                        loadProducts(displayProductList);
                    });
                }
            }

            var onClickCancel = function() {
                displayProductList();
            }

            mb.setHTML(editDiv);

            // Add the Save and Cancel buttons
            mb.addButton("Save", onClickSave, "blue");
            mb.addButton("Delete", onClickDelete);
            mb.addButton("Cancel", onClickCancel);
        }

        mb.setHTML("<p></p>");
        mb.open(loadProducts(displayProductList));
    }
});

