/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-06-19 20:25:28 -0500 (Tue, 19 Jun 2007) $
 * $Rev: 2111 $
 *
 * Version 2.1
 */
(function($){$.fn.bgIframe=$.fn.bgiframe=function(s){if($.browser.msie&&parseInt($.browser.version)<=6){s=$.extend({top:'auto',left:'auto',width:'auto',height:'auto',opacity:true,src:'javascript:false;'},s||{});var prop=function(n){return n&&n.constructor==Number?n+'px':n;},html='<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+'style="display:block;position:absolute;z-index:-1;'+(s.opacity!==false?'filter:Alpha(Opacity=\'0\');':'')+'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+'"/>';return this.each(function(){if($('> iframe.bgiframe',this).length==0)this.insertBefore(document.createElement(html),this.firstChild);});}return this;};if(!$.browser.version)$.browser.version=navigator.userAgent.toLowerCase().match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)[1];})(jQuery);

/*
 * Superfish v1.4.8 - jQuery menu widget
 * Copyright (c) 2008 Joel Birch
 *
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * CHANGELOG: http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt
 */

;(function($){
 $.fn.superfish = function(op){

 var sf = $.fn.superfish,
 c = sf.c,
 $arrow = $(['<span class="',c.arrowClass,'"> &#187;</span>'].join('')),
 over = function(){
 var $$ = $(this), menu = getMenu($$);
 clearTimeout(menu.sfTimer);
 $$.showSuperfishUl().siblings().hideSuperfishUl();
 },
 out = function(){
 var $$ = $(this), menu = getMenu($$), o = sf.op;
 clearTimeout(menu.sfTimer);
 menu.sfTimer=setTimeout(function(){
 o.retainPath=($.inArray($$[0],o.$path)>-1);
 $$.hideSuperfishUl();
 if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}
 },o.delay); 
 },
 getMenu = function($menu){
 var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0];
 sf.op = sf.o[menu.serial];
 return menu;
 },
 addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); };
 
 return this.each(function() {
 var s = this.serial = sf.o.length;
 var o = $.extend({},sf.defaults,op);
 o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){
 $(this).addClass([o.hoverClass,c.bcClass].join(' '))
 .filter('li:has(ul)').removeClass(o.pathClass);
 });
 sf.o[s] = sf.op = o;
 
 $('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() {
 if (o.autoArrows) addArrow( $('>a:first-child',this) );
 })
 .not('.'+c.bcClass)
 .hideSuperfishUl();
 
 var $a = $('a',this);
 $a.each(function(i){
 var $li = $a.eq(i).parents('li');
 $a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);});
 });
 o.onInit.call(this);
 
 }).each(function() {
 menuClasses = [c.menuClass];
 if (sf.op.dropShadows && !($.browser.msie && $.browser.version < 7)) menuClasses.push(c.shadowClass);
 $(this).addClass(menuClasses.join(' '));
 });
 };

 var sf = $.fn.superfish;
 sf.o = [];
 sf.op = {};
 sf.IE7fix = function(){
 var o = sf.op;
 if ($.browser.msie && $.browser.version > 6 && o.dropShadows && o.animation.opacity!=undefined)
 this.toggleClass(sf.c.shadowClass+'-off');
 };
 sf.c = {
 bcClass : 'sf-breadcrumb',
 menuClass : 'sf-js-enabled',
 anchorClass : 'sf-with-ul',
 arrowClass : 'sf-sub-indicator',
 shadowClass : 'sf-shadow'
 };
 sf.defaults = {
 hoverClass : 'sfHover',
 pathClass : 'overideThisToUse',
 pathLevels : 1,
 delay : 800,
 animation : {opacity:'show'},
 speed : 'normal',
 autoArrows : true,
 dropShadows : true,
 disableHI : false, // true disables hoverIntent detection
 onInit : function(){}, // callback functions
 onBeforeShow: function(){},
 onShow : function(){},
 onHide : function(){}
 };
 $.fn.extend({
 hideSuperfishUl : function(){
 var o = sf.op,
 not = (o.retainPath===true) ? o.$path : '';
 o.retainPath = false;
 var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass)
 .find('>ul').hide().css('visibility','hidden');
 o.onHide.call($ul);
 return this;
 },
 showSuperfishUl : function(){
 var o = sf.op,
 sh = sf.c.shadowClass+'-off',
 $ul = this.addClass(o.hoverClass)
 .find('>ul:hidden').css('visibility','visible');
 sf.IE7fix.call($ul);
 o.onBeforeShow.call($ul);
 $ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); });
 return this;
 }
 });

})(jQuery);


/*
 * Supersubs v0.2b - jQuery plugin
 * Copyright (c) 2008 Joel Birch
 *
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 *
 * This plugin automatically adjusts submenu widths of suckerfish-style menus to that of
 * their longest list item children. If you use this, please expect bugs and report them
 * to the jQuery Google Group with the word 'Superfish' in the subject line.
 *
 */

;(function($){ // $ will refer to jQuery within this closure

 $.fn.supersubs = function(options){
 var opts = $.extend({}, $.fn.supersubs.defaults, options);
 // return original object to support chaining
 return this.each(function() {
 // cache selections
 var $$ = $(this);
 // support metadata
 var o = $.meta ? $.extend({}, opts, $$.data()) : opts;
 // get the font size of menu.
 // .css('fontSize') returns various results cross-browser, so measure an em dash instead
 var fontsize = $('<li id="menu-fontsize">&#8212;</li>').css({
 'padding' : 0,
 'position' : 'absolute',
 'top' : '-999em',
 'width' : 'auto'
 }).appendTo($$).width(); //clientWidth is faster, but was incorrect here
 // remove em dash
 $('#menu-fontsize').remove();
 // cache all ul elements
 $ULs = $$.find('ul');
 // loop through each ul in menu
 $ULs.each(function(i) { 
 // cache this ul
 var $ul = $ULs.eq(i);
 // get all (li) children of this ul
 var $LIs = $ul.children();
 // get all anchor grand-children
 var $As = $LIs.children('a');
 // force content to one line and save current float property
 var liFloat = $LIs.css('white-space','nowrap').css('float');
 // remove width restrictions and floats so elements remain vertically stacked
 var emWidth = $ul.add($LIs).add($As).css({
 'float' : 'none',
 'width' : 'auto'
 })
 // this ul will now be shrink-wrapped to longest li due to position:absolute
 // so save its width as ems. Clientwidth is 2 times faster than .width() - thanks Dan Switzer
 .end().end()[0].clientWidth / fontsize;
 // add more width to ensure lines don't turn over at certain sizes in various browsers
 emWidth += o.extraWidth;
 // restrict to at least minWidth and at most maxWidth
 if (emWidth > o.maxWidth) { emWidth = o.maxWidth; }
 else if (emWidth < o.minWidth) { emWidth = o.minWidth; }
 emWidth += 'em';
 // set ul to width in ems
 $ul.css('width',emWidth);
 // restore li floats to avoid IE bugs
 // set li width to full width of this ul
 // revert white-space to normal
 $LIs.css({
 'float' : liFloat,
 'width' : '100%',
 'white-space' : 'normal'
 })
 // update offset position of descendant ul to reflect new width of parent
 .each(function(){
 var $childUl = $('>ul',this);
 var offsetDirection = $childUl.css('left')!==undefined ? 'left' : 'right';
 $childUl.css(offsetDirection,emWidth);
 });
 });
 
 });
 };
 // expose defaults
 $.fn.supersubs.defaults = {
 minWidth : 9, // requires em unit.
 maxWidth : 25, // requires em unit.
 extraWidth : 0 // extra width can ensure lines don't sometimes turn over due to slight browser differences in how they round-off values
 };
 
})(jQuery); // plugin code ends

/**
 * 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.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]);
 }

 // 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));
 }
 },

 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 {
 this.resetChildren(element);
 }
 this.reloadPrice();
// Calculator.updatePrice();
 },

 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;
 }
 }
 }
 },

 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;
 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){
 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];
 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;
 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;
 }

 }
 }
}


/**************************** 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);
 }
}

