/******************************************************************************
* gshpPriceManager.js
*******************************************************************************
Gestionnaire de prix (et son complement)
*******************************************************************************
Fonctions de complement du manager complement :
- onChangeDimension 		Parametres : manager, select, product, dimensions
- onClickPackItem 		Parametres : manager, checkbox, product
- showReference			Parametres : manager, product, code

Fonctions de remplacement du manager complement :
- formatPrice 			Parametres : manager, price, priceType, showPriceType, showCounterValue
- formatDiscountedPrice 	Parametres : manager, price, priceType, showPriceType, showCounterValue

*******************************************************************************
*                                                                             *
* Copyright 2000-2002								                          *
*                                                                             *
******************************************************************************/

//
// ------------------------------------- Global functions
//
function gshpOnClickPackPlusMinus(evt)
{
	evt || (evt = window.event);
	var element = (document.all != null) ? window.event.srcElement : evt.currentTarget;
	if (element != null ) {
		var idData = element.id.split("_");
		if (idData.length >= 3) {
			var productOid 	= idData[2];
			var img 		= document.getElementById("packImg_plusMinus_" + productOid);
			var div			= document.getElementById("packDiv_dimensions_" + productOid);
			if ((img != null) && (div != null)) {
				var srcImg = img.src;
				if (img.src.indexOf("dynlib_plus.gif") != -1) {
					img.src = GshpPriceManager.prototype.MINUS_ICON
					div.style.display = "block";
				}
				else {
					img.src = GshpPriceManager.prototype.PLUS_ICON;
					div.style.display = "none";
				}
				return false;
			}
		}
	}
	return true;
}


//
// ------------------------------------- class GshpPriceManager
//
function GshpPriceManager()
{
	// Global init
	this._oComplement = null;

	this.addReferenceToBasketFormId = "basketReferenceForm";
	this.addPackToBasketFormId = "basketPackForm";

	this._vatCalculation = "vatPrice";
	this._defaultVatRate = 19.6;

	this._showPrices = true;
	this._currency = "€";
	this._vatDisplayMode = "vat";
	this._showPriceType = true;

	this._showCounterValue = false;
	this._counterValueCurrency = "FF";
	this._counterValueRate = 6.55957;

	this._activateStockRules = false;
	this._showWarningStockMsg_AllHiddenRef = false;
	this._warningStockMsgLabel_AllHiddenRef = "";
	this._stockRules = new Object();

	this._productMap = new Object();

	this._productUseMap = new Object();
	this._modeMap = new Object();

	// Initializing objects
	this._initPack 		= null;
	this._initProduct	= null;

	// Current objects
	this._currentPack 	= null;
	this._currentProduct= null;
}

//	=================== CONSTANTS
//
GshpPriceManager.prototype.CURRENTPRODUCT_MODE	= "currentProduct";
GshpPriceManager.prototype.PACK_MODE			= "pack";

GshpPriceManager.prototype.PLUS_ICON 			= "./iso_icons/dynlib_plus.gif";
GshpPriceManager.prototype.MINUS_ICON			= "./iso_icons/dynlib_minus.gif";
GshpPriceManager.prototype.EMPTY_ICON			= "./iso_icons/empty.gif";

//	-------------------------------------------------------------------------
//	Recovery of mode or product use
//	-------------------------------------------------------------------------
GshpPriceManager.prototype.getMode = function(productUse)
{
	return this._productUseMap[productUse];
}

GshpPriceManager.prototype.getProductUse = function(mode)
{
	return this._modeMap[mode];
}

//	-------------------------------------------------------------------------
//	Global init
//	-------------------------------------------------------------------------
GshpPriceManager.prototype.setAddReferenceToBasketFormId = function(addReferenceToBasketFormId)
{
	if (addReferenceToBasketFormId != "")
		this.addReferenceToBasketFormId = addReferenceToBasketFormId;
}

GshpPriceManager.prototype.setAddPackToBasketFormId = function(addPackToBasketFormId)
{
	if (addPackToBasketFormId != "")
		this.addPackToBasketFormId = addPackToBasketFormId;
}

GshpPriceManager.prototype.setVatParameters = function(vatCalculation, defaultVatRate)
{
	this._vatCalculation = vatCalculation;
	this._defaultVatRate = defaultVatRate;
}

GshpPriceManager.prototype.setPriceParameters = function(showPrices, currency, vatDisplayMode, showPriceType)
{
	this._showPrices = showPrices;
	this._currency = currency;
	this._vatDisplayMode = vatDisplayMode;
	this._showPriceType = showPriceType;

	var priceRow = document.getElementById("referencePriceRow");
	if (priceRow != null) {
		if (showPrices) {
			priceRow.style.display = document.all ? "block":"table-row";
		} else {
			priceRow.style.display = "none";
		}
	}
}

GshpPriceManager.prototype.setCounterValueParameters = function(showCounterValue, counterValueCurrency, counterValueRate)
{
	this._showCounterValue = showCounterValue;
	this._counterValueCurrency = counterValueCurrency;
	this._counterValueRate = counterValueRate;
}

GshpPriceManager.prototype.setStockRules = function(showWarningStockMsg_AllHiddenRef, warningStockMsgLabel_AllHiddenRef,
													actionOnRef_AS_NC, showWarningStockMsg_AS_NC, warningStockMsgLabel_AS_NC,
													actionOnRef_GS_R, showWarningStockMsg_GS_R, warningStockMsgLabel_GS_R,
													actionOnRef_GS_NR, showWarningStockMsg_GS_NR, warningStockMsgLabel_GS_NR,
													actionOnRef_WS_R, showWarningStockMsg_WS_R, warningStockMsgLabel_WS_R,
													actionOnRef_WS_NR, showWarningStockMsg_WS_NR, warningStockMsgLabel_WS_NR,
													actionOnRef_CS_R, showWarningStockMsg_CS_R, warningStockMsgLabel_CS_R,
													actionOnRef_CS_NR, showWarningStockMsg_CS_NR, warningStockMsgLabel_CS_NR )
{
	this._activateStockRules = true;

	// All hidden
	this._showWarningStockMsg_AllHiddenRef 	= showWarningStockMsg_AllHiddenRef;
	this._warningStockMsgLabel_AllHiddenRef	= warningStockMsgLabel_AllHiddenRef;

	// Used codes by rules :
	// - AS (Any stock), GS (Good stock), WS (Warning stock) and CS (Critical stock)
	// - NC (Not commandable)
	// - R (reorderable) and NR (Not reorderable)
	this._stockRules = new Object();
	this._stockRules["AS_NC"]	= new GshpStockRule("AS_NC", actionOnRef_AS_NC, showWarningStockMsg_GS_R, warningStockMsgLabel_AS_NC);
	this._stockRules["GS_R"]	= new GshpStockRule("GS_R", actionOnRef_GS_R, showWarningStockMsg_GS_R, warningStockMsgLabel_GS_R);
	this._stockRules["GS_NR"]	= new GshpStockRule("GS_NR", actionOnRef_GS_NR, showWarningStockMsg_GS_NR, warningStockMsgLabel_GS_NR);
	this._stockRules["WS_R"]	= new GshpStockRule("WS_R", actionOnRef_WS_R, showWarningStockMsg_WS_R, warningStockMsgLabel_WS_R);
	this._stockRules["WS_NR"]	= new GshpStockRule("WS_NR", actionOnRef_WS_NR, showWarningStockMsg_WS_NR, warningStockMsgLabel_WS_NR);
	this._stockRules["CS_R"]	= new GshpStockRule("CS_R", actionOnRef_CS_R, showWarningStockMsg_CS_R, warningStockMsgLabel_CS_R);
	this._stockRules["CS_NR"]	= new GshpStockRule("CS_NR", actionOnRef_CS_NR, showWarningStockMsg_CS_NR, warningStockMsgLabel_CS_NR);
}

GshpPriceManager.prototype.setProductUseForCurrentProductMode = function(productUse)
{
	var mode 						= GshpPriceManager.prototype.CURRENTPRODUCT_MODE;
	this._productUseMap[productUse] = mode;
	this._modeMap[mode] 			= productUse;
}

GshpPriceManager.prototype.setProductUseForPackMode = function(productUse)
{
	var mode 						= GshpPriceManager.prototype.PACK_MODE;
	this._productUseMap[productUse] = mode;
	this._modeMap[mode] 			= productUse;
}

//	-------------------------------------------------------------------------
//	Pack init
//	-------------------------------------------------------------------------
GshpPriceManager.prototype.startInitPack = function(oid)
{
	this._initPack = new GshpPack(oid);

	// Current product
	this._currentPack = this._initPack;
}

GshpPriceManager.prototype.setPackLabel = function(label)
{
	if (this._initPack == null)	return;

	this._initPack.label = label;
}

GshpPriceManager.prototype.setPackPromoModel = function(promoOid, promoDescription)
{
	if (this._initPack == null)	return;

	this._initPack.setPromoModel(promoOid, promoDescription);
}

//	-------------------------------------------------------------------------
//	Product init
//	-------------------------------------------------------------------------
GshpPriceManager.prototype.startInitProduct = function(productUse, oid)
{
	var productMode = this.getMode(productUse);
	this._initProduct = new GshpProduct(productMode, productUse, oid);

	// Map to find product from input id
	this._productMap[oid + "_" + productUse] = this._initProduct;

	// Current product
	if (productMode == GshpPriceManager.prototype.CURRENTPRODUCT_MODE)
		this._currentProduct = this._initProduct;
	else
	if ((productMode == GshpPriceManager.prototype.PACK_MODE) && (this._initPack != null))
		this._initPack.addProduct(this._initProduct);
}

GshpPriceManager.prototype.setProductLabel = function(label)
{
	if (this._initProduct == null) return;

	this._initProduct.label = label;
}

GshpPriceManager.prototype.setIsCurrentProduct = function(isCurrentProduct)
{
	if (this._initProduct == null) return;

	this._initProduct.isCurrentProduct = isCurrentProduct;
}

GshpPriceManager.prototype.setOpenDimension = function(useOpenDimension, openDimensionLabel)
{
	if (this._initProduct == null) return;

	this._initProduct.useOpenDimension	= useOpenDimension;
	this._initProduct.openDimensionLabel= openDimensionLabel;
}

GshpPriceManager.prototype.setOpenCategories = function(openCategory1, openCategory2, openCategory3, openCategory4, openCategory5)
{
	if (this._initProduct == null) return;

	this._initProduct.openCategories[0] = openCategory1;
	this._initProduct.openCategories[1] = openCategory2;
	this._initProduct.openCategories[2] = openCategory3;
	this._initProduct.openCategories[3] = openCategory4;
	this._initProduct.openCategories[4] = openCategory5;
}

GshpPriceManager.prototype.addPrices = function(list)
{
	if (this._initProduct == null) return;

	for (var i=0; i<list.length; i++) {
		var record = list[i].split("|");
		var code = record[0];
		this._initProduct.setReferenceRecord(code, record);
	}
}

GshpPriceManager.prototype.addModel = function(rank, label)
{
	if (this._initProduct == null) return;

	this._initProduct.dimensionLabels[rank-1] = label
}

//	-------------------------------------------------------------------------
//	Rounded calculation of price, vat price or vat rate
//	-------------------------------------------------------------------------
GshpPriceManager.prototype.calculatePrice = function(vatPrice, vatRate)
{
	return this.roundPrice(vatPrice / (1 + 0.01 * vatRate));
}
GshpPriceManager.prototype.calculateVatPrice = function(price, vatRate)
{
	return this.roundPrice(price * (1 + 0.01 * vatRate));
}
GshpPriceManager.prototype.calculateVatRate = function(price, vatPrice)
{
	return this.roundRate(100 * ((vatPrice / price) - 1));
}

//	-------------------------------------------------------------------------
//	Rounding of price or rate
//	-------------------------------------------------------------------------
GshpPriceManager.prototype.roundPrice = function(price)
{
	return (Math.round(price * 100) / 100);
}
GshpPriceManager.prototype.roundRate = function(rate)
{
	return (Math.round(rate * 10) / 10);
}

//	-------------------------------------------------------------------------
//	Computing/Validating/Formating of price
//	-------------------------------------------------------------------------
GshpPriceManager.prototype.computePrice = function(record)
{
	var basePrice = parseFloat(record[3]);
	if (isNaN(basePrice)) basePrice = 0;
	var baseVatPrice = parseFloat(record[4]);
	if (isNaN(baseVatPrice)) baseVatPrice = 0;

	var vatRate = parseFloat(record[5]);
	if (isNaN(vatRate) || (vatRate == 0)) vatRate = this._defaultVatRate;

	var discountedPrice = parseFloat(record[18]);
	if (isNaN(discountedPrice)) discountedPrice = 0;
	var discountedVatPrice = parseFloat(record[19]);
	if (isNaN(discountedVatPrice)) discountedVatPrice = 0;

	var clientDiscountPercentage = parseFloat(record[25]);
	if (isNaN(clientDiscountPercentage)) clientDiscountPercentage = 0;
	var applyClientDiscountPercentageOnDiscountedPrice = (record[26] == 'true');

	// Base prices
	var oPrice = this.validatePrice(basePrice, baseVatPrice, vatRate, true);
	basePrice 	= oPrice.price;
	baseVatPrice= oPrice.vatPrice;
	vatRate		= oPrice.vatRate;

	// Discounted prices
	if ((discountedPrice != 0) || (discountedVatPrice != 0)) {
		if (applyClientDiscountPercentageOnDiscountedPrice == false) clientDiscountPercentage = 0.0;

		var oPrice = this.validatePrice(discountedPrice, discountedVatPrice, vatRate, false);
		discountedPrice 	= oPrice.price;
		discountedVatPrice	= oPrice.vatPrice;
		return new Array(basePrice, baseVatPrice, vatRate, discountedPrice, discountedVatPrice, clientDiscountPercentage);
	}
	return new Array(basePrice, baseVatPrice, vatRate, basePrice, baseVatPrice, clientDiscountPercentage);
}

GshpPriceManager.prototype.validatePrice = function(price, vatPrice, vatRate, canModifyVatRate)
{
	var oPrice = new Object();
	oPrice.price	= price;
	oPrice.vatPrice	= vatPrice;
	oPrice.vatRate	= vatRate;

	if (this._vatCalculation == "price") {
		if (canModifyVatRate)	oPrice.vatRate = this.roundRate(vatRate);
		oPrice.vatPrice = this.roundPrice(vatPrice);
		oPrice.price	= this.calculatePrice(oPrice.vatPrice, oPrice.vatRate);
	}
	else
	if (this._vatCalculation == "vatPrice") {
		if (canModifyVatRate)	oPrice.vatRate = this.roundRate(vatRate);
		oPrice.price = this.roundPrice(price);
		oPrice.vatPrice = this.calculateVatPrice(oPrice.price, oPrice.vatRate);
	}
	else
	if ((this._vatCalculation == "vat") && (price != 0) && (canModifyVatRate == true)) {
		oPrice.price	= this.roundPrice(price);
		oPrice.vatPrice = this.roundPrice(vatPrice);
		oPrice.vatRate	= this.calculateVatRate(oPrice.price, oPrice.vatPrice);
	}
	return oPrice;
}

GshpPriceManager.prototype.formatProductPrice = function(product, code)
{
	var record = product.getReferenceRecord(code);
	if (record == null) return "pas de prix disponible";

	var computedPrice = this.computePrice(record);
	var basePrice 	= computedPrice[0];
	var baseVatPrice= computedPrice[1];
	var vatRate 	= computedPrice[2];
	var price 		= computedPrice[3];
	var vatPrice 	= computedPrice[4];
	var clientDiscountPercentage = computedPrice[5];

	// Client percentage discount
	if (clientDiscountPercentage > 0) {
		price 	= this.roundPrice(price - (price * clientDiscountPercentage / 100.0));
		vatPrice= this.calculateVatPrice(price, vatRate);
	}

	// Display of prices
	var vatDisplayMode	= this._vatDisplayMode;
	var showPriceType	= this._showPriceType;
	var showCounterValue= (product.mode == GshpPriceManager.prototype.PACK_MODE) ? false : this._showCounterValue;
	if (price != basePrice) {
		return this.formatDiscountedPriceAccordingToVatDisplayMode(basePrice, baseVatPrice, price, vatPrice, vatDisplayMode, showPriceType, showCounterValue);
	} else {
		return this.formatPriceAccordingToVatDisplayMode(basePrice, baseVatPrice, vatDisplayMode, showPriceType, showCounterValue);
	}
}

GshpPriceManager.prototype.formatPriceAccordingToVatDisplayMode = function(price, vatPrice, vatDisplayMode, showPriceType, showCounterValue)
{
	switch (vatDisplayMode) {
		case "vatFree":
			return this.formatPrice(price, " HT", showPriceType, showCounterValue);
		case "vat":
			return this.formatPrice(vatPrice, " TTC", showPriceType, showCounterValue);
		default:
			return this.formatPrice(price, " HT", showPriceType, showCounterValue) + "<span class='gshpSeparatorPrices'> - </span>" + this.formatPrice(vatPrice, " TTC", showPriceType, showCounterValue);
	}
}

GshpPriceManager.prototype.formatDiscountedPriceAccordingToVatDisplayMode = function(basePrice, baseVatPrice, price, vatPrice, vatDisplayMode, showPriceType, showCounterValue)
{
	switch (vatDisplayMode) {
		case "vatFree":
			return this.formatDiscountedPrice(basePrice, price, " HT", showPriceType, showCounterValue);
		case "vat":
			return this.formatDiscountedPrice(baseVatPrice, vatPrice, " TTC", showPriceType, showCounterValue);
		default:
			return this.formatDiscountedPrice(basePrice, price, " HT", showPriceType, showCounterValue) + "<span class='gshpSeparatorPrices'> - </span>" + this.formatDiscountedPrice(baseVatPrice, vatPrice, " TTC", showPriceType, showCounterValue);
	}
}

GshpPriceManager.prototype.formatPrice = function(price, priceType, showPriceType, showCounterValue)
{
	// Manager complement
	if ((this._oComplement != null) && (typeof(this._oComplement.formatPrice) == "function"))
		return this._oComplement.formatPrice(this, price, priceType, showPriceType, showCounterValue);

	// Default treatment
	if (priceType == null) priceType = "";

	var str = this.formatPriceValue(price, this._currency);
	if (showPriceType == true) str += priceType;
	if (showCounterValue  == true) {
		var counterPrice = price * this._counterValueRate;
		str += " <span class='gshpCounterValue'>(" + this.formatPriceValue(counterPrice, this._counterValueCurrency);
		if (showPriceType == true) str += priceType;
		str += ")</span>";
	}
	return str;
}

GshpPriceManager.prototype.formatDiscountedPrice = function(price, discountedPrice, priceType, showPriceType, showCounterValue)
{
	// Manager complement
	if ((this._oComplement != null) && (typeof(this._oComplement.formatDiscountedPrice) == "function"))
		return this._oComplement.formatDiscountedPrice(this, price, discountedPrice, priceType, showPriceType, showCounterValue);

	// Default treatment
	if (priceType == null) priceType = "";

	var str = "<span class='gshpDiscountedPriceContainer'>";
	str += "<span class='gshpDashedPrice'>";
	str += this.formatPriceValue(price, this._currency);
	if (showPriceType == true) str += priceType;
	str += "</span>";

	str += "<span class='gshpSeparatorDashedDiscountedPrices'>&#160;</span>";

	str += "<span class='gshpDiscountedPrice'>";
	str += this.formatPriceValue(discountedPrice, this._currency);
	if (showPriceType == true) str += priceType;
	if (showCounterValue == true) {
		var counterPrice = discountedPrice * this._counterValueRate;
		str += " <span class='gshpCounterValue'>(" + this.formatPriceValue(counterPrice, this._counterValueCurrency);
		if (showPriceType == true) str += priceType;
		str += ")</span>";
	}
	str += "</span>";
	str += "</span>";
	return str;
}

GshpPriceManager.prototype.formatPriceValue = function(money, unit)
{
	money = parseFloat(money);
	if (isNaN(money)) return "&nbsp;";
	var sign ="";
	if (money < 0) {
		money = -money;
		sign = "-";
	}
	var integer = Math.floor(money);
	var full = "" + integer;
	// NB : A cause des arrondis, on utilise round au lieu de floor et on ne va pas factoriser l'expression mathematique en ecrivant : 100 * (money - integer)
	// Cas à problème : 583.05 | 152.89
	var decimal = "" + Math.round((100 * money) - (100 * integer));
	if (decimal.length == 1) decimal = "0"+decimal;
	var res = null;
	var pos = full.length;
	while (pos > 3) {
		block = full.substr(pos - 3, 3);
		if (res == null) {
			res = block;
		} else {
			res = block + " "+res;
		}
		pos -= 3;
	}
	if (pos > 0) {
		block = full.substr(0, pos);
		if (res == null) {
			res = block;
		} else {
			res = block+" "+res;
		}
	}
	if (unit == "&#8364;") unit = String.fromCharCode(8364);
	if (unit == "£") {
		res = unit + "\240" + sign + res + "." + decimal;
	} else {
		res = sign + res + "," + decimal + "\240" + unit;
	}
	return res;
}

//	-------------------------------------------------------------------------
//	Display of prices
//	-------------------------------------------------------------------------
GshpPriceManager.prototype.showCurrentProductPrices = function()
{
	if (this._currentProduct == null) return;

	// Analysis and display
	this._studyReferences(this._currentProduct);
	this._showProductPrices(this._currentProduct);
}

GshpPriceManager.prototype.showPackPrices = function()
{
	if (this._currentPack == null) return;

	// Analysis of pack items
	var managePlusMinus = false;
	var productList = this._currentPack.productList;
	for (var ind=0; ind<productList.length; ind++) {
		var product = productList[ind];

		// Analysis
		this._studyReferences(product);

		// Recovery of existence flag of current product in pack
		if (product.isCurrentProduct == true)
			this._currentPack.hasCurrentProduct = true;

		// Recovery of maximun count of commandable reference to know if you manage plus/minus link
		if ((product.nbReference - product.nbNotCommandableReference) > 1)
			this._currentPack.managePlusMinus = true;
	}

	// Display
	for (var ind=0; ind<productList.length; ind++) {
		var product = productList[ind];
		this._showProductPrices(product);
	}

	// Update of prices
	this._updatePackPrice();
}

//	-------------------------------------------------------------------------
//	Management of events
//	-------------------------------------------------------------------------
GshpPriceManager.prototype.onChangeDimension = function(select)
{
	var idData = select.id.split("_");
	if (idData.length < 4) return;
	var productKey 	= idData[1] + "_" + idData[2];	// oid  and use
	var n 			= parseInt(idData[3], 10) -1;
	var product 	= this._productMap[productKey];
	if (product == null) return;

	var dimensions = new Array();
	for (var i=0; i<=n; i++) {
		var dimensionCodes = product.dimensionCodes[i];
		if (dimensionCodes == null) continue;
		var referenceDimensionSelect = document.getElementById("referenceDimensionSelect_" + product.oid + "_" + product.use + "_" + (i+1));
		dimensions[i] = referenceDimensionSelect.value;
	}
	for (var i=n+1; i<5; i++) {
		var dimensionCodes = product.dimensionCodes[i];
		if (dimensionCodes == null) continue;
		this._fillOptions(product, i, dimensions);
		return;
	}
	this._selectReference(product, dimensions);

	// Update of pack price (with discount percentage for each pack item)
	if (product.isSelectedPackItem() == true)
		this._updatePackPrice();

	// Manager complement
	if ((this._oComplement != null) && (typeof(this._oComplement.onChangeDimension) == "function"))
		this._oComplement.onChangeDimension(this, select, product, dimensions);
}

GshpPriceManager.prototype.onClickPackItem = function(checkbox)
{
	var idData = checkbox.id.split("_");
	if (idData.length < 3) return;
	var productKey 	= idData[2] + "_" + this.getProductUse(GshpPriceManager.prototype.PACK_MODE);	// oid  and use
	var product 	= this._productMap[productKey];
	if (product == null) return;

	product.isCheckedPackItem = checkbox.checked;

	// Update of pack price (with discount percentage for each pack item)
	this._updatePackPrice();

	// Manager complement
	if ((this._oComplement != null) && (typeof(this._oComplement.onClickPackItem) == "function"))
		this._oComplement.onClickPackItem(this, checkbox, product);
}

GshpPriceManager.prototype.onCustomizePackItem = function(link)
{
	var idData = link.id.split("_");
	if (idData.length < 3) return;
	var productKey 	= idData[2] + "_" + this.getProductUse(GshpPriceManager.prototype.PACK_MODE);	// oid  and use
	var product 	= this._productMap[productKey];
	if (product == null) return;

	// Manager complement
	if ((this._oComplement != null) && (typeof(this._oComplement.onClickPackItem) == "function"))
		this._oComplement.onCustomizePackItem(this, product);
}

//	-------------------------------------------------------------------------
//	Display of reference data (prices, code, warning message, add button, ...)
//	-------------------------------------------------------------------------
GshpPriceManager.prototype.showReference = function(product, code)
{
	var record 			= product.getReferenceRecord(code);
	var stockRule 		= product.getReferenceStockRule(code);
	var notCommandable	= product.getReferenceNotCommandable(code);

	// Data (price and code)
	if (product.mode == GshpPriceManager.prototype.CURRENTPRODUCT_MODE) {
		var ref = record[1];
		var publicRef = record[2];	
		var stock = parseInt(record[20], 10);
	
		// Price
		var refPriceValueElt = document.getElementById("referencePriceValue");
		if (refPriceValueElt != null) refPriceValueElt.innerHTML = this.formatProductPrice(product, code);

		// Stock
		var refStockElt = document.getElementById("referenceStock");
		if (refStockElt != null) refStockElt.innerHTML = (stock < 0) ? 0 : stock;

		// Codes
		var refCodeElt = document.getElementById("referenceCode");
		if (refCodeElt != null) refCodeElt.innerHTML = ref;

		var refPublicCodeElt = document.getElementById("referencePublicCode");
		if (refPublicCodeElt != null) refPublicCodeElt.innerHTML = publicRef;
	}
	else
	if (product.mode == GshpPriceManager.prototype.PACK_MODE) {
		// Price
		var refPriceValueElt = document.getElementById("packReferencePriceValue_" + product.oid);
		if (refPriceValueElt != null) refPriceValueElt.innerHTML = this.formatProductPrice(product, code);
	}

	// Stock message
	if (this._activateStockRules && stockRule) {
		// Warning message is necessary only for "current product" mode if :
		// - All references are hidden 			WarningStockMsg_AllHiddenRef
		// - According to stock rule			WarningStockMsg_??
		if (product.mode == GshpPriceManager.prototype.CURRENTPRODUCT_MODE) {
			if (product.allRefAreHidden == true) {
				if (this._showWarningStockMsg_AllHiddenRef == true) {
					var warningStockMsgId_AllHiddenRef = document.getElementById("warningStockMsg_AllHiddenRef");
					if (warningStockMsgId_AllHiddenRef != null) {
						warningStockMsgId_AllHiddenRef.style.display = "block";
						warningStockMsgId_AllHiddenRef.innerHTML = this._warningStockMsgLabel_AllHiddenRef;
					}
				}
			}
			else {
				// AnyStock not commandable, GoodStock, WarningStock and CriticalStock
				var stockRuleTypes = new Array("AS_NC", "GS_R", "GS_NR", "WS_R", "WS_NR", "CS_R", "CS_NR");
				for (var ind=0; ind<stockRuleTypes.length; ind++) {
					var stockRuleType 	= stockRuleTypes[ind];
					var elementId 		= "warningStockMsg_" + stockRuleType;
					var warningStockMsgId = document.getElementById(elementId);
					if (warningStockMsgId != null) 	{
						// Element is hidden if it's not the current stock rule or if message is empty
						var displayMsg = ((stockRule.getType() == stockRuleType) && stockRule.haveWarningMsg());
						warningStockMsgId.style.display = displayMsg ? "block" : "none";
						warningStockMsgId.innerHTML 	= displayMsg ? stockRule.getWarningMsg() : "";
					}
				}
			}
		}

		// Button to add reference into basket
		if (product.mode == GshpPriceManager.prototype.CURRENTPRODUCT_MODE) {
			// According to some conditions, we can not command the reference
			notCommandable = (notCommandable || stockRule.cannotCommandReference());

			// Adding to basket
			addToBasketId = document.getElementById("addToBasket");
			if (addToBasketId != null)
				addToBasketId.style.display = (notCommandable ? "none" : "block" );
		}
	}

	// Manager complement
	if ((this._oComplement != null) && (typeof(this._oComplement.showReference) == "function"))
		this._oComplement.showReference(this, product, code);
}

//	-------------------------------------------------------------------------
//	Private functions
//	-------------------------------------------------------------------------
GshpPriceManager.prototype._showProductPrices = function(product)
{
	if ((product == null) || (product.studied == false)) return;

	// Pack mode
	if (product.mode == GshpPriceManager.prototype.PACK_MODE) {
		// Dimensions are not visible for moment
		var packDiv = document.getElementById("packDiv_dimensions_" + product.oid);
		if (packDiv  != null) {
			packDiv.style.display = "none";
		}

		// If all references are not commandable, we can not see product or pack if product is the current product in card
		if (product.allRefAreNotCommandable	== true) {
			if (product.isCurrentProduct == true) {
				if (this._currentPack != null)
					this._currentPack.isHidden = true;

				var divPack = document.getElementById("divPack");
				if (divPack != null) {
					divPack.style.display = "none";
				}
			}
			else {
				var packRow = document.getElementById("packRow_data_" + product.oid);
				if (packRow != null) {
					packRow.style.display = "none";
				}
			}
		}
		// Mamangement of plusMinus div
		else {
			this._buildPackDivPlusMinus(product);
		}
	}

	// Selects of dimension
	var first = true;
	for (var i=0; i<5; i++) {
		var dimensionCodes = product.dimensionCodes[i];
		if (dimensionCodes == null) {
			var referenceDimensionRow = document.getElementById("referenceDimensionRow_" + product.oid + "_" + product.use + "_" + (i+1));
			if (referenceDimensionRow != null) {
				referenceDimensionRow.style.display = "none";
			}
		}
		if (!first) continue;
		first = false;
		var referenceDimensionSelect = document.getElementById("referenceDimensionSelect_" + product.oid + "_" + product.use + "_" + (i+1));
		if (referenceDimensionSelect == null) {
			this._selectReference(product, new Array());
			break;
		}
		for (var oid in dimensionCodes) {
			var label = dimensionCodes[oid];
			var option = document.createElement("OPTION");
			option.text = label;
			option.value = oid;
			referenceDimensionSelect.options.add(option);
		}
		referenceDimensionSelect.selectedIndex = 0;
		this.onChangeDimension(referenceDimensionSelect);
	}
}

GshpPriceManager.prototype._studyReferences = function(product)
{
	// Init of dimensions
	product.studied 		= true;
	product.dimensionCodes	= new Array();
	product.referenceByDim	= new Object();

	var nbReference = 0;
	var nbNotCommandableReference = 0;
	var nbHiddenReference = 0;
	for (var code in product.references) {
		nbReference++;
		var record = product.getReferenceRecord(code);
		if (this._activateStockRules) {
			var stock			= parseInt(record[20], 10);
			var notCommandable	= (record[21] == 'true');
			var notReorderable	= (record[22] == 'true');
			var warningStock	= parseInt(record[23], 10);
			var criticalStock	= parseInt(record[24], 10);

			var stockRuleKey = this.getStockRuleKey(notCommandable, notReorderable, stock, warningStock, criticalStock);
			var stockRule = this._stockRules[stockRuleKey];
			if (stockRule == null) {
				alert("Stock rule with key [" + stockRuleKey + "] is null.");
				continue;
			}
			product.setReferenceNotCommandable(code, notCommandable);
			product.setReferenceStockRule(code, stockRule);

			// Treatment of not commandable references
			if (notCommandable || stockRule.cannotCommandReference()) {
				nbNotCommandableReference++;
				if (stockRule.isHiddenReference()) {
					nbHiddenReference++;
					continue;
				}
			}
		}
		var dimRef = "";
		if (product.useOpenDimension == true) {
			var openDimension = record[6];
			dimRef = openDimension;
			if (product.dimensionCodes[0] == null) product.dimensionCodes[0] = new Object();
			product.dimensionCodes[0][openDimension] = openDimension;
		}
		else {
			for (var i=0; i<5; i++) {
				var oid = record[7 + 2 * i];
				dimRef += oid + "|";
				if (oid == "") continue;
				if (product.dimensionCodes[i] == null) product.dimensionCodes[i] = new Object();
				product.dimensionCodes[i][oid] = record[8 + 2 * i];
			}
		}
		product.referenceByDim[dimRef] = record[0];
	}

	// Recovery of count
	product.nbReference					= nbReference;
	product.nbNotCommandableReference	= nbNotCommandableReference;
	product.nbHiddenReference			= nbHiddenReference;

	// Detection if all references are not commandable or hidden
	product.allRefAreNotCommandable = (nbReference == nbNotCommandableReference);
	product.allRefAreHidden   		= (nbReference == nbHiddenReference);
}

GshpPriceManager.prototype._buildPackDivPlusMinus = function(product)
{
	var div = document.getElementById("packDiv_plusMinus_" + product.oid);
	if (div != null ) {
		if (this._currentPack.managePlusMinus == true) {
			var img = document.createElement("img");
			img.id = "packImg_plusMinus_" + product.oid;
			img.align = "absbottom";
			img.style.width = "16px";
			img.style.height = "16px";
			img.border = 0;

			if (product.nbReference - product.nbNotCommandableReference > 1) {
				var a = document.createElement("a");
				a.href = "#";
				a.id = "packLink_plusMinus_" + product.oid;
				a.onclick = gshpOnClickPackPlusMinus;

				img.src = GshpPriceManager.prototype.PLUS_ICON;
				a.appendChild(img);
				div.appendChild(a);
			}
			else {
				img.src = GshpPriceManager.prototype.EMPTY_ICON;
				div.appendChild(img);
			}
		}
	}
}

GshpPriceManager.prototype._fillOptions = function(product, n, dimensions)
{
	var referenceDimensionSelect = document.getElementById("referenceDimensionSelect_" + product.oid + "_" + product.use + "_" + (n+1));
	while (referenceDimensionSelect.firstChild) {
		referenceDimensionSelect.removeChild(referenceDimensionSelect.firstChild);
	}
	var values = new Object();
	for (var code in product.references) {
		var record = product.getReferenceRecord(code);
		var stockRule = product.getReferenceStockRule(code);
		var notCommandableRef = product.getReferenceNotCommandable(code);

		var ok = true;
		if (product.useOpenDimension == true) {
			var dimension = dimensions[0];
			if ((dimension != null) && (dimension != record[6]))
				ok = false;
		}
		else {
			for (var i=0; i<5; i++) {
				var dimension = dimensions[i];
				if (dimension == null) continue;
				var oid = record[7 + 2 * i];
				if (oid != dimension) {
					ok = false;
					break;
				}
			}
		}

		// Reference is hidden
		if ((ok == true) && (stockRule != null)) {
			if (((product.mode == GshpPriceManager.prototype.CURRENTPRODUCT_MODE) && (stockRule.isHiddenReference() == true)) ||
				((product.mode == GshpPriceManager.prototype.PACK_MODE) && (notCommandableRef || (stockRule.cannotCommandReference()))))
			ok = false;
		}

		if (ok) {
			if (product.useOpenDimension == true) {
				var openDimension = record[6];
				values[openDimension] = openDimension;
			}
			else {
				var dimensionOid	= record[7 + 2 * n];
				var dimensionLabel	= record[8 + 2 * n];
				values[dimensionOid] = dimensionLabel;
			}
		}
	}
	for (var oid in values) {
		var label = values[oid];
		var option = document.createElement("OPTION");
		option.text = label;
		option.value = oid;
		referenceDimensionSelect.options.add(option);
	}
	this.onChangeDimension(referenceDimensionSelect);
}

GshpPriceManager.prototype._selectReference = function(product, dimensions)
{
	for (var code in product.references) {
		var record = product.getReferenceRecord(code);
		var ok = true;
		if (product.useOpenDimension == true) {
			var dimension = dimensions[0];
			if ((dimension != null) && (dimension != record[6]))
				ok = false;
		}
		else {
			for (var i=0; i<5; i++) {
				var dimension = dimensions[i];
				if (dimension == null) continue;
				var oid = record[7 + 2 * i];
				if (oid != dimension) {
					ok = false;
					break;
				}
			}
		}

		if (ok) {
			product.setCurrentReferenceCode(code);
			this.showReference(product, code);
			return;
		}
	}
}

GshpPriceManager.prototype._buildPackItemDescription = function(product)
{
	if (product == null) return;

	// Generation of description
	var packItemDescr = ""
	if (product.canCommandCurrentReference() == true) {
		var record = product.getReferenceRecord(product.getCurrentReferenceCode());

		var computedPrice = this.computePrice(record);
		var basePrice 	= computedPrice[0];
		var baseVatPrice= computedPrice[1];
		var vatRate 	= computedPrice[2];
		var price 		= computedPrice[3];
		var vatPrice	= computedPrice[4];
		var clientDiscountPercentage = computedPrice[5];

		var packDiscountPercentage	= product.packDiscountPercentage;

		// Recovery of pack item customization
		var customization 	= "";
		var customizationElt= document.getElementById("packItemCustomization_" + product.oid);
		if (customizationElt != null)
			customization = customizationElt.value;

		// Description
		packItemDescr += "basketCode=" + objStringUtils.escape(record[1], "#|") + "#";
		packItemDescr += "basketLabel=" + objStringUtils.escape(product.label, "#|") + "#";
		packItemDescr += "basketCustomization=" + objStringUtils.escape(customization, "#|") + "#";
		packItemDescr += "basketPrice=" + price + "#";
		packItemDescr += "basketVatPrice=" + vatPrice + "#";
		packItemDescr += "basketBasePrice=" + basePrice + "#";
		packItemDescr += "basketBaseVatPrice=" + baseVatPrice + "#";
		packItemDescr += "basketVat=" + vatRate + "#";
		packItemDescr += "basketClientDiscountPercentage=" + clientDiscountPercentage + "#";
		packItemDescr += "basketPackDiscountPercentage=" + packDiscountPercentage + "#";
		packItemDescr += "basketReference=" + objStringUtils.escape(record[0], "#|");
	}
	return packItemDescr;
}

GshpPriceManager.prototype._updatePackPrice = function()
{
	if (this._currentPack == null) return;

	// Pack items
	var productList = this._currentPack.productList;

	// Recovery of count of selected pack item
	var nbSelectedPackItem = 0;
	for (var ind=0; ind<productList.length; ind++) {
		var product = productList[ind];
		if (product.isSelectedPackItem() == true) {
			nbSelectedPackItem++;
		}
	}

	// Calculation of prices according to pack discount percentages
	var percentageList = this._currentPack.getDiscountPercentageList(nbSelectedPackItem);

	// Calculation of totals (prices and discounts)
	var subTotalPrice = subTotalVatPrice = 0.0;
	var totalPrice = totalVatPrice = 0.0;

	var indPackItem = 0;
	for (var ind=0; ind<productList.length; ind++) {
		var product = productList[ind];
		if (product.isSelectedPackItem() == true) {
			var record = product.getReferenceRecord(product.getCurrentReferenceCode());

			var computedPrice = this.computePrice(record);
			var basePrice 	= computedPrice[0];
			var baseVatPrice= computedPrice[1];
			var vatRate 	= computedPrice[2];
			var price 		= computedPrice[3];
			var vatPrice	= computedPrice[4];
			var clientDiscountPercentage = computedPrice[5];

			// Recovery of pack dsicount percentage
			var packDiscountPercentage 		= percentageList[indPackItem];
			product.packDiscountPercentage	= packDiscountPercentage;

			// Client percentage discount
			if (clientDiscountPercentage > 0) {
				price 	= this.roundPrice(price - (price * clientDiscountPercentage / 100.0));
				vatPrice= this.calculateVatPrice(price, vatRate);
			}

			// Sub total (prices without pack discount)
			subTotalPrice += price;
			subTotalVatPrice += vatPrice;

			// Total (prices with pack discount)
			if (packDiscountPercentage > 0) {
				price 	= this.roundPrice(price - (price * packDiscountPercentage / 100.0));
				vatPrice= this.calculateVatPrice(price, vatRate);
			}
			totalPrice += price;
			totalVatPrice += vatPrice;

			indPackItem++;
		}
	}

	// Price of selected pack items
	var priceValueElt = document.getElementById("packItemsPriceValue");
	if (priceValueElt != null) priceValueElt.innerHTML = this.formatPriceAccordingToVatDisplayMode(subTotalPrice, subTotalVatPrice, this._vatDisplayMode, this._showPriceType, false);

	// Discount value
	var discountValueElt = document.getElementById("packDiscountValue");
	if (discountValueElt != null) discountValueElt.innerHTML = this.formatPriceAccordingToVatDisplayMode(subTotalPrice-totalPrice, subTotalVatPrice-totalVatPrice, this._vatDisplayMode, this._showPriceType, false);

	// Price of pack
	var priceValueElt = document.getElementById("packPriceValue");
	if (priceValueElt != null) priceValueElt.innerHTML = this.formatPriceAccordingToVatDisplayMode(totalPrice, totalVatPrice, this._vatDisplayMode, this._showPriceType, false);
}

//	-------------------------------------------------------------------------
//	addReferenceToBasket,addCurrentReferenceToBasket,  addCurrentPackToBasket and addCurrentAnythingToBasket
//	Adding of data to basket
//	Returns : True if adding
//	-------------------------------------------------------------------------
GshpPriceManager.prototype.addReferenceToBasket = function(	formId,
															iRefOid, sCode, sLabel, sCustomization, 
															iQuantity, 
															dPrice, dVatPrice, 
															dBasePrice, dBaseVatPrice, 
															dVat, 
															dClientDiscountPercentage )
{
	// Checking of data
	if ((formId == null) || (formId == "")) return false;
	if ((iRefOid == null) || isNaN(iRefOid)) return false;
	if ((sCode == null) || (sCode == "")) return false;
	if (sLabel == null) sLabel = "";
	if (typeof(sLabel) != "string") sLabel = "" + sLabel;
	if (sCustomization == null) sCustomization = "";
	if (typeof(sCustomization) != "string") sCustomization = "" + sCustomization;
	if ((iQuantity == null) || (typeof(iQuantity) != "number") || (iQuantity < 1)) iQuantity = 1;
	if ((dPrice == null) || (typeof(dPrice) != "number")) dPrice = 0.0;
	if ((dVatPrice == null) || (typeof(dVatPrice) != "number")) dVatPrice = 0.0;
	if ((dBasePrice == null) || (typeof(dBasePrice) != "number")) dBasePrice = 0.0;
	if ((dBaseVatPrice == null) || (typeof(dBaseVatPrice) != "number")) dBaseVatPrice = 0.0;
	if ((dVat == null) || (typeof(dVat) != "number")) dVat = this._defaultVatRate;
	if ((dClientDiscountPercentage == null) || (typeof(dClientDiscountPercentage) != "number")) dClientDiscountPercentage = 0.0;

	// Recovery of form
	var form = document.getElementById(formId);
	if (form == null) {
		alert("The form [" + formId + "] to sent reference is not defined!");
		return false;
	}

	// Update of form
	form.basketCode.value = sCode;
	form.basketLabel.value = sLabel;
	form.basketCustomization.value = sCustomization;
	form.basketQuantity.value = iQuantity;
	form.basketPrice.value = dPrice;
	form.basketVatPrice.value = dVatPrice;
	form.basketBasePrice.value = dBasePrice;
	form.basketBaseVatPrice.value = dBaseVatPrice;
	form.basketVat.value = dVat;
	form.basketClientDiscountPercentage.value = dClientDiscountPercentage;
	form.basketReference.value = iRefOid;

	form.submit();
	return true;
}

GshpPriceManager.prototype.addCurrentReferenceToBasket = function()
{
	var record = this._currentProduct ? this._currentProduct.getReferenceRecord(this._currentProduct.getCurrentReferenceCode()) : null;
	if (record == null) {
		alert("No current reference!");
		return false;
	}

	// Recovery of form
	var form = document.getElementById(this.addReferenceToBasketFormId);
	if (form == null) {
		alert("The form [" + this.addReferenceToBasketFormId + "] to sent reference is not defined!");
		return false;
	}

	// Recovery of data
	var quantity = 1;
	var quantityInput = document.getElementById("gshpBasketQuantityInput");
	if (quantityInput) {
		quantity = parseInt(quantityInput.value, 10);
		if (isNaN(quantity) || quantity < 1) quantity = 1;
	}

	var computedPrice = this.computePrice(record);
	var basePrice	= computedPrice[0];
	var baseVatPrice= computedPrice[1];
	var vatRate		= computedPrice[2];
	var price		= computedPrice[3];
	var vatPrice	= computedPrice[4];
	var clientDiscountPercentage = computedPrice[5];

	// Update of form (Customization is not done here)
	form.basketCode.value = record[1];
	form.basketLabel.value = "" + this._currentProduct.label;
	form.basketQuantity.value = quantity;
	form.basketPrice.value = price;
	form.basketVatPrice.value = vatPrice;
	form.basketBasePrice.value = basePrice;
	form.basketBaseVatPrice.value = baseVatPrice;
	form.basketVat.value = vatRate;
	form.basketClientDiscountPercentage.value = clientDiscountPercentage;
	form.basketReference.value = record[0];

	form.submit();
	return true;
}

GshpPriceManager.prototype.addCurrentPackToBasket = function()
{
	if (this._currentPack == null) return false;
	if (this._currentPack.isHidden == true) return false;

	// Recovery of form
	var form = document.getElementById(this.addPackToBasketFormId);
	if (form == null) {
		alert("The form [" + this.addPackToBasketFormId + "] to sent pack is not defined!");
		return false;
	}

	// Recovery of descriptions for selected references
	var packDescr = "";
	var productList = this._currentPack.productList;
	for (var ind=0; ind<productList.length; ind++) {
		var product = productList[ind];
		if (product.isSelectedPackItem() == true) {
			var description = this._buildPackItemDescription(product);
			if (description != "") {
				if (packDescr != "") packDescr += "|";
				packDescr += description;
			}
		}
	}

	// Update of form
	if (packDescr != "") {
		form["basketPack"].value = this._currentPack.oid;
		form["basketQuantity"].value = "1";
		form["basketPackDescription"].value = packDescr;

		form.submit();
		return true;
	}
	return false;
}

GshpPriceManager.prototype.addCurrentAnythingToBasket = function()
{
	var addTo = this.addCurrentPackToBasket();
	if (addTo == false)
		addTo = this.addCurrentReferenceToBasket();
	return addTo;
}

//	-------------------------------------------------------------------------
//	getStockRuleKey
//	Generation fo key about stock rule
//	-------------------------------------------------------------------------
GshpPriceManager.prototype.getStockRuleKey = function(notCommandable, notReorderable, stock, warningStock, criticalStock)
{
	var key = "";
	if (notCommandable == true)
		key += "AS_NC";
	else {
		if (stock > warningStock)
			key += "GS_";
		else
		if ((warningStock >= stock ) && (stock > criticalStock))
			key += "WS_";
		else
			key += "CS_";
		key += notReorderable ? "NR" : "R";
	}
	return key;
}


// ------------------------------------- Manager complement
//
GshpPriceManager.prototype.setManagerComplement = function(managerComplement)
{
	this._oComplement = managerComplement;
}

GshpPriceManager.prototype.getManagerComplement = function()
{
	return this._oComplement;
}


//
// ------------------------------------- class GshpStockRule
//
function GshpStockRule(type, actionOnRef, showWarningMsg, warningMsg)
{
	this._type				= type;
	this._actionOnRef		= actionOnRef;
	this._showWarningMsg	= showWarningMsg;
	this._warningMsg		= warningMsg;
}

GshpStockRule.prototype.isHiddenReference = function()
{
	return (this._actionOnRef == "hideRef");
}

GshpStockRule.prototype.canCommandReference = function()
{
	return (this._actionOnRef == "authorizeRefCommand");
}

GshpStockRule.prototype.cannotCommandReference = function()
{
	return (this._actionOnRef != "authorizeRefCommand");;
}

GshpStockRule.prototype.haveWarningMsg = function()
{
	return ((this._showWarningMsg == true) && (this._warningMsg != ""));
}

GshpStockRule.prototype.getType = function()
{
	return this._type;
}

GshpStockRule.prototype.getWarningMsg = function()
{
	if (this.haveWarningMsg() == true)
		return this._warningMsg;
	return "";
}


//
// ------------------------------------- class GshpPack
//
function GshpPack(oid)
{
	this.oid	= oid;
	this.label 	= "";

	this.isHidden 			= false;
	this.managePlusMinus	= false;
	this.hasCurrentProduct	= false;
	this.productList 		= new Array();

	this.promoOid 				= null;
	this.promoDescription		= "";
	this.discountPercentageLists= new Array();
}

GshpPack.prototype.addProduct = function(product)
{
	if (product.mode == GshpPriceManager.prototype.PACK_MODE)
		this.productList[this.productList.length] = product;
}

GshpPack.prototype.getDiscountPercentageList = function(nbProduct)
{
	var percentageList = this.discountPercentageLists[nbProduct];
	if (percentageList == null)  {
		percentageList = new Array();

		// Recovery of list with less products
		for (var ind=nbProduct-1; ind>=0; ind--) {
			var tmpPercentageList = this.discountPercentageLists[ind];
			if (tmpPercentageList != null) {
				for (var ind2=0; ind2<tmpPercentageList.length; ind2++) {
					percentageList[ind2] = tmpPercentageList[ind2];
				}
				break;
			}
		}

		// 0.0 is complement percentage
		for (var ind=percentageList.length; ind<nbProduct; ind++) {
			percentageList[ind] = 0.0;
		}
	}
	return percentageList;
}

GshpPack.prototype.setPromoModel = function(promoOid, promoDescription)
{
	this.promoOid 			= promoOid;
	this.promoDescription	= promoDescription;
	this._buildDiscountPercentageLists();
}

GshpPack.prototype._buildDiscountPercentageLists = function()
{
	this.discountPercentageLists = new Array();
	var discountList = this.promoDescription.split("\n");
	for (var ind=0; ind<discountList.length; ind++) {
		var discount = discountList[ind];
		if (discount == "") continue;
		var discountValueList = discount.split(" ");

		var percentageList = new Array();
		for (var ind2=0; ind2<discountValueList.length; ind2++) {
			var percentage = parseFloat(discountValueList[ind2]);
			if (isNaN(percentage)) continue;
			percentageList[percentageList.length] = percentage;
		}

		this.discountPercentageLists[percentageList.length] = percentageList;
	}
}


//
// ------------------------------------- class GshpProduct
//
function GshpProduct(mode, use, oid)
{
	this.mode	= mode;
	this.use	= use;
	this.oid	= oid;

	this.studied			= false;
	this.label 				= "";
	this.useOpenDimension	= false;
	this.openDimensionLabel	= "";
	this.references 		= new Object();
	this.dimensionLabels 	= new Array("","","","","");
	this.dimensionCodes		= new Array();
	this.referenceByDim		= new Object();
	this.openCategories 	= new Array("","","","","");

	this.nbReference				= 0;
	this.nbNotCommandableReference	= 0;
	this.nbHiddenReference			= 0;

	this.allRefAreNotCommandable	= false;
	this.allRefAreHidden 			= false;

	this.isCheckedPackItem 		= false;
	this.packDiscountPercentage	= 0.0;

	this.currentReferenceCode 	= "";
}

GshpProduct.prototype.getCurrentReferenceCode = function()
{
	return this.currentReferenceCode;
}
GshpProduct.prototype.getReferenceRecord = function(code)
{
	return this.references[code]._record;
}
GshpProduct.prototype.getReferenceStockRule = function(code)
{
	return this.references[code]._stockRule;
}
GshpProduct.prototype.getReferenceNotCommandable = function(code)
{
	return this.references[code]._notCommandable;
}

GshpProduct.prototype.setCurrentReferenceCode = function(code)
{
	this.currentReferenceCode = code;
}
GshpProduct.prototype.setReferenceRecord = function(code, record)
{
	if (this.references[code] == null)	this.references[code] = new Object();
	this.references[code]._record = record;
}
GshpProduct.prototype.setReferenceStockRule = function(code, stockRule)
{
	if (this.references[code] == null)	this.references[code] = new Object();
	this.references[code]._stockRule = stockRule;
}
GshpProduct.prototype.setReferenceNotCommandable = function(code, notCommandable)
{
	if (this.references[code] == null)	this.references[code] = new Object();
	this.references[code]._notCommandable = notCommandable;
}

GshpProduct.prototype.isSelectedPackItem = function()
{
	return (this.nbReference - this.nbNotCommandableReference > 0) &&
			((this.mode == GshpPriceManager.prototype.PACK_MODE) && 
			((this.isCurrentProduct == true) || (this.isCheckedPackItem == true)));
}

GshpProduct.prototype.canCommandCurrentReference = function()
{
	var code 			= this.getCurrentReferenceCode();
	var notCommandable	= this.getReferenceNotCommandable(code);
	var stockRule		= this.getReferenceStockRule(code);
	return !(notCommandable || stockRule.cannotCommandReference());
}


// ------------------------------------- Global object
//
var objGshpPriceManagerComplement;	// May be overriden by decor
var objGshpPriceManager = new GshpPriceManager();

// Recovery of overriden of default manager complement
if (objGshpPriceManagerComplement != null)
	objGshpPriceManager.setManagerComplement( objGshpPriceManagerComplement );
else
	objGshpPriceManager.setManagerComplement( new GshpPriceManagerComplement() );