/**
 * Der Modulprogrammierer - Vinai Kopp, Rico Neitzel GbR
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the
 * Der Modulprogrammierer - COMMERCIAL SOFTWARE LICENSE (v1.0) (DMCSL 1.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.der-modulprogrammierer.de/licenses/dmcsl-1.0.html
 *
 *
 * @category   DerModPro
 * @package    DerModPro_BCP
 * @copyright  Copyright (c) 2010 Der Modulprogrammierer - Vinai Kopp, Rico Neitzel GbR
 * @license    http://www.der-modulprogrammierer.de/licenses/dmcsl-1.0.html (DMCSL 1.0)
 */

if(typeof BCP == 'undefined') {
	var BCP = {};
}

BCP.Config = Class.create(Product.Config, {
	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, '');

		/*
		 * Update allowed products for each option
		 */
		var allowedProducts = [];
		var prevOption = false;
		var product;
		var index = 1;
		if (element.prevSetting && element.prevSetting.selectedIndex > 0) {
			prevOption = element.prevSetting.options[element.prevSetting.selectedIndex].config;
		}
		for (var i = 0; i < options.length; i++) {
			if (! prevOption) allowedProducts = options[i].products.clone();
			else {
				allowedProducts = [];
				for (var j = 0; j < options[i].products.length; j++) {
					product = options[i].products[j];
					if (prevOption.allowedProducts.indexOf(product) != -1) allowedProducts.push(product);
				}
			}
			options[i].allowedProducts = allowedProducts.clone();
			if (allowedProducts.length > 0) {
				element.options[index] = new Option(this.getOptionLabel(options[i]), options[i].id);
				element.options[index].config = options[i];
				index++;
			}
		}
		if (element.nextSetting) {
			this.disableAllChildren(element.nextSetting);
		}
	},
	reloadAllOptionLabels: function() {
        this.settings.each(function(element) {
			this.reloadOptionLabels(element);
		}.bind(this));
	},
    reloadOptionLabels: function(element) {
		for (var i = 0; i < element.options.length; i++) {
			if (element.options[i].config) {
				element.options[i].text = this.getOptionLabel(element.options[i].config);
			}
		}
	},
	configureElement: function($super, element) {
		if (! this.config.bcp) return;
		
        if (element.value) {
            this.state[element.config.id] = element.value;
			element.nextSetting.disabled = false;
			if (element.nextSetting) {
				this.fillSelect(element.nextSetting);
			}
		} else {
			this.resetChildren(element);
		}

		/*
		 * Set the currently selected price
		 */
		if (element.selectedIndex > 0) {
			var price = this.getOptionPrice(element.options[element.selectedIndex].config);
			this.updatePrice(price);
		}

		/*
		 * If a specific product is selected, update the product view
		 */
		if (element.selectedIndex > 0) {
			if (element.options[element.selectedIndex].config.allowedProducts.length == 1) {
				this.updateProductView(element.options[element.selectedIndex].config.allowedProducts[0])
			}
		}
	},
	disableAllChildren: function(element) {
		element.selectedIndex = 0;
		element.disabled = true;
		if (element.nextSetting) {
			this.disableAllChildren(element.nextSetting);
		}
	},
	updatePrice: function(price) {
		if (price === false) return;
		
		if (this.getBcpCurrentPrice() == price) {
			return;
		}
		
		this.setBcpCurrentPrice(price);

		this.reloadAllOptionLabels();

		/*
		 * Use direct property access here so we don't need to rewrite the Product.OptionsPrice class
		 */
		optionsPrice.productPrice = price;
		optionsPrice.reload();
	},
	updateProductView: function(productId) {
		if (this.getBcpCurrentProduct() == productId) {
			return;
		}
		this.setBcpCurrentProduct(productId);

		if (this.disableAjax) return;

		if (
			this.config.bcp.updateSections.media ||
			this.config.bcp.updateSections.shortDesc ||
			this.config.bcp.updateSections.collateral
		) {

			this.showSpinner();

			var request = new Ajax.Request(
				this.config.bcp.updateProductUrl,
				{
					method: 'post',
					onFailure: this.ajaxFailure.bind(this),
					onSuccess: this.ajaxSuccess.bind(this),
					parameters: {
						id: productId,
						parent_id: this.config.bcp.cpId
					}
				}
			);
		}
	},
	ajaxFailure: function() {
		this.hideSpinner();
		alert('Error fetching product update!');
	},
	ajaxSuccess: function(transport) {
		this.hideSpinner();
		var response;
		if (transport && transport.responseText){
			try {
				response = eval('(' + transport.responseText + ')');
			}
			catch (e) {
				response = {};
			}
		}

		if (response.error){
			if ((typeof response.message) == 'string') {
				alert(response.message);
			} else {
				alert(response.message.join("\n"));
			}
			return false;
		}

		if (response.updates) {
			for (var i = 0; i < response.updates.length; i++) {
				if (response.updates[i].dom_selector && response.updates[i].html) {
					var elements = $$(response.updates[i].dom_selector);
					if (response.updates[i].prepare) try {
						eval(response.updates[i].prepare);
					} catch (e) {}
					if (elements) elements.each(function(element) {
						Element.replace(element, response.updates[i].html);
					}.bind(this));
					if (response.updates[i].callback) try {
						eval(response.updates[i].callback);
					} catch (e) {}
				}
			}
		}
	},
	showSpinner: function() {
		if ($('bcp-spinner') && this.config.bcp.showSpinner) $('bcp-spinner').show();
	},
	hideSpinner: function() {
		if ($('bcp-spinner') && this.config.bcp.showSpinner) $('bcp-spinner').hide();
	},
	getOptionLabel: function(option) {
		var tax;
		var excl;
		var incl;
		var price = this.getOptionPrice(option);

		if (price === false) {
			// no single price selected
			str = option.label;
			if (this.config.bcp && this.config.bcp.unknownPriceLabel) {
				str += ' ' + this.config.bcp.unknownPriceLabel;
			}
			return str;
		}

		// respect config option: hide option prices if they are the same as the currently visible product price
		if (this.config.bcp &&
			this.config.bcp.showOptionPriceIfSame == 0 &&
			price == this.getBcpCurrentPrice()) {
			return option.label;
		}
		price = parseFloat(price);
		
        if (this.taxConfig.includeTax) {
            tax = price / (100 + this.taxConfig.defaultTax) * this.taxConfig.defaultTax;
            excl = price - tax;
            incl = excl * (1+(this.taxConfig.currentTax/100));
        } else {
            tax = price * (this.taxConfig.currentTax / 100);
            excl = price;
            incl = excl + tax;
        }

        if (this.taxConfig.showIncludeTax || this.taxConfig.showBothPrices) {
            price = incl;
        } else {
            price = excl;
        }
		
		var prefix = this.config.bcp ? this.config.bcp.format.price.prefix : ' ';
		var sufix = this.config.bcp ? this.config.bcp.format.price.sufix : ' ';

        var str = option.label;
		
		if (this.taxConfig.showBothPrices) {
			str += ' ' + prefix + this.formatPrice(excl, true) + ' (' + this.formatPrice(price, true) + ' ' + this.taxConfig.inclTaxTitle + ')' + sufix;
		} else {
			str += ' ' + prefix + this.formatPrice(price, true) + sufix;
		}
        return str;
	},
	getOptionPrice: function(option) {
		var prices = this.getOptionPrices(option);
		if (prices.length == 1) return prices[0];
		return false;
	},
	getOptionPrices: function(option) {
		var products = [];
		var prices = [];
		var price;
		if (option.products && option.products.length == 1) products = option.products;
		else if (option.allowedProducts && option.allowedProducts) products = option.allowedProducts;
		else if (option.products) products = option.products;
		if (products.length) {
			for (var i = 0; i < products.length; i++) {
				price = this.getBcpProductPrice(products[i]);
				if (prices.indexOf(price)==-1) prices.push(price);
			}
		}
		return prices;
	},
	formatPrice: function($super, price, showSign) {
		price = $super(price, false); // force price to be absolute (no - r +)
		return price;
	},
	reloadPrice: function($super) {
		// price updates are handled differently with bcp
		return;
	},
	setBcpCurrentPrice: function(price) {
		this.config.bcp.currentPrice = price;
	},
	getBcpCurrentPrice: function() {
		var price = false;
		if (this.config.bcp) {
			if (this.config.bcp.currentPrice) price = this.config.bcp.currentPrice;
			else price = this.config.bcp.cpPrice;
		}
		return price;
	},
	getBcpProductPrice: function(productId) {
		if (this.config.bcp && this.config.bcp.spPrices[productId]) {
			return this.config.bcp.spPrices[productId]
		}
		return 0;
	},
	getBcpCurrentProduct: function() {
		if (this.config.bcp && this.config.bcp.currentProduct) {
			return this.config.bcp.currentProduct;
		}
		return 0;
	},
	setBcpCurrentProduct: function(productId) {
		this.config.bcp.currentProduct = productId;
		/*
		 * BasePricePro compatibility:
		 */
		if (typeof BasePrice!='undefined' && window.basePrice && window.basePrice.product) {
			window.basePrice.product.setCurrentProductId(productId)
		}
	},
	addBcpConfig: function(config) {
		this.config.bcp = config;
		if (this.config.bcp.spDefault) {
			this.setSimpleProduct(this.config.bcp.spDefault);
		}
		this.reloadAllOptionLabels();
	},
	setSimpleProduct: function(productId) {
		this.disableAjax = true;
		this.settings.each(function(element) {
			var attributeId = element.attributeId;
			var options = this.getAttributeOptions(attributeId);
			for (var i = 0; i < options.length; i++) {
				if (options[i].products.indexOf(productId) > -1) {
					element.value = options[i].id;
					this.configureElement(element);
					return;
				}
			}
		}.bind(this));
		this.disableAjax = false;
	}
});

/*
 * Overwrite the original Product.Config class
 */
Product.Config = BCP.Config;
