/**
 * Magento Enterprise Edition
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Magento Enterprise Edition License
 * that is bundled with this package in the file LICENSE_EE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.magentocommerce.com/license/enterprise-edition
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category   design
 * @package    enterprise_bellsports
 * @copyright  Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
 * @license    http://www.magentocommerce.com/license/enterprise-edition
 */

/**
 * CONFIGURABLE PRODUCT WITH INDEPENDENT OPTION SELECTION
 * 
 * DEPENDENCIES
 * - js/varien/product.js
 */

Product.ConfigMu = Class.create(Product.Config, {

    /**
     * Internal constructor
     * 
     * @param object config
     * @param int isFancy
     * @param int productId
     * @param string serialNumber
     */
    initialize: function(config, isFancy, productId, serialNumber) {
        this.productId = productId;
        this.config = config;
        this.isfancy = isFancy;
        this.selectedProductsHash = [];
        var relId = this.productId;
        if (serialNumber != null && serialNumber != undefined && serialNumber != false) {
            this.serialNumber = serialNumber;
            relId += '_' + this.serialNumber;
        } else {
            this.serialNumber = false;
        }
        this.taxConfig = this.config.taxConfig;
        this.settings = $$('.super-attribute-select[rel=' + relId + ']');
        this.state = new Hash();
        this.priceTemplate = new Template(this.config.template);
        this.prices = config.prices;

        this.settings.each(function(element) {
            Event.observe(element, 'change', this.configure.bind(this))
        }.bind(this));

        // fill state
        this.settings.each(function(element) {
            var attributeId = element.id.replace(/[a-z]*/, '');
            if(attributeId && this.config.attributes[attributeId.split('_')[0]]) {
                element.config = this.config.attributes[attributeId.split('_')[0]];
                element.attributeId = attributeId;
                this.state[attributeId] = false;
            }
        }.bind(this));

        // Init settings dropdown
        this.settings.each(function(element) {
            this.fillSelect(element, []);
        }.bind(this));

        // try retireve options from url
        var separatorIndex = window.location.href.indexOf('#');
        if (separatorIndex != -1) {
            var paramsStr = window.location.href.substr(separatorIndex + 1);
            this.values = paramsStr.toQueryParams();
            this.settings.each(function(element) {
                var attributeId = element.attributeId;
                element.value = this.values[attributeId];
                this.configureElement(element);
            }.bind(this));
        }

        if ($('product-price-'+this.config.productId)) {
            this.defaultPriceRange = $('product-price-'+this.config.productId).innerHTML;
        }
    },

    /**
     * Configure dropdown on change event
     * 
     * @param HTMLSelectElement element
     */
    configureElement: function(element) {
        this.state[element.config.id] = element.value ? element.value : false;
        this.settings.each(function(ell) {
            //reload all dropdowns
            var selectedProducts = this.getSelectedProducts(ell);
            this.fillSelect(ell, selectedProducts);
            ell.value = this.state[ell.config.id];
            this.reloadOptionLabels(ell, selectedProducts);
        }.bind(this));

        this.reloadPrice();
        Cufon.refresh('.price-box > :not(".old-price")');
    },

    /**
     * Get available products for current elenent
     * 
     * @param HTMLSelectElement element
     * @return array
     */
    getSelectedProducts: function(element) {
        var selectedProducts = [];
        this.settings.each(function(ell) {
            if (element.config.id != ell.config.id) {
                var selectedIndex = ell.selectedIndex > 0 ? ell.selectedIndex : 0;
                if (ell.options[selectedIndex].value) {
                    if (selectedProducts.size() > 0) {
                        if (ell.options[selectedIndex].config && 
                            ell.options[selectedIndex].config.products) {
                            selectedProducts = selectedProducts.intersect(
                                ell.options[selectedIndex].config.products
                            );
                        }
                    } else {
                        selectedProducts = ell.options[selectedIndex].config && 
                                ell.options[selectedIndex].config.products ? 
                                ell.options[selectedIndex].config.products : [];
                    }
                }
            }
        });

        return selectedProducts;
    },

    /**
     * Fill dropdown with options
     * 
     * @param HTMLSelectElement element
     * @param array selectedProducts
     */
    fillSelect: function(element, selectedProducts) {
        var attributeId = element.id.replace(/[a-z]*/, '');
        var options = this.getAttributeOptions(attributeId);
        this.clearSelect(element);
        var lbl = this.getChooseLabel(attributeId, this.config.attributes);
        element.options[0] = new Option(this.config.chooseText + lbl, '');
        if(this.isfancy) {
            $('dd'+attributeId+'-header-val').innerHTML = this.config.chooseText + lbl;
        }

        if(options) {
            var index = 1;
            var fancyContent = '';
            var intersect = [];
            for (var i=0; i<options.length; i++) {
                var allowedProducts = [];
                var isOptionAvailable = true;
                allowedProducts = options[i].products.clone();
                if (selectedProducts && selectedProducts.size() > 0 && 
                    selectedProducts.intersect(allowedProducts).size() == 0) {
                    isOptionAvailable = false;
                }

                if (allowedProducts.size() > 0) {
                    options[i].allowedProducts = allowedProducts;
                    element.options[index] = new Option(
                        this.getOptionLabel(options[i], options[i].price), 
                        options[i].id
                    );
                    element.options[index].config = options[i];
                    if (this.isfancy) {
                        fId = element.options[index].value + '_' + this.productId;
                        if (this.serialNumber != false) {
                            fId += '_' + this.serialNumber;
                        }
                        if (this.optionIsActive(allowedProducts) && isOptionAvailable) {
                            fancyContent += '<li><a href="javascript:void(0);"' + 
                                'onclick="fancyList.f'+attributeId+'.selOption(this);" rel="' + 
                                fId +'" class="fancy-items fancy-active-item">' + 
                                element.options[index].innerHTML + '</a></li>';
                        } else {
                            fancyContent += '<li><a href="javascript:void(0);"' + 
                                'rel="" class="fancy-items fancy-inactive-item">' + 
                                element.options[index].innerHTML+'</a></li>';
                        }
                    }
                    index++;
                }
            }
            if (this.isfancy) {
                $('dd' + attributeId + '-list').innerHTML = fancyContent;
            }
            this.fixTitle($('dd' + attributeId));
        }
    },

    /**
     * Update option labels
     * 
     * @param HTMLSelectElement element
     * @param array selectedProducts
     */
    reloadOptionLabels: function(element, selectedProducts) {
        var selectedPrice;
        var selectedIndex = element.selectedIndex > 0 ? element.selectedIndex : 0;
        if (element.options[selectedIndex].config) {
            selectedPrice = parseFloat(element.options[selectedIndex].config.price);
        } else {
            selectedPrice = 0;
        }
        var fancyUpdateArrTxt = [];
        var fancyUpdateArrIds = [];
        var fancyProducts = [];
        for (var i=0;i<element.options.length;i++) {
            if (element.options[i].config) {
                element.options[i].text = this.getOptionLabel(
                    element.options[i].config, 
                    element.options[i].config.price-selectedPrice
                );
                fancyUpdateArrTxt[i] = element.options[i].text;
                fancyUpdateArrIds[i] = element.options[i].value;
                var allowedProducts = element.options[i].config.allowedProducts
                if (selectedProducts && selectedProducts.size() > 0) {
                    allowedProducts = selectedProducts.intersect(allowedProducts);
                }
                fancyProducts[i] = {
                    'products':element.options[i].config.products, 
                    'allowedProducts': allowedProducts
                }
            }
        }
        if (this.isfancy) {
            var fancyAttrId = element.id.replace(/[a-z]*/, '');
            this.fillFancy(
                fancyUpdateArrTxt, 
                fancyUpdateArrIds, 
                fancyAttrId, 
                element.options[selectedIndex], 
                fancyProducts
            );
        }
    },

    /**
     * Check whether option active
     * 
     * @param array element
     * @return bool
     */
    optionIsActive: function(allowedProducts) {
        var saleableProducts = this.config.saleableProducts;
        if (saleableProducts == null) {
            return true;
        }
        for (var i=0; i<allowedProducts.length; i++) {
            if (allowedProducts[i] in saleableProducts) {
                return saleableProducts[allowedProducts[i]];
            }
        }
        return false;
    },

    /**
     * Get default label
     * 
     * @param int attrId
     * @param array attributes
     * @return string
     */
    getChooseLabel: function(attrId, attributes) {
        var vowels = "aeiouAEIOU";
        var lbl = attributes[attrId.split('_')[0]].label;
        return ' '+lbl;
    },

    /**
     * Update dropdowns with fancy content
     * 
     * @param array updArr
     * @param array updIds
     * @param string attrId
     * @param HTMLOptionElement selIndex
     * @param array fancyProducts
     */
    fillFancy: function(updArr, updIds, attrId, selIndex, fancyProducts) {
        var fancyContent = '';
        var lbl = this.getChooseLabel(attrId, this.config.attributes);
        if (selIndex.value == '') {
            $('dd'+attrId+'-header-val').innerHTML = this.config.chooseText + lbl;
            $('dd'+attrId+'-header-val').removeClassName('selected');
            Validation.validate($('attribute'+attrId));
        } else {
            $('dd'+attrId+'-header-val').innerHTML = selIndex.innerHTML;
            $('dd'+attrId+'-header-val').addClassName('selected');
            Validation.validate($('attribute'+attrId));
            fancyContent += '<li><a href="javascript:void(0);" onclick="fancyList.f' + 
                attrId + '.selOption(this);" rel="" class="fancy-items">' + 
                this.config.chooseText+lbl + '</a></li>';
        }
        for (var i=1; i < updArr.length; i++) {
            aId = updIds[i] + '_' + this.productId;
            if (this.serialNumber != false) {
                aId += '_' + this.serialNumber;
            }
            if (this.optionIsActive(fancyProducts[i].allowedProducts)) {
                fancyContent += '<li><a href="javascript:void(0);" onclick="fancyList.f' + 
                    attrId + '.selOption(this);" rel="' + aId + '" class="fancy-items fancy-active-item' + 
                    (selIndex.value == updIds[i] ? ' active' : '' ) + '">' + updArr[i] + '</a></li>';
            } else {
                fancyContent += '<li><a href="javascript:void(0);" rel="" class="fancy-items fancy-inactive-item' + 
                    (selIndex.value == updIds[i] ? ' active' : '' ) + '">' + updArr[i] + '</a></li>';
            }
        }
        $('dd' + attrId + '-list').innerHTML = fancyContent;
        this.fixTitle($('dd' + attrId));
    },

    /**
     * Get attribute options
     * 
     * @param string attributeId
     * @return array
     */
    getAttributeOptions: function(attributeId) {
        if (this.config.attributes[attributeId.split('_')[0]]) {
            return this.config.attributes[attributeId.split('_')[0]].options;
        }
    },

    /**
     * Reload product price
     * 
     */
    reloadPrice: function() {
        var price = 0;
        var isDefaultLabels = true;

        for (var i=this.settings.length-1;i>=0;i--) {
            var selectedIndex = this.settings[i].selectedIndex > 0 ? this.settings[i].selectedIndex : 0;
            var selected = this.settings[i].options[selectedIndex];
            if (selected.config) {
                price += parseFloat(selected.config.price);
            }
            if (selected.value != '') {
                isDefaultLabels = false;
            }
        }

        var opId = 'optionsPrice' + this.config.productId;
        if (this.serialNumber != false) {
            opId += '_' + this.serialNumber;
        }
        eval(opId).changePrice('config', price);
        if (this.config.allowRandeLabel && isDefaultLabels && this.defaultPriceRange) {
            $('product-price-'+this.config.productId).innerHTML = this.defaultPriceRange;
        } else {
            eval(opId).reload();
        }
    },

    /**
     * Disable dropdown option
     * 
     * @param HTMLOptionElement element
     */
    disableOption: function(element) {
        var attributeId = element.id.replace(/[a-z]*/, '');
        $('dd' + attributeId).setOpacity(0.5);
        $('dd' + attributeId + "-content").setOpacity(0);
        this.fixTitle($('dd' + attributeId));
    },

    /**
     * Enable dropdown option
     * 
     * @param HTMLOptionElement element
     */
    enableOption: function(element) {
        var attributeId = element.id.replace(/[a-z]*/, '');
        $('dd' + attributeId).setOpacity(1);
        $('dd' + attributeId+"-content").setOpacity(1);
    },

    /**
     * Apply design to dropdown title
     * 
     * @param HTMLDListElement dd
     */
    fixTitle: function(dd) {
        setTimeout(function() {
            if (dd.getElementsByTagName('dt')[0] && 
                dd.getElementsByTagName('dt')[0].getElementsByTagName('span')[0]) {
                var span = dd.getElementsByTagName('dt')[0].getElementsByTagName('span')[0];
                str = span.innerHTML;
                span.title = str;
                var padding = parseInt($(span.parentNode).getStyle('paddingLeft')) + 
                    parseInt($(span.parentNode).getStyle('paddingRight'));
                var oldSpanWidth = span.offsetWidth + padding;
                var parentNodeWidth = parseInt(dd.parentNode.offsetWidth > 0) ? 
                    dd.parentNode.offsetWidth : dd.getElementsByTagName('dt')[0].offsetWidth;
                if (parentNodeWidth > 0 && parentNodeWidth < span.offsetWidth + padding) {
                    while (parentNodeWidth < span.offsetWidth + padding) {
                        oldSpanWidth = span.offsetWidth + padding;
                        str = str.substr(0, str.length - 1);
                        span.innerHTML = str + ' ...';
                        if (span.offsetWidth == span.offsetWidth + padding) {
                            break;
                        }
                    }
                }
            }
        },0);
    }
});


Product.OptionsPrice.prototype.reload = function () {
    var price;
    var formattedPrice;
    var optionPrices = this.getOptionPrices();
    var nonTaxable = optionPrices[1];
    optionPrices = optionPrices[0];
    $H(this.containers).each(function(pair) {
        var _productPrice;
        var _plusDisposition;
        var _minusDisposition;
        if ($(pair.value)) {
            if (pair.value == 'old-price-'+this.productId && this.productOldPrice != this.productPrice) {
                _productPrice = this.productOldPrice;
                _plusDisposition = this.oldPlusDisposition;
                _minusDisposition = this.oldMinusDisposition;
            } else {
                _productPrice = this.productPrice;
                _plusDisposition = this.plusDisposition;
                _minusDisposition = this.minusDisposition;
            }

            var price = optionPrices+parseFloat(_productPrice)
            if (this.includeTax == 'true') {
                // tax = tax included into product price by admin
                var tax = price / (100 + this.defaultTax) * this.defaultTax;
                var excl = price - tax;
                var incl = excl*(1+(this.currentTax/100));
            } else {
                var tax = price * (this.currentTax / 100);
                var excl = price;
                var incl = excl + tax;
            }

            excl += parseFloat(_plusDisposition);
            incl += parseFloat(_plusDisposition);
            excl -= parseFloat(_minusDisposition);
            incl -= parseFloat(_minusDisposition);

            //adding nontaxlable part of options
            excl += parseFloat(nonTaxable);
            incl += parseFloat(nonTaxable);

            if (pair.value == 'price-including-tax-'+this.productId) {
                price = incl;
            } else if (pair.value == 'old-price-'+this.productId) {
                if (this.showIncludeTax || this.showBothPrices) {
                    price = incl;
                } else {
                    price = excl;
                }
            } else {
                if (this.showIncludeTax) {
                    price = incl;
                } else {
                    if (!this.skipCalculate || _productPrice == 0) {
                        price = excl;
                    } else {
                        price = optionPrices+parseFloat(_productPrice);
                    }
                }
            }

            if (price < 0) price = 0;

            if (price > 0 || this.displayZeroPrice) {
                formattedPrice = this.formatPrice(price);
            } else {
                formattedPrice = '';
            }

            if ($(pair.value).select('.price-range')[0]) {
                $(pair.value).select('.price-range')[0].innerHTML = formattedPrice;
                if ($(pair.value+this.duplicateIdSuffix) && $(pair.value+this.duplicateIdSuffix).select('.price-range')[0]) {
                    $(pair.value+this.duplicateIdSuffix).select('.price-range')[0].innerHTML = formattedPrice;
                }
            } else {
                $(pair.value).addClassName('price');
                $(pair.value).innerHTML = formattedPrice;
                if ($(pair.value+this.duplicateIdSuffix)) {
                    $(pair.value+this.duplicateIdSuffix).innerHTML = formattedPrice;
                }
            }
        };
    }.bind(this));
};

