var Product = new Hash();

Product.Config = new Class({
	Implements: [Events,Options],
	options: {},
	initialize: function(productConfig){
		//console.log('PC: ',productConfig);
		/*
			SETUP THE ATTRIBUTE OBJECT
		*/
		this.productAttributes = new Hash(productConfig.attributes);
		this.basePrice = productConfig.basePrice;
		this.oldPrice = productConfig.oldPrice;
		this.productId = productConfig.productId;
		this.taxConfig = new Hash(productConfig.taxConfig);
		this.template = productConfig.template;				
		//this.initOptions(this.productAttributes);
		
		// from original Product proto class
		this.config     = productConfig;
		this.state      = new Hash();
		this.settings   = $$('.super-attribute-select');
		this.settings.each(function(element){
            element.addEvent('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]) {
            
            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.fillSelect(this.settings[i])
                
            //$(this.settings[i]).childSettings = childSettings.combine();
            $(this.settings[i]).childSettings = $A(childSettings);
            $(this.settings[i]).prevSetting   = prevSetting;
            $(this.settings[i]).nextSetting   = nextSetting;
            childSettings.push(this.settings[i]);
        }		
	},
	
    configure: function(event) {
        //var element = Event.element(event);
        var element = event.target;
        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();
    },
    
    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;
                }
            }
        }
    },  
    
    
    formatSelectbox: function(element) {
    	var el = $(element);
    	
	    el.addEvent('mouseenter', function(evt) {
	    	if (!el.retrieve('orgWidth')) {
	    		el.store('orgWidth', el.getStyle('width'));
	    		el.setStyle('width', 'auto');
	    	}
	    });
	    
	    
	    if (Browser.Engine.trident) {
		    el.addEvent('blur', function() {
		    	if (el.retrieve('orgWidth')) {
			    	el.setStyle('width', el.retrieve('orgWidth'));
			    	el.eliminate('orgWidth');
		    	}
		    });
	    } else {
	    	el.addEvent('mouseleave', function() {
	    		if (el.retrieve('orgWidth')) {
	    			el.setStyle('width', el.retrieve('orgWidth'));
	    			el.eliminate('orgWidth');
	    		}
	    	});
	    }
    },
    
    
    fillSelect: function(element) { 
    	this.formatSelectbox(element);
    	
    	
        var attributeId = element.id.replace(/[a-z]*/, '');
        var options = this.getAttributeOptions(attributeId);
        
       //console.log('options', options);
        
    	if(element.nodeName != 'DIV'){
	        this.clearSelect(element);
	        
	        //element.options[0] = new Element('option',{'text':this.config.chooseText,'value':''});
	        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 = [];
	                var allowedPrices = [];
	                
	                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]);
	                        	allowedPrices.push(this.getChildProductPrice(options[i].products[j]));
	                            //console.log('allowed Product: ', options[i].products[j]);
	                            //console.log('allowed Price: ', this.getChildProductPrice(options[i].products[j]));
	                        }
	                    }
	                } else {
	                    //allowedProducts = options[i].products.clone();
	                    allowedProducts = $A(options[i].products);
	                }
	                
	                //if(allowedProducts.size()>0){
	                if(allowedProducts.length > 0){
	                	options[i].allowedProducts = allowedProducts;
	                    options[i].allowedPrices = allowedPrices;
	
	   					/* breaking in IE
	                    element.options[index] = new Element('option',{
	                    	'text':this.getOptionLabel(options[i], options[i].price), 
	                    	'value':options[i].id 
	                    });
	                    */
	                    //console.log('OPT: ', options[i]);
	                    element.options[index] = new Option(this.getOptionLabel(options[i], null), options[i].id);
	                    
	                    element.options[index].config = options[i];
	                    index++;
	                }
	            }
	        }
    		
    	} else {
	        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();
	                    allowedProducts = $A(options[i].products);
	                }
	                if(allowedProducts.length > 0){
	                    options[i].allowedProducts = allowedProducts;

			    		// bla, do swatch here
						swatch = new Swatch({
							container : element,
							target	  : 'swatchValue',
							copy	  : this.getOptionLabel(options[i], options[i].price),
							value	  : options[i].id,
							text	  : this.getOptionLabel(options[i], options[i].price)
						})
						
						opt = swatch.element;
						if(index == 1){
							opt.addClass('active');
							$('swatchValue').set('value', options[i].id)	
						}
						opt.inject(element);
	   
			    		/*
	                    element.options[index] = new Element('option',{
	                    	'text':this.getOptionLabel(options[i], options[i].price), 
	                    	'value':options[i].id 
	                    });
						*/ 	
	                    //element.options[index].config = options[i];
	                    index++;
	                }
	            }
	        }
   		
    	}
    },    
    
    
    getOptionLabel: function(option, price){
    	//console.log('getOptionLabel; ', option);
    	
        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);
            }
        }
        
        //console.log(arguments);
        
        if (option.allowedPrices && option.allowedPrices.length) {
        	var dif = option.allowedPrices[0]-this.basePrice;
        	if (dif != 0) {
        		if (dif > 0) {
        			str += ' (+' + this.formatPrice(option.allowedPrices[0]-this.basePrice) + ')';
        		} else {
        			str += ' (-' + this.formatPrice(option.allowedPrices[0]-this.basePrice) + ')';
        		}
        	}
        }
        
        //console.log('getOptionLabel: ' + str);
        //console.log('getOptionLabel-Price: ' + price);
        return str;
    },

    formatPrice: function(num) {
		num = num.toString().replace(/\$|\,/g,'');
		
		if(isNaN(num)){
			num = "0";
		}
		
		var sign = (num == (num = Math.abs(num)));

		num = Math.floor(num*100+0.50000000001);
		var cents = num%100;
		num = Math.floor(num/100).toString();
		
		if(cents<10){
			cents = "0" + cents;
		}
		
		for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
			num = num.substring(0,num.length-(4*i+3))+','+
			
		num.substring(num.length-(4*i+3));
		
		return (((sign)?'':'-') + '$' + num + '.' + cents);
    },
        
    getChildProductPrice: function(pid) {
    	return this.config.childProducts[pid];
    },
    
	optionChanged : function(e){
		// NOTE: this is handled on change in site.js, checkVariationPrice function
		
		// NEED TO LOOP THROUGH ALL SELECTED ATTRIBUTES AND UPDATE THE PRICE DISPLAYED ON THE SITE
		// var newPrice = this.basePrice.toFloat() + e.target.getSelected().retrieve('option_price')[0].toFloat();
		// $(document.body).getElement('.price').set('text','$'+newPrice.format());
	},
	
	// NOTE: initOptions is dead
//	initOptions: function (attrs) {
//		
//		attrs.each(function(attribute){
//			this.selectBox = $('attribute'+attribute.id); // get the target select box
//			this.selectBox.addEvent('change',this.optionChanged.bindWithEvent(this));
//			
//			attribute.options.each(function(sel_option, index){ // loop through all of the attribute options and then create select box options out of them.
//				var priceOffset = "";
//				if(sel_option.price > 0){
//					 priceOffset = "+ $" + sel_option.price.toFloat().format();
//				}
//				else if(sel_option.price == 0){
//					
//				}
//				else{
//					priceOffset = sel_option.price;
//				}
//				// create radio inputs if needed here else do options //
//				
//				var opt = '';
//				var opt_label = '';
//				var swatch = '';
//				if(attribute.code == 'color'){
//					/*
//					swatch = new Swatch({
//				    	container : this.selectBox,
//				    	target	  : 'swatchValue',
//				    	copy	  : sel_option.label,
//				    	value	  : sel_option.id,
//						text	  : sel_option.label + " " + priceOffset
//					})
//					opt = swatch.element;
//					if(index == 0){
//						opt.addClass('active');
//						$('swatchValue').set('value', sel_option.id)	
//					}
//					*/
//					// opt = new Element('input',{
//					// 	'type'	: 'radio',
//					// 	'name'	: 'select_size',
//					// 	'value' : sel_option.id,
//					// 	'text'	: sel_option.label + " " + priceOffset
//					// });	
//					// opt_label = new Element('label',{
//					// 	'text'	: sel_option.label + " " + priceOffset
//					// });
//					opt = new Element('option',{
//						'value'	: sel_option.id,
//						'text' 	: sel_option.label + " " + priceOffset
//					});
//				}else if(attribute.code == 'shirt_size'){
//					opt = new Element('option',{
//						'value'	: sel_option.id,
//						'text' 	: 'z' + sel_option.label + " " + priceOffset,
//						'class'	: 'bozo'
//					});
//				}
//				
//				// need to be able to attach price object to be used when selection changes to update price
//				/*
//				opt.store('option_price',sel_option.price);
//				opt.store('option_products',sel_option.products);
//				*/
//				opt.inject(this.selectBox);
//				if(opt_label){
//					opt_label.inject(this.selectBox);
//				}
//				
//			}.bind(this));
//		}.bind(this));
//		
//	},
	
    clearSelect: function(element){
        for(var i=element.options.length-1;i>=0;i--){
            element.remove(i);
        }
    },	
    
    getAttributeOptions: function(attributeId){
        if(this.config.attributes[attributeId]){
        	//console.log('getAttributeOptions: ', this.config.attributes[attributeId].options);
            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);
            }
        }
        console.log(price);
		// console.log('OP-A: ',optionsPrice);
        optionsPrice.changePrice('config', price);
        optionsPrice.reload();

        return price;

        if($('product-price-'+this.config.productId)){
            $('product-price-'+this.config.productId).set('html',price);
        }
        this.reloadOldPrice();
    }
});
/**************************** OPTIONS ***************************************/


/**************************** SUPER PRODUCTS ********************************/
Product.Super = new Hash();
Product.Super.Configurable = new Class({
    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 = {
Product.OptionsPrice = new Class({
	initialize: function(config){
		//console.log('POP-A: ', 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];
        $$(this.containers).each(function(pair) {
            var _productPrice;
            //console.log('PP: ',  _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).getElements('.price')[0]) {
                    $(pair.value).getElements('.price')[0].innerHTML = formattedPrice;
                    if ($(pair.value+this.duplicateIdSuffix) && $(pair.value+this.duplicateIdSuffix).getElements('.price')[0]) {
                        $(pair.value+this.duplicateIdSuffix).getElements('.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);
    },
    
    
	reloadPriceLabels: function(productPriceIsKnown) {
		// console.log('POP-B: ', this)
	    var priceLabel = '';
	    if (!productPriceIsKnown) {
	        priceLabel = spConfig.config.priceFromLabel;
	    }
	
	    var priceSpanId = 'configurable-price-from-' + this.productId;
	    var duplicatePriceSpanId = priceSpanId + this.duplicateIdSuffix;
	
	    $(priceSpanId).getElements('span.configurable-price-from-label').each(function(label) {
	        label.set('html',priceLabel);
	    });
	
	    if ($(duplicatePriceSpanId) && $(duplicatePriceSpanId).getElements('span.configurable-price-from-label')) {
	        $(duplicatePriceSpanId).getElements('span.configurable-price-from-label').each(function(label) {
		        label.set('html',priceLabel);
	        });
	    }
	}
    
})




/* 
 * swatch class 
 */
Swatch = new Class({
	Implements: [Options],	
    options:{
    	// passed when creating new Countdown
    	container : null,
    	target	  : null,
    	copy	  : null,
    	value	  : null,
		text	  : null
    },
    initialize: function(options){
    	this.setOptions(options);
    	this.container	 	= $(this.options.container); 
    	this.target		 	= $(this.options.target); 
    	this.value		 	= this.options.value; 
    	this.copy			= '<img src="/resources/images/swatches/' + (this.options.copy.replace(' ','-')).replace('/','-') + '.jpg"/ alt="'+ this.options.copy +'"><em>' + this.options.copy  + '</em>';
		this.element		= this.init();
		return this;
	},
	init : function(){
		return new Element('span',{
			'id':'swatch-' + this.value,
			'html':this.copy,
			'class':'sel_swatch',
			'events':({
				// binding with even here passes event, and makes "this" in select the event, so no longer had access to this.options... etc
				'click': this.select.bind(this)
			})
		})
		
	},
	clear : function(){
		this.selections = this.container.getElements('span');
		this.selections.each(function(el){
			el.removeClass('active')
		})		
		this.element.addClass('active');
	},
	select : function(){
		this.target.set('value', this.value);
		this.clear();
	}
});
Swatch.implement(new Events, new Options); 


