Array.prototype.intersect = function(someArray) {
    if (!Object.isArray(someArray)) {
        throw 'Wrong parameter type: need Array, but got ' + (typeof someArray);
        return;
    }
    var shorter = this.length <= someArray.length ? this : someArray;
    var longer  = this.length >  someArray.length ? this : someArray;

    var result = [];

    shorter.each(function(elem) {
        if (longer.indexOf(elem) != -1) {
            result.push(elem);
        }
    });

    return result;
};


if (typeof Product=='undefined') {
    var Product = {};
}

Jarlssen = Class.create();

Jarlssen.Common = Class.create();

Jarlssen.Common.fireEvent = function(/*Object*/node, /*String*/eventName) {
    var myNode = typeof node === 'string' ? $(node) : node;
    var myEventName = Jarlssen.Common._normalizeEventName(eventName);
    if (document.createEvent) {
        var myEvent = document.createEvent('HTMLEvents');
        myEvent.initEvent(myEventName, false, true);
    }
    if (document.createEvent) {
        myNode.dispatchEvent(myEvent);
    } else {
        myNode.fireEvent('on' + myEventName);
    }
};

Jarlssen.Common._normalizeEventName = function(/*String*/eventName) {
    var tmpName = (eventName.toString()).toLowerCase();
    if (tmpName.substr(0, 2) === 'on') {
        tmpName = tmpName.substr(2);
    }
    return tmpName;
};

/**
 * **********CONFIGURABLE PRODUCT BENNY BIKE
 * SIZE/COLOR*******************************
 */
Product.ConfigBennyBikeColor = Class.create();
Product.ConfigBennyBikeColor.prototype = {
    initialize : function(config) {
        this.config = config;
        this.taxConfig = this.config.taxConfig;
        this.settings = $$('.super-attribute-select-color');
        this.state = new Hash();
        this.priceTemplate = new Template(this.config.template);
        this.prices = config.prices;
        this._imagePrefix = '/skin/frontend/bennybike/default/images/media/test/bennybike';

        // Init settings dropdown
        for ( var i = this.settings.length - 1; i >= 0; i--) {
            this.initList(this.settings[i]);
            Event.observe(this.settings[i].select('ul')[0], 'click', this.configure.bind(this));
        }
    },

    matchProduct: function() {
        var result = [];

        Object.values(this.config.attributes).each(function(elem) {
            var value = this._getCurrentAttributeValue(elem.id);
            elem.options.each(function(elemInner) {
                if (elemInner.id == value) {
                    if (result.length < 1) {
                        result = elemInner.products.clone();
                    } else {
                        result = result.intersect(elemInner.products);
                    }
                }
            });
        }.bind(this));
        return result.reduce();
    },

    _getCurrentAttributeValue: function(attributeId) {
        var radios = document.getElementsByName('super_attribute[' + attributeId + ']');
        var returnVal = null;
        $A(radios).each(function(elem) {
            if (elem.checked) {
                returnVal = elem.value;
                return false;
            }
        });
        if (returnVal === null) {
            returnVal = this.config.attributes[attributeId].defaultValue;
        }
        return returnVal;
    },

    getAttributeId: function(element) {
        return element.id.replace(/[a-z]*/, '');
    },

    // wrapper for binding configuration to an element
    configure : function(event) {
        var element = Event.element(event);
        this.configureElement(element);
    },

    configureElement : function(element) {
        // console.log(element);
        // this.reloadOptionLabels(element);

        if (element.next()) {
            element.up().up().select('li a').each(function(e, i) {
                e.removeClassName('active');
            });
            element.next().checked = true;
            var prodId = this.matchProduct();
            element.addClassName('active');

            /* load new image */
            $('product-loader').show();
            url = this.config.images[prodId];
            if (!url) {
                url = '/skin/frontend/bennybike/default/images/outofstock.png';
            }
            new Ajax.Request(
                url,
                {
                    method: 'get',
                    onSuccess: function(transport) {
                        $$('.product-image img')[0].src = url;
                        $('product-loader').hide();
                    }
                }
            );
        }

        //this.reloadPrice();
    },

    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) {
        if (element.childSettings) {
            for ( var i = 0; i < element.childSettings.length; i++) {
                element.childSettings[i].selectedIndex = 0;
                element.childSettings[i].disabled = true;
                if (element.config) {
                    this.state[element.config.id] = false;
                }
            }
        }
    },

    initList : function(element) {
        var attributeId = this.getAttributeId(element);

        var attribute = this.getAttribute(attributeId);
        var options = this.getAttributeOptions(attributeId);
        var images = this.config.images;
        var defaultImage = false;

        if (options) {
            var activeId = false;
            var list = new Element('ul');
            for (var i = 0; i < options.length; i++) {
                var isActive = attribute.defaultValue == options[i].id;
                var currentId = attribute.code + '_' + attribute.id + '_' + options[i].id;
                if (isActive) {
                    activeId = currentId;
                }
                list.insert(
                    '<li>' +
                        '<a class="' + attribute.code + '_' + options[i].id + ' ' + options[i].label + ' ' + (isActive ? 'active' : '') + '" href="javascript:void(0)">' +
                            '<span>' + options[i].label + '</span>' +
                        '</a>' +
                        '<input ' + (isActive ? 'checked="checked"' : '') + ' id="' + currentId + '" name="super_attribute[' + attribute.id + ']"  type="radio" value="' + options[i].id + '" style="display: none" />' +
                    '</li>'
                );
            }
            element.insert(list);
            if (activeId) {
                $(activeId).checked = true;
                $(activeId).defaultChecked = true;
            }
        }

        var defaultImage = images[this.matchProduct()];

        new Ajax.Request(defaultImage, {
            onComplete: function(response) {
                ($$('.product-image img')[0]).src = defaultImage;
//                for (var idx in images) {
//                    new Ajax.Request(images[idx]);
//                }
            }
        });

    },

    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;
    },

    getAttributeOptions : function(attributeId) {
        if (this.config.attributes[attributeId]) {
            return this.config.attributes[attributeId].options;
        }
    },

    getAttribute : function(attributeId) {
        if (this.config.attributes[attributeId]) {
            return this.config.attributes[attributeId];
        }
    },

    reloadPrice : function() {
        var price = 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);
            }
        }

        optionsPrice.changePrice('config', price);
        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;
            }

        }
    }
};

//var spConfig = new Product.Config( {
//    "attributes" : {
//        "76" : {
//            "id" : "76",
//            "code" : "color",
//            "label" : "Color",
//            "options" : [ {
//                "id" : "11",
//                "label" : "orange",
//                "price" : "0",
//                "products" : [ "7", "13" ]
//            }, {
//                "id" : "12",
//                "label" : "pink",
//                "price" : "0",
//                "products" : [ "8", "9" ]
//            }, {
//                "id" : "13",
//                "label" : "silver",
//                "price" : "0",
//                "products" : [ "10", "14" ]
//            } ]
//        },
//        "499" : {
//            "id" : "499",
//            "code" : "size",
//            "label" : "Size",
//            "options" : [ {
//                "id" : "17",
//                "label" : "Mini",
//                "price" : "0",
//                "products" : [ "7", "8", "14" ]
//            }, {
//                "id" : "18",
//                "label" : "Maxi",
//                "price" : "5",
//                "products" : [ "9", "10", "13" ]
//            } ]
//        }
//    },
//    "template" : "#{price} \u20ac",
//    "basePrice" : "19.95",
//    "oldPrice" : "19.95",
//    "productId" : "11",
//    "chooseText" : "Option w\u00e4hlen...",
//    "taxConfig" : {
//        "includeTax" : 1,
//        "showIncludeTax" : true,
//        "showBothPrices" : false,
//        "defaultTax" : 19,
//        "currentTax" : 19,
//        "inclTaxTitle" : "Inkl. Steuern"
//    }
//});

Product.ConfigBennyBikeSize = Class.create(
    Product.ConfigBennyBikeColor,
    {
        initialize : function(config) {
            this.config = config;
            this.taxConfig = this.config.taxConfig;
            this.settings = $$('.super-attribute-select-size');
            this.state = new Hash();
            this.priceTemplate = new Template(this.config.template);
            this.prices = config.prices;

            // Init settings dropdown
            for ( var i = this.settings.length - 1; i >= 0; i--) {
                this.initList(this.settings[i]);
                this.settings[i].select('input').each(function(el) {
                    Event.observe(el, 'click', this.configure.bind(this));
                }.bind(this));
            }
        },
        initList : function(element) {
            var attributeId = this.getAttributeId(element);

            var attribute = this.getAttribute(attributeId);
            var options = this.getAttributeOptions(attributeId);

            if (options) {
                var activeId = false;
                var list = new Element('ul');
                for (var i = 0; i < options.length; i++) {
                    var isActive = attribute.defaultValue == options[i].id;
                    var currentId = attribute.code + '_' + attribute.id + '_' + options[i].id;
                    if (isActive) {
                        activeId = currentId;
                    }
                    list.insert(
                        '<li ' + (isActive ? 'class="active"' : '') + '>' +
                            '<input ' + (isActive ? 'checked="checked" defaultChecked="true"' : '') + ' id="' + currentId + '" name="super_attribute[' + attribute.id + ']"  type="radio" value="' + options[i].id + '" />' +
                            '<label for="' + currentId + '">' + options[i].label + '</label>' +
                        '</li>'
                    );
                }
                element.insert(list);

                if (activeId) {
                    $(activeId).checked = true;
                    $(activeId).defaultChecked = true;
                }

            }
        },
        configureElement : function(element) {
            // this.reloadOptionLabels(element);
            element.up().up().select('li').each(function(e, i) {
                e.removeClassName('active');
            });

            if (element.up()) {
                var prodId = this.matchProduct();
                element.up().addClassName('active');

                /* load new image */
                $('product-loader').show();
                url = this.config.images[prodId];
                if (!url) {
                    url = '/skin/frontend/bennybike/default/images/outofstock.png';
                }
                new Ajax.Request(
                    url,
                    {
                        method: 'get',
                        onSuccess: function(transport) {
                            $$('.product-image img')[0].src = url;
                            $('product-loader').hide();
                        }
                    }
                );
            }

            //this.reloadPrice();
        }
    }
);

var EventDelegator = Class.create({
    initialize: function(sourceSelector, targetSelector, eventName) {
        this.targets = $$(targetSelector);
        this.sources = $$(sourceSelector);
        if (this.targets.length !== this.sources.length) {
            throw 'Differing amounts of sources and targets';
            return;
        }
        this.eventName = eventName;
        this.sources.each(function(elem, index) {
            Event.observe(elem, this.eventName, this._getDelegationHandler(index, this.eventName).bindAsEventListener(this));
        }.bind(this));
    },
    _getDelegationHandler: function(index, eventName) {
        return function(event) {
            Jarlssen.Common.fireEvent(this.targets[index], eventName);
        };
    }
});
