/**
* 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 Varien
* @package js
* @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
* @license http://www.magentocommerce.com/license/enterprise-edition
*/
if(typeof selectedAssocProducts=='undefined') {
    var selectedAssocProducts = {};
}
if(typeof Product=='undefined') {
    var Product = {};
}
/**************************** CONFIGURABLE PRODUCT **************************/
Product.Config = Class.create();
Product.Config.prototype = {
    initialize: function(config){
        // Shouldn't all of this happen ONLY if the dom is loaded?
        this.config = config;
        this.taxConfig = this.config.taxConfig;
        this.settings = $$('.super-attribute-select');
        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]) {
                element.config = this.config.attributes[attributeId];
                element.attributeId = attributeId;
                this.state[attributeId] = false;
            }
        }.bind(this))
        // Init settings dropdown
        var childSettings = [];
        for(var i=this.settings.length-1;i>=0;i--){
            var prevSetting = this.settings[i-1] ? this.settings[i-1] : false;
            var nextSetting = this.settings[i+1] ? this.settings[i+1] : false;
            if(i==0){
                this.fillSelect(this.settings[i])
            }
            else {
                this.settings[i].disabled=true;
            }
            $(this.settings[i]).childSettings = childSettings.clone();
            $(this.settings[i]).prevSetting = prevSetting;
            $(this.settings[i]).nextSetting = nextSetting;
            childSettings.push(this.settings[i]);
        }
        // Set default values - from config and overwrite them by url values
        if (config.defaultValues) {
            this.values = config.defaultValues;
        }
        var separatorIndex = window.location.href.indexOf('?');
        if (separatorIndex != -1) {
            var paramsStr = window.location.href.substr(separatorIndex+1);
            var urlValues = paramsStr.toQueryParams();
            if (!this.values) {
                this.values = {};
            }
            for (var i in urlValues) {
                this.values[i] = urlValues[i];
            }
        }
    //jQuery(document).ready(function() {
    // spConfig.configureForValues();
    //});
    },
    configureForValues: function () {
        if (this.values) {
            this.settings.each(function(element){
                var attributeId = element.attributeId;
                element.value = (typeof(this.values[attributeId]) == 'undefined')? '' : this.values[attributeId];
                this.configureElement(element);
            }.bind(this));
            // Sort out the zoomer... but this time, init it
            this.sortOutZoomer( true );
        }
    },
    configure: function(event){
        var element = Event.element(event);
        this.configureElement(element);
    },
    configureElement : function(element) {
        this.reloadOptionLabels(element);
        if(element.value){
            this.state[element.config.id] = element.value;
            if(element.nextSetting){
                element.nextSetting.disabled = false;
                this.fillSelect(element.nextSetting);
                this.resetChildren(element.nextSetting);
            } else if(element.prevSetting) {
                element.prevSetting.disabled = false;
                this.reloadOptionLabels(element.prevSetting);
            }
        }
        else {
            this.resetChildren(element);
        }
        this.reloadPrice();
        for ( var i = 0; i < element.options.length; i++ ) {
            if ( element.options[i].value == element.value ) {
                if (element.options[i].disabled) {
                    jQuery('div.add-to-cart p.availability').removeClass().addClass('availability').addClass('out-of-stock')
                    .html('Availability: <span>Out of stock</span>');
                }
                else{
                    jQuery('div.add-to-cart p.availability').removeClass().addClass('availability').addClass('in-stock')
                    .html('Availability: <span>In stock</span>');
                }
            }
        }
        if (!element.value || element.value.substr(0,6) == 'Please' || element.value == "Select...") return; // Selected "choose option"
        var attributeId = element.id.replace(/[a-z]*/, '');
        for (var a in this.config.attributes) {
            for (i = 0; i < this.config.attributes[a].options.length; i++) {
                if (this.config.attributes[a].options[i].id != element.value) continue;
                selectedAssocProducts[a] = this.config.attributes[attributeId].options[i].products;
            }
        }
        // if a colour was set/changed
        if ( attributeId == '80')
        {
            // preload the description via ajax for this colour attribute
            var productNo = intersect(selectedAssocProducts) || selectedAssocProducts[attributeId][0];
            this.reloadDescription(productNo);
            this.sortOutZoomer();
        }
    },
    sortOutZoomer: function( init ) {
        var attributeId = '80';
        if ( init ) {
            for (var a in this.config.attributes) {
                for (i = 0; i < this.config.attributes[a].options.length; i++) {
                    if (this.config.attributes[a].options[i].id != this.values["80"]) continue;
                    selectedAssocProducts[a] = this.config.attributes[attributeId].options[i].products;
                }
            }
        }
        var productNo = intersect(selectedAssocProducts) || selectedAssocProducts[attributeId][0];
        var assoc_tmp = assocIMG[productNo].split(',');
        var assoc_tmp_zoom = fullIMG[productNo].split(',');
        var assoc_tmp_thumbnail = thumbIMG[productNo].split(',');
        var tmp_html = "";
        // For the set of associated images (for the given product number)
        // create a NEW ordered list of thumbs
        for(i=0;i<assoc_tmp.length;i++)
        {
            tmp_html +='<li><a ';
            if ( i === 0 ) {
                // First thumb in our gallery/thumb list should become the active one.
                tmp_html += ' class="zoomThumbActive"';
            } else {
                tmp_html += ' class=""';
            }
            // @note, our thumbs have onclick attributes
            tmp_html += ' rel="{smallimage:\'' + assoc_tmp[i] + '\', largeimage:\'' + assoc_tmp_zoom[i] + '\'}" href="javascript:void(0);" onclick="spConfig.switchImage(this);" ><img src="' + assoc_tmp_thumbnail[i] + '" height="64" width="64" /></a></li>';
        }
        jQuery('div.more-views > ul').html(tmp_html);
        var prodview = jQuery('.prodview');
        var theJQZoom = prodview.data('jqzoom');
        // A jqzoom exists...
        if ( theJQZoom && jQuery('.zoomThumbActive').length > 0 ) {
            // we have a thumb list, lets set the active zoom to be the first
            // in the list
            var thumb = jQuery('.zoomThumbActive' );
            theJQZoom.swapimage( thumb );
            // And load the appropriate description via ajax
            this.reloadDescription(productNo);
        // We can exit now...
        } else {
            var options = {
                offset:10,
                zoomWidth: 410,
                zoomHeight: 360,
                //xOffset:110,
                zoomType: 'standard',
                lens:false,
                position:"right",
                preload:true
            };
            if ( jQuery('.zoomThumbActive').length > 0 ) {
                var prodview = jQuery('.prodview');
                prodview.jqzoom(options);
                // NOW we should have a jqzoom...
                theJQZoom = prodview.data('jqzoom');
                // we should have an active item...
                var thumb = jQuery('.zoomThumbActive' );
                theJQZoom.swapimage( thumb );
            }
        }
    },
    switchImage: function( thumb ) {
        // Return if this is the active thumb...
        if(jQuery( thumb ).hasClass('zoomThumbActive')){
            return false;
        }
        // Not the active thumb, remove the active thumb
        jQuery( '.zoomThumbActive' ).removeClass( 'zoomThumbActive' );
        // tell jqzoom to swap to this new thumb
        var prodview = jQuery('.prodview');
        var theJQZoom = prodview.data('jqzoom');
        theJQZoom.swapimage( thumb );
    },
    reloadDescription: function(productNo){
        //Update descriptions!
        var url = '/index.php/ajaxproduct';
        var pars = 'id='+productNo[0]+'&attribute=description';
        var target = 'tabs-1';
        var myAjax = new Ajax.Updater(target, url, {
            method: 'get', 
            parameters: pars
        });
    },
    isOutOfStock: function(productId) {
        if (this.config.saleable[productId] == 1) {
            return false;
        }
        return true;
    },
    reloadOptionLabels: function(element){
        var selectedPrice;
        if(element.options[element.selectedIndex].config){
            selectedPrice = parseFloat(element.options[element.selectedIndex].config.price)
        }
        else{
            selectedPrice = 0;
        }
        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);
            }
        }
    },
    resetChildren : function(element){
        delete selectedAssocProducts[element.config.id]; // Added
        if(element.childSettings) {
            for(var i=0;i<element.childSettings.length;i++){
                element.childSettings[i].selectedIndex = 0;
                element.childSettings[i].disabled = true;
                delete selectedAssocProducts[element.childSettings[i].config.id]; // Added
                if(element.config){
                    this.state[element.config.id] = false;
                }
            }
        }
    },
    fillSelect: function(element){
        var attributeId = element.id.replace(/[a-z]*/, '');
        var options = this.getAttributeOptions(attributeId);
        this.clearSelect(element);
        element.options[0] = new Option(this.config.chooseText, '');
        var prevConfig = false;
        if(element.prevSetting){
            prevConfig = element.prevSetting.options[element.prevSetting.selectedIndex];
        }
        if(options) {
            var index = 1;
            var colours="";
            for(var i=0;i<options.length;i++){
                var allowedProducts = [];
                if(prevConfig) {
                    for(var j=0;j<options[i].products.length;j++){
                        if(prevConfig.config.allowedProducts
                            && prevConfig.config.allowedProducts.indexOf(options[i].products[j])>-1){
                            // For the current available product, determine if it is out of stock
                            if ( this.isOutOfStock( options[i].products[j] ) )
                                options[i].disabled = true;
                            else
                                options[i].disabled = false;
                            allowedProducts.push(options[i].products[j]);
                        }
                    }
                } else {
                    allowedProducts = options[i].products.clone();
                }
                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];
                    element.options[index].disabled = options[i].disabled;
                    index++;
                }
            }
        }
    },
    getOptionLabel: function(option, price){
        var price = parseFloat(price);
        if (this.taxConfig.includeTax) {
            var tax = price / (100 + this.taxConfig.defaultTax) * this.taxConfig.defaultTax;
            var excl = price - tax;
            var incl = excl*(1+(this.taxConfig.currentTax/100));
        } else {
            var tax = price * (this.taxConfig.currentTax / 100);
            var excl = price;
            var incl = excl + tax;
        }
        if (this.taxConfig.showIncludeTax || this.taxConfig.showBothPrices) {
            price = incl;
        } else {
            price = excl;
        }
        var str = option.label;
        if(price){
            if (this.taxConfig.showBothPrices) {
            //str+= ' ' + this.formatPrice(excl, true) + ' (' + this.formatPrice(price, true) + ' ' + this.taxConfig.inclTaxTitle + ')';
            } else {
            //str+= ' ' + this.formatPrice(price, true);
            }
        }
        return str;
    },
    formatPrice: function(price, showSign){
        var str = '';
        price = parseFloat(price);
        if(showSign){
            if(price<0){
                // str+= '-';
                price = -price;
            }
            else{
            // str+= '+';
            }
        }
        var roundedPrice = (Math.round(price*100)/100).toString();
        if (this.prices && this.prices[roundedPrice]) {
            str+= this.prices[roundedPrice];
        }
        else {
            str+= this.priceTemplate.evaluate({
                price:price.toFixed(2)
                });
        }
        return str;
    },
    clearSelect: function(element){
        for(var i=element.options.length-1;i>=0;i--){
            element.remove(i);
        }
    },
    getAttributeOptions: function(attributeId){
        if(this.config.attributes[attributeId]){
            return this.config.attributes[attributeId].options;
        }
    },
    reloadPrice: function(){
        var price = 0;
        var oldPrice = 0;
        for(var i=this.settings.length-1;i>=0;i--){
            var selected = this.settings[i].options[this.settings[i].selectedIndex];
            if(selected.config){
            // price += parseFloat(selected.config.price);
            // oldPrice += parseFloat(selected.config.oldPrice);
            }
        }
        // optionsPrice.changePrice('config', {'price': price, 'oldPrice': 0 });
        // optionsPrice.reload();
        return price;
        if($('product-price-'+this.config.productId)){
            $('product-price-'+this.config.productId).innerHTML = price;
        }
        this.reloadOldPrice();
    },
    reloadOldPrice: function(){
        if ($('old-price-'+this.config.productId)) {
            var price = parseFloat(this.config.oldPrice);
            for(var i=this.settings.length-1;i>=0;i--){
                var selected = this.settings[i].options[this.settings[i].selectedIndex];
                if(selected.config){
                    price+= parseFloat(selected.config.price);
                }
            }
            if (price < 0)
                price = 0;
            price = this.formatPrice(price);
            if($('old-price-'+this.config.productId)){
                $('old-price-'+this.config.productId).innerHTML = price;
            }
        }
    }
}
/**************************** SUPER PRODUCTS ********************************/
Product.Super = {};
Product.Super.Configurable = Class.create();
Product.Super.Configurable.prototype = {
    initialize: function(container, observeCss, updateUrl, updatePriceUrl, priceContainerId) {
        this.container = $(container);
        this.observeCss = observeCss;
        this.updateUrl = updateUrl;
        this.updatePriceUrl = updatePriceUrl;
        this.priceContainerId = priceContainerId;
        this.registerObservers();
    },
    registerObservers: function() {
        var elements = this.container.getElementsByClassName(this.observeCss);
        elements.each(function(element){
            Event.observe(element, 'change', this.update.bindAsEventListener(this));
        }.bind(this));
        return this;
    },
    update: function(event) {
        var elements = this.container.getElementsByClassName(this.observeCss);
        var parameters = Form.serializeElements(elements, true);
        new Ajax.Updater(this.container, this.updateUrl + '?ajax=1', {
            parameters:parameters,
            onComplete:this.registerObservers.bind(this)
        });
        var priceContainer = $(this.priceContainerId);
        if(priceContainer) {
            new Ajax.Updater(priceContainer, this.updatePriceUrl + '?ajax=1', {
                parameters:parameters
            });
        }
    }
}
/**************************** PRICE RELOADER ********************************/
Product.OptionsPrice = Class.create();
Product.OptionsPrice.prototype = {
    initialize: function(config) {
        this.productId = config.productId;
        this.priceFormat = config.priceFormat;
        this.includeTax = config.includeTax;
        this.defaultTax = config.defaultTax;
        this.currentTax = config.currentTax;
        this.showIncludeTax = config.showIncludeTax;
        this.showBothPrices = config.showBothPrices;
        this.productPrice = config.productPrice;
        this.productOldPrice = config.productOldPrice;
        this.skipCalculate = config.skipCalculate;//@deprecated after 1.5.1.0
        this.duplicateIdSuffix = config.idSuffix;
        this.specialTaxPrice = config.specialTaxPrice;
        this.oldPlusDisposition = config.oldPlusDisposition;
        this.plusDisposition = config.plusDisposition;
        this.oldMinusDisposition = config.oldMinusDisposition;
        this.minusDisposition = config.minusDisposition;
        this.optionPrices = {};
        this.containers = {};
        this.displayZeroPrice = true;
        this.initPrices();
    },
    setDuplicateIdSuffix: function(idSuffix) {
        this.duplicateIdSuffix = idSuffix;
    },
    initPrices: function() {
        this.containers[0] = 'product-price-' + this.productId;
        this.containers[1] = 'bundle-price-' + this.productId;
        this.containers[2] = 'price-including-tax-' + this.productId;
        this.containers[3] = 'price-excluding-tax-' + this.productId;
        this.containers[4] = 'old-price-' + this.productId;
    },
    changePrice: function(key, price) {
        this.optionPrices[key] = price;
    },
    getOptionPrices: function() {
        var price = 0;
        var nonTaxable = 0;
        var oldPrice = 0;
        var priceInclTax = 0;
        var currentTax = this.currentTax;
        $H(this.optionPrices).each(function(pair) {
            if ('undefined' != typeof(pair.value.price) && 'undefined' != typeof(pair.value.oldPrice)) {
                price += parseFloat(pair.value.price);
                oldPrice += parseFloat(pair.value.oldPrice);
            } else if (pair.key == 'nontaxable') {
                nonTaxable = pair.value;
            } else if (pair.key == 'priceInclTax') {
                priceInclTax += pair.value;
            } else if (pair.key == 'optionsPriceInclTax') {
                priceInclTax += pair.value * (100 + currentTax) / 100;
            } else {
                price += parseFloat(pair.value);
                oldPrice += parseFloat(pair.value);
            }
        });
        var result = [price, nonTaxable, oldPrice, priceInclTax];
        return result;
    },
    reload: function() {
        var price;
        var formattedPrice;
        var optionPrices = this.getOptionPrices();
        var nonTaxable = optionPrices[1];
        var optionOldPrice = optionPrices[2];
        var priceInclTax = optionPrices[3];
        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 = 0;
                if (pair.value == 'old-price-'+this.productId && optionOldPrice !== undefined) {
                    price = optionOldPrice+parseFloat(_productPrice);
                } else {
                    price = optionPrices+parseFloat(_productPrice);
                    priceInclTax += parseFloat(_productPrice) * (100 + this.currentTax) / 100;
                }
                if (this.specialTaxPrice == 'true') {
                    var excl = price;
                    var incl = priceInclTax;
                } else 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 == 'price-excluding-tax-'+this.productId) {
                    price = excl;
                } 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 {
                        price = excl;
                    }
                }
                if (price < 0) price = 0;
                if (price > 0 || this.displayZeroPrice) {
                    formattedPrice = this.formatPrice(price);
                } else {
                    formattedPrice = '';
                }
                if ($(pair.value).select('.price')[0]) {
                    $(pair.value).select('.price')[0].innerHTML = formattedPrice;
                    if ($(pair.value+this.duplicateIdSuffix) && $(pair.value+this.duplicateIdSuffix).select('.price')[0]) {
                        $(pair.value+this.duplicateIdSuffix).select('.price')[0].innerHTML = formattedPrice;
                    }
                } else {
                    $(pair.value).innerHTML = formattedPrice;
                    if ($(pair.value+this.duplicateIdSuffix)) {
                        $(pair.value+this.duplicateIdSuffix).innerHTML = formattedPrice;
                    }
                }
            };
        }.bind(this));
    },
    formatPrice: function(price) {
        return formatCurrency(price, this.priceFormat);
    }
}
function intersect(ar) // ar can be an array of arrays or an asssociative array
{
    if (ar == null) return false;
    var a = new Array();
    if (ar.length == undefined) // Associate Array
    {
        for (var i in ar)
            a.push(ar[i]);
    }
    else
        a = ar;
    if (a.length == 1) return false; // Single array ? Nothing to intersect with
    var common = new Array();
    function loop(a, index, s_index, e_index)
    {
        if (index == null) index = 0;
        if (s_index == null) s_index = 0;
        if (e_index == null) e_index = a[index].length;
        if (index == a.length - 1) return;
        for (var i = s_index; i < e_index; i++)
        {
            if (common.indexOf(a[index][i]) != -1) continue;
            for (var j = 0; j < a[index + 1].length; j++)
            {
                if (a[index][i] != a[index+1][j]) continue;
                loop(a, index + 1, j, j + 1);
                if (index + 1 == a.length - 1) {
                    common.push(a[index][i]);
                    break;
                }
            }
        }
    }
    loop(a);
    return common;
}
