/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE_AFL.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * 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.
 *
 * @copyright  Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
 * @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 */
if(typeof Product=='undefined') {
    var Product = {};
}

/********************* IMAGE ZOOMER ***********************/

Product.Zoom = Class.create();
/**
 * Image zoom control
 *
 * @author      Magento Core Team <core@magentocommerce.com>
 */
Product.Zoom.prototype = {
    initialize: function(imageEl, trackEl, handleEl, zoomInEl, zoomOutEl, hintEl){
        this.containerEl = $(imageEl).parentNode;
        this.imageEl = $(imageEl);
        this.handleEl = $(handleEl);
        this.trackEl = $(trackEl);
        this.hintEl = $(hintEl);

        this.containerDim = Element.getDimensions(this.containerEl);
        this.imageDim = Element.getDimensions(this.imageEl);

        this.imageDim.ratio = this.imageDim.width/this.imageDim.height;

        this.floorZoom = 1;

        if (this.imageDim.width > this.imageDim.height) {
            this.ceilingZoom = this.imageDim.width / this.containerDim.width;
        } else {
            this.ceilingZoom = this.imageDim.height / this.containerDim.height;
        }

        if (this.imageDim.width <= this.containerDim.width
            && this.imageDim.height <= this.containerDim.height) {
            this.trackEl.up().hide();
            this.hintEl.hide();
            this.containerEl.removeClassName('product-image-zoom');
            return;
        }

        this.imageX = 0;
        this.imageY = 0;
        this.imageZoom = 1;

        this.sliderSpeed = 0;
        this.sliderAccel = 0;
        this.zoomBtnPressed = false;

        this.showFull = false;

        this.selects = document.getElementsByTagName('select');

        this.draggable = new Draggable(imageEl, {
            starteffect:false,
            reverteffect:false,
            endeffect:false,
            snap:this.contain.bind(this)
        });

        this.slider = new Control.Slider(handleEl, trackEl, {
            axis:'horizontal',
            minimum:0,
            maximum:Element.getDimensions(this.trackEl).width,
            alignX:0,
            increment:1,
            sliderValue:0,
            onSlide:this.scale.bind(this),
            onChange:this.scale.bind(this)
        });

        this.scale(0);

        Event.observe(this.imageEl, 'dblclick', this.toggleFull.bind(this));

        Event.observe($(zoomInEl), 'mousedown', this.startZoomIn.bind(this));
        Event.observe($(zoomInEl), 'mouseup', this.stopZooming.bind(this));
        Event.observe($(zoomInEl), 'mouseout', this.stopZooming.bind(this));

        Event.observe($(zoomOutEl), 'mousedown', this.startZoomOut.bind(this));
        Event.observe($(zoomOutEl), 'mouseup', this.stopZooming.bind(this));
        Event.observe($(zoomOutEl), 'mouseout', this.stopZooming.bind(this));
    },

    toggleFull: function () {
        this.showFull = !this.showFull;
        //TODO: hide selects for IE only

        for (i=0; i<this.selects.length; i++) {
            this.selects[i].style.visibility = this.showFull ? 'hidden' : 'visible';
        }
        val_scale = !this.showFull ? this.slider.value : 1;
        this.scale(val_scale);

        this.trackEl.style.visibility = this.showFull ? 'hidden' : 'visible';
        this.containerEl.style.overflow = this.showFull ? 'visible' : 'hidden';
        this.containerEl.style.zIndex = this.showFull ? '1000' : '9';

        return this;
    },

    scale: function (v) {

        var centerX = (this.containerDim.width*(1-this.imageZoom)/2-this.imageX)/this.imageZoom;
        var centerY = (this.containerDim.height*(1-this.imageZoom)/2-this.imageY)/this.imageZoom;

        this.imageZoom = this.floorZoom+(v*(this.ceilingZoom-this.floorZoom));

        this.imageEl.style.width = (this.imageZoom*this.containerDim.width)+'px';
        if(this.containerDim.ratio){
          this.imageEl.style.height = (this.imageZoom*this.containerDim.width*this.containerDim.ratio)+'px'; // for safari
        }

        this.imageX = this.containerDim.width*(1-this.imageZoom)/2-centerX*this.imageZoom;
        this.imageY = this.containerDim.height*(1-this.imageZoom)/2-centerY*this.imageZoom;

        this.contain(this.imageX, this.imageY, this.draggable);

        return true;
    },

    startZoomIn: function()
    {
        this.zoomBtnPressed = true;
        this.sliderAccel = .002;
        this.periodicalZoom();
        this.zoomer = new PeriodicalExecuter(this.periodicalZoom.bind(this), .05);
        return this;
    },

    startZoomOut: function()
    {
        this.zoomBtnPressed = true;
        this.sliderAccel = -.002;
        this.periodicalZoom();
        this.zoomer = new PeriodicalExecuter(this.periodicalZoom.bind(this), .05);
        return this;
    },

    stopZooming: function()
    {
        if (!this.zoomer || this.sliderSpeed==0) {
            return;
        }
        this.zoomBtnPressed = false;
        this.sliderAccel = 0;
    },

    periodicalZoom: function()
    {
        if (!this.zoomer) {
            return this;
        }

        if (this.zoomBtnPressed) {
            this.sliderSpeed += this.sliderAccel;
        } else {
            this.sliderSpeed /= 1.5;
            if (Math.abs(this.sliderSpeed)<.001) {
                this.sliderSpeed = 0;
                this.zoomer.stop();
                this.zoomer = null;
            }
        }
        this.slider.value += this.sliderSpeed;

        this.slider.setValue(this.slider.value);
        this.scale(this.slider.value);

        return this;
    },

    contain: function (x,y,draggable) {

        var dim = Element.getDimensions(draggable.element);

        var xMin = 0, xMax = this.containerDim.width-dim.width;
        var yMin = 0, yMax = this.containerDim.height-dim.height;

        x = x>xMin ? xMin : x;
        x = x<xMax ? xMax : x;
        y = y>yMin ? yMin : y;
        y = y<yMax ? yMax : y;

        this.imageX = x;
        this.imageY = y;

        this.imageEl.style.left = this.imageX+'px';
        this.imageEl.style.top = this.imageY+'px';

        return [x,y];
    }
}

/**************************** CONFIGURABLE PRODUCT **************************/
Product.Config = Class.create();
Product.Config.prototype = {	
    initialize: function(config){		
        this.config     = config;
		this.initialConfig = config;
		this.tempConfig = config;
		var colorAttributeId = 76;
		var sizeAttributeId = 446;
		this.initialColour = "";
		this.productImages = [];
		
		colorSetting   = $('attributecolor' + colorAttributeId);	
		
        selectSettings   = $$('.super-attribute-select');
		
		// build a settings array that contains all the attributes and their options
		this.settings = [];
		this.settings.push(colorSetting);	
		
		for(var i=0;i< selectSettings.length;i++){	
			this.settings.push(selectSettings[i]);
		}	
		
        this.state      = new Hash();
        this.priceTemplate = new Template(this.config.template);
        this.prices     = config.prices;
		
        this.settings.each(function(element){
									
			
			var attributeId = element.id.replace(/[a-z]*/, '');		
			if (attributeId==colorAttributeId) {
            	//Event.observe(element, 'click', this.configureColor.bind(this))				
			} else {
				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 = [];
		
		
		
		// Init color setting dropdown
		this.fillColorSelect(this.settings[0]);
		
        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 (this.settings[i].tagName=='SELECT') {
            	//if (i> 0) alert(this.settings[i].selectedIndex);
				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]);
        }
		
		//element = $('coloroption115');
		//this.configureColorElement(element);
		if (this.config.colour !='') {
			this.selectFirstColor(this.settings[0],this.config.colour);
		} else {
			this.selectFirstColor(this.settings[0],this.config.attributes[this.colorAttributeId].options[0].id);	
		}
        // 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;
				if (attributeId==colorAttributeId) {
					element.value = this.values[attributeId];
                	this.configureColorElement(element);
				} else {
                	element.value = this.values[attributeId];
                	this.configureElement(element);
				}
            }.bind(this));
        }*/
    },

    configure: function(event){
        var element = Event.element(event);
        this.configureElement(element);
    },
	
	configureColor: function(event){
        var element = Event.element(event);
		this.configureColorElement(element);
    },
	
	configureColor2: function(element){
		this.configureColorElement(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 {
            this.resetChildren(element);
        }
        this.reloadPrice();
	},
	
	configureColorElement : function(element) {
		if (element.tagName=='IMG') {
			var colorOptionId = element.id.replace(/[a-z]*/, '');	
		} else {
			var colorOptionId = '';
		}
		colorSetting = this.settings[0];
		this.fillColorSelect(colorSetting,colorOptionId);
		attributeId = colorSetting.id.replace(/[a-z]*/, '');
		// assign the selected option to the color setting and give the focus to the next attribute settings 
		if(colorOptionId){	
			this.state[attributeId] = colorOptionId;
			if(colorSetting.nextSetting){						
				colorSetting.nextSetting.disabled = false;					
				this.fillSelect(colorSetting.nextSetting,colorOptionId);
				this.resetChildren(colorSetting.nextSetting);
				
				var thisImage = this.config.attributes[76].options[0].image_zoom;
				//CHANGE MAGIC ZOOM IMAGE
				$('magicZoomLink').href = thisImage;
			}
		}
		else {
			this.resetChildren(colorSetting);
		}	
    },
	
	reloadOptionColors: function(element,currentOptionId){ 
		attributeId = element.id.replace(/[a-z]*/, '');
		var options = this.getAttributeOptions(attributeId);
		
        for(var i=0;i<options.length;i++){
			if (options[i].id == currentOptionId) {
				$('coloroption' + options[i].id).className = $('coloroption' + options[i].id).className + ' current';
			}
        }
    },

    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){
				//Un.titled - Removed to stop dropdown from being rebuilt when an option is clicked as it's not necessary
				//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;
                }
            }
        }
    },

    fillSelect: function(element,colorOptionId){
		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){
			if (colorOptionId!='') {
				for (i=0;i<element.prevSetting.config.options.length;i++) {
					id = element.prevSetting.config.options[i].id;	
					if (id==colorOptionId) {
						colourProducts = element.prevSetting.config.options[i].products.clone();
						//ADDED BY DAN
						this.tempConfig.price = element.prevSetting.config.options[i].price;
						//ADDED BY DAN
						//this.config.basePrice = options[i].basePrice;
						//this.config.oldPrice = options[i].oldPrice;		
						//if(this.tempConfig.price != null) {
						this.reloadPrice();
						//}
						//////////
					}					
				}
			} else {
				prevConfig = element.prevSetting.options[element.prevSetting.selectedIndex];
			}            
        }
		
        if(options) {
            var index = 1;
            for(var i=0;i<options.length;i++){
				var allowedProducts = [];

				if (colorOptionId=='') {                	
					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){
								allowedProducts.push(options[i].products[j]);
							}
						}
					} else {
						allowedProducts = options[i].products.clone();
					}						
				} else {  
					for(var j=0;j<options[i].products.length;j++){
						if(colourProducts
							&& colourProducts.indexOf(options[i].products[j])>-1){
							allowedProducts.push(options[i].products[j]);
						}
					}	
				} 
				
				if(allowedProducts.size()>0){
					options[i].allowedProducts = allowedProducts;
					
					// Un.titled - Modified to allow product stock level to be shown in size dropdown
					element.options[index] = new Option(this.getOptionLabel(options[i], options[i].price)+" ("+this.config.products_qty[allowedProducts]+")", options[i].id);
					//element.options[index] = new Option(this.getOptionLabel(options[i], options[i].price), options[i].id);
					element.options[index].config = options[i];
					index++;
				}		
            }
        }
    },
	
	createImage: function(id, src,alt,className) {
		currentSwatchDimension = 51;
		
		if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
			var imageElement = document.createElement("<img id='"+id+"' onclick=\"spConfig.configureColor2(this);\" />");	
			imageElement.setAttribute("src",src);
			imageElement.setAttribute("alt",alt);
			//if (className!='') imageElement.setAttribute("class",className);
			
			// if current class, reduce the size of 2 pixels
			if (className=='current') {
				imageElement.setAttribute("width",currentSwatchDimension);
				imageElement.setAttribute("height",currentSwatchDimension);
			}
		} else {
			var imageElement = document.createElement("img");	
			imageElement.src = src;
			imageElement.id = id;
			imageElement.alt = alt;
			if (className!='') imageElement.addClassName(className);
			
			if (className=='current') {
				imageElement.width = currentSwatchDimension;
				imageElement.height = currentSwatchDimension;
			}
		}	
		return imageElement;
	},
	
	fillColorSelect: function(element,currentOptionId){
		
        var attributeId = element.id.replace(/[a-z]*/, '');
		var options = this.getAttributeOptions(attributeId);		
		
        if(options) {
            var index = 1;
			for(var i=0;i<options.length;i++){
				//var dlElement = document.createElement("dl");     
                if(options[i].products.size()>0){	
					optionElementId = 'coloroption' + options[i].id;
					if (options[i].id) {
						if (!currentOptionId) {
							currentOptionId = options[i].id;
							firstLoad = true;
						} 
						if ($(optionElementId)) element.removeChild($(optionElementId));
					}
					
					
					this.productImages[i] = new Image();
					this.productImages[i].src = options[i].product_image;
					
					//var ddElement = document.createElement("dd");	
					//dlElement.appendChild(ddElement);	
					if (currentOptionId == options[i].id) {						
						imageElement = this.createImage(optionElementId,options[i].image,options[i].label,'current');
						
						$('attribute'+attributeId).value = options[i].id;
						if ($('currentColor')) element.removeChild($('currentColor'));
						currentColor = document.createElement("span");	
						currentColor.id= 'currentColor';	
						//currentColor.innerHTML = this.getOptionLabel(options[i], options[i].price,true);
						currentColor.innerHTML = "";//this.getOptionLabel(options[i],'',true);
						$('selectedColour').update(this.getOptionLabel(options[i],'',true));
						$('colourDescription').update("is \""+options[i].description+"\"");
						
						
						if (this.productImages[i].src!='') 
							if($('image')) {
								$('image').src = this.productImages[i].src;
								
								//CHANGE MAGIC ZOOM IMAGE
								var thisImage = options[i].image_zoom;
								$$('div.MagicZoomBigImageCont > div > img').each(function(el) {
									if(thisImage != '') {
										el.src = thisImage;	
									}
								  });
							}
					} else {
						imageElement = this.createImage(optionElementId,options[i].image,options[i].label);	
					}
					
					//ddElement.appendChild(imageElement);
					
					//var ddElement = document.createElement("dd");	
					//ddElement.innerHTML = this.getOptionLabel(options[i], options[i].price,true);
					//dlElement.appendChild(ddElement);	
					//alert(imageElement);
					
					//POSSIBLE PROBLEM
					if (!(/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent))) {
						Event.observe(imageElement, 'click', this.configureColor.bind(this));
					}
					//
							
					element.appendChild(imageElement);
					index++;					
                }
				element.appendChild(currentColor);
				if (currentOptionId == options[i].id) {
					$(optionElementId).addClassName('current');
				}
				
            }			
	    }
    },
	
	selectFirstColor:function(element,selectedColourId) {
		var attributeId = element.id.replace(/[a-z]*/, '');
        var options = this.getAttributeOptions(attributeId);	
		if(options) {  
            for(var i=0;i<options.length;i++){				   
                if(options[i].products.size()>0){	
					optionElementId = 'coloroption' + options[i].id;
					if ((selectedColourId == '' && options[i].id) || (options[i].id == selectedColourId)) {					
						if ($(optionElementId)) {	
							this.configureColorElement($(optionElementId));
							this.tempConfig.price = options[i].price;
							//ADDED BY DAN
							//this.config.basePrice = options[i].basePrice;
							//this.config.oldPrice = options[i].oldPrice;		
							//if(this.tempConfig.price != null) {
								this.reloadPrice();
							//}
							//////////
							return true;
						}
					}			
				}
            }	
		}
	},

    getOptionLabel: function(option, price,split){
		
        var price = parseFloat(price);
        var str = option.label;
			
		if(price){
			if (split) str += '<br />';
            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(){
		//return false;
		var price = parseFloat(this.tempConfig.price);
		if(this.config.specialPrice != null) {
			price = parseFloat(this.config.specialPrice)+price;
			//alert("price1");
		} else {
			price = parseFloat(this.config.basePrice)+price;
			//alert("price2");
		}
		
		//alert("price: "+price);
		if(price != null) {
			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($('product-price-'+this.config.productId)){
				$('product-price-'+this.config.productId).innerHTML = price;
			}
			
			//ADDED TO REMOVE SPECIAL PRiCE IF NOT AVAILABLE
			if(!$('regular-price-'+this.config.productId)) {
				if(this.tempConfig.price > 0) {
					$('product-price-'+this.config.productId).ancestors()[0].hide();
					$('product-price-'+this.config.productId).ancestors()[0].previousSiblings()[0].className = 'regular-price';
				} else {
					$('product-price-'+this.config.productId).ancestors()[0].show();
					$('product-price-'+this.config.productId).ancestors()[0].previousSiblings()[0].className = 'old-price';
				}
			//alert(this.config.base);
			}
		}
		
        this.reloadOldPrice();
    },

    reloadOldPrice: function(){
		 var price = parseFloat(this.config.initialPrice);
		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)) {
            if($('old-price-'+this.config.productId)){
                $('old-price-'+this.config.productId).innerHTML = price;
	        }
			
        } else {
			if($('product-price-'+this.config.productId)) {
				$('product-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.productPrice       = config.productPrice;
        this.showIncludeTax     = config.showIncludeTax;
        this.showBothPrices     = config.showBothPrices;
        this.productPrice       = config.productPrice;
        this.productOldPrice    = config.productOldPrice;
        this.skipCalculate      = config.skipCalculate;
        this.duplicateIdSuffix  = config.idSuffix;

        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] = parseFloat(price);
    },

    getOptionPrices: function() {
        var result = 0;
        var nonTaxable = 0;
        $H(this.optionPrices).each(function(pair) {
            if (pair.key == 'nontaxable') {
                nonTaxable = pair.value;
            } else {
                result += pair.value;
            }
        });
        var r = new Array(result, nonTaxable);
        return r;
    },

    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')[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);
    }
}
