var giQuantityInStock = -1;

// BOF : gestion des stocks et attributs
function myProduct() {
	// definition des variables
	this.manage_stock	= false;					// gestion de stock ou non
	

	this.settings		= {									// configuration de la classe
										'instance_name'	: 'product',
										'container' 		: 'attributes',
										'attributes'		: {
											'container'		: 'ul_attr',
											'attribute'		: {
												'container'	: 'li_attr_',
												'input_name': 'combination',
												'style'			: 'width:255px;'
											}		
										},
										'basket'					: {
											'container'		: 'basket',
											'input_qty_id': 'order_product_quantity'
										}
									}

	this.attributes		= {};
	this.combinations	= {};
	
	this.stock				= 0; 							// stock sans combination
	
	// methodes

//#
	// constucteur de classe
	this.construct	= function(pricing, manage_stock) {
		this.settings.pricing	= pricing;
		this.manage_stock	= manage_stock;
	}
	
//#
	// php equivalent
	this.trim				= function(string) {
		return string.replace(/^\s+/g,'').replace(/\s+$/g,''); 
	}
	
	/**
	 * ##################################################################################################################################
	 *					ATTRIBUTES
	 * ##################################################################################################################################
	 */

//#
	// chargement des select au load de la page
	this.loadAttributes	= function(attributes) {
		this.attributes	= attributes;
		var first_attr_id	= null;
		// supprime le container (en cas de réappel)
		if($(this.settings.attributes.container)) $(this.settings.attributes.container).remove();
		//creation du container attribute
		/*$(this.settings.container).insert({
			bottom: '<ul id="' + this.settings.attributes.container + '">' + '</ul>'
		});*/
		
		// add table
		$(this.settings.container).insert({
			bottom: new Element('table', {
														id			: this.settings.attributes.container,
														align		: 'right'
													}).update('<tfoot><tr><td style="padding-top: 6px; padding-right: 2px;" id="' + this.settings.basket.container + '"></td></tr></tfoot><tbody><tr><td class="osb_td_product_detail_description"><strong>' + gaLabels['OSB_ATTRIBUTE_DETAIL'] +  '</strong></td></tr></tbody>')
		});
		
		// pour chaque attribut
		for(var attr_id in this.attributes) {
			// mémorisation du premier id, pour initialisation
			if(!first_attr_id) first_attr_id	= attr_id;
			// id	= create a select
			this.createAttribute(attr_id, this.attributes[attr_id].name);
			// create options
			//this.createOptions(attr_id, this.attributes[attr_id].options); // can't be used with IE 
		}
		// initializeSelection avec le premier attr id
		if(first_attr_id) {
			this.initializeAttribute(first_attr_id);
			// affiche les options possible du premier
			this.displayOptions(first_attr_id);
		}
	}
	
//#	
	// sur le onchange recalcul dynamique des options
	this.initializeAttribute	= function(attribute_id) {
		var nb_next_attributes	= 0;
		var first_attr_id				= null;		// premier id
		// l'attribut nous donne la position courante
		var next_attributes	= this.getNextAttributes(attribute_id);		
		// pour chaque attribut suivant
		for(var attr_id in next_attributes){
			nb_next_attributes++;
			// reset select
			this.resetOptions(attr_id);
			// si 1 er attribut de n
			if(!first_attr_id) {
				first_attr_id	= attr_id;
				// si la valeur n-1 est "faite choix"
				if(!this.getValueSelectedOption(attribute_id)) {
					// disable select
					this.disableAttribute(first_attr_id);
				}
				// sinon
				else {
					// charger options possibles
					this.displayOptions(first_attr_id);
					// enable select
					this.enableAttribute(first_attr_id);
				}
			}
			// sinon
			else {
				// disable select
				this.disableAttribute(attr_id);
			}
		}
		// si pas d'attribut suivant alors display price
		/*if(!nb_next_attributes)*/ this.displayPriceCombination();
	}
	
//#	
	// creation html de l'attribut
	this.createAttribute	= function(attribute_id, attribute_name){
		var oTable	= $(this.settings.attributes.container);		// pointer on table
		var oTBody	=	oTable.getElementsByTagName('tbody')[0];					// pointer on body
	
		oRow = oTBody.insertRow(-1);
		// ajout du libellé
		//oCell = oRow.insertCell(-1);
		//oCell.innerHTML	= (this.countAttributes() > 1 ? gaLabels['OSB_ATTRIBUTE_CHOOSE'] + this.getPosAttribute(attribute_id) + ' : ' : '') + attribute_name ; //htmlspecialchars(attribute_name) 
		// creation de l'attribut (select)
		oCell = oRow.insertCell(-1);
		oCell.id	=  this.settings.attributes.attribute.container + attribute_id ;
		
		//option	= '<option value="0">' + gaLabels['OSB_ATTRIBUTE_CHOOSE_LIST'] + '</option>\n';
		//option	= '<option value="0">--- ' + (this.countAttributes() > 1 ? gaLabels['OSB_ATTRIBUTE_CHOOSE'] + this.getPosAttribute(attribute_id) + ' : ' : '') + attribute_name + ' ---</option>\n';
		option	= '<option value="0">' + attribute_name + '</option>\n';
		
		/*$(this.settings.attributes.attribute.container + attribute_id).insert({
			bottom: new Element('select', {														
														name			: this.settings.attributes.attribute.input_name + '[' + attribute_id + ']',
														id				: this.settings.attributes.attribute.input_name + '' + attribute_id + '',
														style			: this.settings.attributes.attribute.style,
														'onchange': this.settings.instance_name + '.initializeAttribute(\'' + attribute_id + '\');'
													}).update(option)
		});*/
		$(this.settings.attributes.attribute.container + attribute_id).innerHTML	= '<select name="' + this.settings.attributes.attribute.input_name + '[' + attribute_id + ']' + '" id="' + this.settings.attributes.attribute.input_name + attribute_id + '" style="' + this.settings.attributes.attribute.style + ';margin-bottom: 4px;padding: 1px;" onchange="' + this.settings.instance_name + '.initializeAttribute(\'' + attribute_id + '\');' + '">' + option + '</select>';
	}
	
//#
	// return next attribute ids 
	this.getNextAttributes	= function(attribute_id) {	
		var attributes_list	= new Object();
		var attr_id	= attribute_id;
		// tant que getNextAttribute (attribute id) != null		
		while(attr_id	= this.getNextAttribute(attr_id) ) {
			// construire le tableau d'id			
			attributes_list[attr_id]	= {};
		}
		// retourne id list
		return attributes_list;
	}
	
//#	
	//return next attribute id
	this.getNextAttribute	= function(attribute_id) {
		var selects	= $(this.settings.attributes.container).getElementsByTagName('select');
		// parcourir les attributs
		for(var i = 0; i < selects.length; i++) {
			// si attribute_id = null
			if(!attribute_id) {
				// renvoyer le premier
				return this.translateAttribute(selects[i].id);
			}
			// sinon
			else {
				// si attribute_id = celui pointé
				if(this.translateAttribute(selects[i].id) == attribute_id) {
					// si l'id suivant existe
					if( (i+1) < selects.length) {
						// renvoyer l'id suivant
						return this.translateAttribute(selects[i+1].id);
					}
					// sinon
					else {
						// renvoyer null
						return null;
					}
				}
				// sinon
					// continuer
			}
		}
		return null;
	}
	
//#
	// return next previous ids
	this.getPreviousAttributes	= function(attribute_id) {
		var attributes_list	= new Object();
		var attr_id	= attribute_id;
		// tant que getNextAttribute (attribute id) != null		
		while(attr_id	= this.getPreviousAttribute(attr_id) ) {
			// construire le tableau d'id
			attributes_list[attr_id]	= {};
		}
		// retourne id list
		return attributes_list;
	}
	
//#
	//return previous attribute id
	this.getPreviousAttribute	= function(attribute_id) {
		var selects	= $(this.settings.attributes.container).getElementsByTagName('select');
		// parcourir les attributs
		for(var i = (selects.length-1); i >= 0; i--) {
			// si attribute_id = null
			if(!attribute_id) {
				// renvoyer le premier
				return this.translateAttribute(selects[i].id);
			}
			// sinon
			else {
				// si attribute_id = celui pointé
				if(this.translateAttribute(selects[i].id) == attribute_id) {
					// si l'id suivant existe
					if( (i-1) >= 0 ) {
						// renvoyer l'id suivant
						return this.translateAttribute(selects[i-1].id);
					}
					// sinon
					else {
						// renvoyer null
						return null;
					}
				}
				// sinon
					// continuer
			}
		}
		return null;
	}
	
//#
	// active le select
	this.enableAttribute	= function(attribute_id) {
		$(this.settings.attributes.attribute.input_name + attribute_id).disabled	= false;
	}
	
//#
	// desactive le select
	this.disableAttribute	= function(attribute_id) {
		$(this.settings.attributes.attribute.input_name + attribute_id).disabled	= true;
	}

//#
	// split attribute id, and return int id
	this.translateAttribute	= function(raw_attribute_id) {
		var attr_id	= raw_attribute_id.substr(this.settings.attributes.attribute.input_name.length);
		return attr_id;
	}
	
//#
	// compte le nombre d'attribut
	this.countAttributes	= function() {
		var counter	= 0; 
		for(var i in this.attributes) {
			counter++;
		}
		return counter;
	}
	
//#
	// donne la position d'un attribut
	this.getPosAttribute	= function(attribute_id) {
		var counter	= 0; 
		for(var attr_id in this.attributes) {
			counter++;
			if(attr_id == attribute_id) return counter;
		}
		return counter;
	}
	
	/**
	 * ##################################################################################################################################
	 *					OPTIONS
	 * ##################################################################################################################################
	 */
	
//#
	// creation html de l'option
	this.createOptions		= function(attribute_id, options) {
		// option null
		$(this.settings.attributes.attribute.input_name + '' + attribute_id + '').insert({
			bottom: new Element('option', {
														'value'			: 0
													}).update( '<option value="0">' + this.attributes[attribute_id].name + '</option>\n')	//gaLabels['OSB_ATTRIBUTE_CHOOSE_LIST']
		});
		// pour toutes les options
		for(var opt_id in options) {
			// creation de l'option
			var option_name	= options[opt_id].name; //htmlspecialchars(options[opt_id].name);
			$(this.settings.attributes.attribute.input_name + '' + attribute_id + '').insert({
				bottom: new Element('option', {
															title				: html_entity_decode(options[opt_id].name),			// htmlspecialchars?
															'value'			: opt_id
														}).update(option_name)
			});
		}			
	}
	
//#	
	// retourne la value ou null si pas d'option selected
	this.getValueSelectedOption	= function(attribute_id) {
		// si get value = 0
		if($(this.settings.attributes.attribute.input_name + attribute_id).getValue() == "0") {
			// alors retourne null
			return null;
		}
		// sinon
		else {
			// retourne la valeur
			return $(this.settings.attributes.attribute.input_name + attribute_id).getValue();
		}
	}
	
//#	
	// affiche que les options nécessaires
	this.displayOptions	= function(attribute_id) {
		var kept_options_list	= new Object();
		// cache toutes les options
		this.hideOptions(attribute_id);
		// getPreviousAttributes
		var previous_attributes	= this.getPreviousAttributes(attribute_id);
		// pour chaque combinaison		
		for(var i in this.combinations) {
			var match	= true;
			for(var attr_id in previous_attributes) {
				if(typeof(this.combinations[i].attributes[attr_id]) == 'undefined' || this.combinations[i].attributes[attr_id] != this.getValueSelectedOption(attr_id) ) {
					match	= false;
				}
			}
			// si previous attribute-option match
			if(match && typeof(this.combinations[i].attributes[attribute_id]) != 'undefined') {
				// alors keep next id
				kept_options_list[this.combinations[i].attributes[attribute_id]]	= {}
			}
			//sinon hide
		}		
		// pour liste to keep
		/*for(var opt_id in kept_options_list) {
			// show id
			this.showOption(attribute_id, opt_id);
		}*/
		this.showOptions(attribute_id, kept_options_list);
	}
	
//#
	// display all options
	this.showOptions	= function(attribute_id, keep_list) {
		/*var options	= $(this.settings.attributes.attribute.input_name + attribute_id).getElementsByTagName('option');
		// pour chaque option
		for(var i = 0; i < options.length; i++) {
			// show
			$(options[i]).show();
		}*/
		// patch pour ie
		// pour chaque attribut
		var options_to_keep	= new Object();
		for(var attr_id in this.attributes) {
			if(attr_id == attribute_id) {
				for(var opt_id in this.attributes[attr_id].options) {
					if(typeof(keep_list[opt_id]) != "undefined" ) {
						options_to_keep[opt_id]	= this.attributes[attr_id].options[opt_id];
					}
				}
				this.createOptions(attribute_id, options_to_keep);
				break;
			}
		}
	}
	
//#
	// hide all options
	this.hideOptions	= function(attribute_id) {
		/*var options	= $(this.settings.attributes.attribute.input_name + attribute_id).getElementsByTagName('option');
		// pour chaque option
		for(var i = 1; i < options.length; i++) {		// except first choice
			// show
			$(options[i]).hide();
			$(options[i]).remove();
		}*/
		$(this.settings.attributes.attribute.input_name + attribute_id).innerHTML	= '';
	}

//#
	// réaffiche tout et place le sélect sur 0
	/*this.showOption	= function(attribute_id, opt_id) {
		var options	= $(this.settings.attributes.attribute.input_name + attribute_id).getElementsByTagName('option');
		// pour chaque option
		for(var i = 0; i < options.length; i++) {
			// show
			if(options[i].value == opt_id)	{
				$(options[i]).show();
				return true;
			}
		}
		return false;
	}*/
	
//#
	// place le sélect sur 0
	this.resetOptions	= function(attribute_id) {
		// selected index = 0
		$(this.settings.attributes.attribute.input_name + attribute_id).selectedIndex	= 0;
	}
	
	/**
	 * ##################################################################################################################################
	 *					COMBINATIONS
	 * ##################################################################################################################################
	 */
	
//#
	// chargement des combinations
	this.loadCombinations	= function(combinations) {
		// sauvegarde des combinations
		this.combinations	= combinations;
	}
	
//#
	// valide que la combinaison est ok
	this.checkCombination	= function() {
		//isNaN est déjà géré...
		var stock_asked	=	parseInt($(this.settings.basket.input_qty_id).value, 10);
		// si attributes
		if(this.countAttributes()) {				
			// valide la combinaison
			var combination_id	= this.getIdCombination();
			// si get combination == null
			if(!combination_id) {
				// combinaison indisponible		// impossible normalement
//				console.debug('combination inexistante');
				return false;						// combination inexistante
			}
			else {
				// si stock actif
				if(this.manage_stock)  {
					// vérifie le stock
					if(this.getValidStockCombination(combination_id, stock_asked, true)) {
						// retourne true si ok
//						console.debug('ok, order is possible');
						return true;			// ok, order is possible
					}
					else {
//						console.debug('pas suffisament de stock');
						return false;			// pas suffisament de stock
					}
				}
				else {
//					console.debug('Combination ok, pas de gestion de stock');
					return true;				// Combination ok, pas de gestion de stock
				}
			}
		}
		// sinon ok
		else {		
//			console.debug('pas d\'attribut, donc ok coté déclinaison');
			return this.getValidStock(stock_asked, true);	// pas de déclinaison, mais vérif du stock
		}
	}
	
//#
	// affiche le prix final
	this.displayPriceCombination = function() {
		//$(this.settings.basket.container).innerHTML	= 'xxx,xx' + (this.settings.pricing.display == 'HT' ? this.settings.pricing.ht_name : this.settings.pricing.ttc_name);
		var output	= '';
		var combination_id	= this.getIdCombination();
		// si get combination == null
		if(!combination_id) {
			// combinaison indisponible		// impossible normalement
			output	= '';
		}
		// sinon
		else {
			// si pas de stock
			if(!this.getValidStockCombination(combination_id)) {
				// epuisé
				output	= '<div class="osb_product_not_on_sale" style="text-align:right; white-space:nowrap;">' + gaLabels['OSB_ATTRIBUTE_OUT_OF_STOCK'] + '</div>';
			}			
			// sinon price
			else {
				// si le prix n'est pas identique pour toutes les combinations
				if(!this.settings.pricing.same_price) {
					// calcul du prix final...
					final_price	= this.calcPriceCombination(parseFloat(this.combinations[combination_id].values.variation_ht));
					final_price	= number_format (final_price, 2, ',', ' ');
					output	= '<div class="osb_price" style="text-align:right; white-space:nowrap;">';
					output	+= gaLabels['OSB_ATTRIBUTE_USER_TOTAL'] + ' ' + final_price + (this.settings.pricing.display == 'HT' ? this.settings.pricing.ht_name : this.settings.pricing.ttc_name);
					output	+= '</div>';
				}
			}
		}
			
		// sortie affichage
		$(this.settings.basket.container).innerHTML	= output;
	}

//#
	// calcul le prix final
	this.calcPriceCombination = function(variation_ht) {
		
		var ttc				= 0;
		var ht				= 0;
		var vat				= (parseFloat(this.settings.pricing.vat) / 100) + 1;
		var base_price_ht	= parseFloat(this.settings.pricing.base_price);
		var eco_tax_ht		= parseFloat(this.settings.pricing.eco_tax);
		var discount_value	= parseFloat(this.settings.pricing.discount_value);
		
		// switch discount type
		switch(this.settings.pricing.discount_type) {
			// percent
			case 'PERCENT':
				ttc	= ((base_price_ht * vat + variation_ht * vat - eco_tax_ht * 1.196) * (1 - (discount_value / 100))) + (eco_tax_ht * 1.196);
				ht	= ((base_price_ht + variation_ht - eco_tax_ht) * (1 - (discount_value / 100))) + eco_tax_ht;
				break;
			// amount
			case 'AMOUNT': 
				// ttc	= (base price * tva) + (variation * tva) - (dicount_value * tva)
				ttc	= Math.round(base_price_ht * vat * 100)/100 + Math.round(variation_ht * vat * 100)/100 - Math.round(discount_value * vat * 100)/100;
				// ht		= base price + variation - dicount_value
				ht	= base_price_ht + variation_ht - discount_value;
				break;
			// none
			case 'NONE':
				// ttc	= (base price * tva) + (variation * tva)
				ttc	= Math.round(base_price_ht * vat * 100)/100 + Math.round(variation_ht * vat * 100)/100;
				// ht		= base price + variation
				ht	= base_price_ht + variation_ht;
				break;
		}
		
		// si ttc alors retourne ttc final price
		if(this.settings.pricing.display == "TTC") return Math.round(ttc * 100) / 100;
		// sinon retourne ht final price
		else return Math.round(ht * 100) / 100;
	}
	
	
//#
	// retourne la combinaison id
	this.getIdCombination	= function() {
		if(!this.countAttributes()) return null;			// no attribute, no combination
		// getNextId(null)
		var next_attributes	= this.getNextAttributes(null);		
		// pour chaque id
		
		// pour chaque combinaison		
		for(var i in this.combinations) {
			var match	= true;
			for(var attr_id in next_attributes) {
				if(typeof(this.combinations[i].attributes[attr_id]) == 'undefined' || this.combinations[i].attributes[attr_id] != this.getValueSelectedOption(attr_id) ) {
					match	= false;
				}
			}
			// si next attribute-option match
			if(match) {
				// retourne l'id combination
				return i;
			}
		}
		// nothing has been found
		return null;
	}
	
//#
	// retourne si le stock est possible
	this.getValidStockCombination	= function(combination_id, quantity, decrease_stock) {
		var qty	= quantity != null ? quantity : 1;
		// si get combination == null
		giQuantityInStock = -1;
		if(!combination_id) {
			// retourne invalid			
			return false;
		}
		// sinon
		else {
			// si pas gestion de stock
			if(!this.manage_stock) {
				// alors retourner true
				return true;
			}
			// sinon
			else {				
				//si le stock est inférieur à quantité demandée
				if(parseInt(this.combinations[combination_id].values.stock, 10) < qty){
					// alors retourner false
					giQuantityInStock = this.combinations[combination_id].values.stock;
					return false;										
				}
				// sinon
				else {
					if(decrease_stock) this.combinations[combination_id].values.stock	= parseInt(this.combinations[combination_id].values.stock, 10) - qty;		// decrease stock pour pseudo réalité d'épuisement du stock
					// retourner true
					return true;
				}
			}
		}
	}
	
	/**
	 * ##################################################################################################################################
	 *					STOCK WITHOUT COMBINATION
	 * ##################################################################################################################################
	 */
	
//#
	// load stock
	this.loadStock	= function(stock) {
		for(var combination_id in stock) {
			this.stock	= parseInt(stock[combination_id].values.stock, 10);
			break;		// only one time, anyway it should be one iteration, but we never know
		}
	}
	
//#
	// stock ok ?
	this.getValidStock	= function(quantity, decrease_stock) {
		if(!this.manage_stock) {
			return true;																// stock pas géré
		}
		else {
			if(quantity <= this.stock) {
				if(decrease_stock)  this.stock	-= quantity;		// decrease stock pour pseudo réalité d'épuisement du stock
				return true;			// stock suffisant
			}
			else return false;													// stock faible
		}
	}
	
}
// EOF : gestion des stocks et attributs
