/*****************/
/*	CLASS CART   */
/*****************/
var CLASS ={};
(function(){
	CLASS.cart = function(){
	};
	CLASS.cart.prototype = {
		qte:0,
		amount:0,
		shippingCost:0,
		shippingCostSelected:false,
		shippingCode:"",
		totalAmount:0,
		VAT:0,
		productList:{},
		currency:'$',
		CART_init:function(cart){
			this.productList = cart.productList;
			this.qte = cart.qte;
			this.amount = cart.amount;
			this.shippingCost = cart.shippingCost;
			this.shippingCode = cart.shippingCode;
			this.totalAmount = cart.totalAmount;
		},
		/**
		* add a product to CART
		* send request to actions.php ta add product to cart
		* retrieve product's cart's quantity and cart's amount  
		* @param string product -> product reference
		* @param qte
		* @param HTMLElement -> container of product to send to html cart after update
		*/
		addtoCart:function (product, qte, HTMLElement) {
			if (qte <= 0){
				alert("Veuillez choisir une quantité supérieure à 0");
				return;
			}
			
			var cart_instance = this;
			//var article = $('article.product_line input[value='+product+'], article.product_coffret input[value='+product+']').parents('article.product_line, article.product_coffret');
			$.post('includes/actions.php', { action:"addtoCart", product: product, qte: qte }, function(data) {
				var cart = data.split(";");
				var qte = cart[0];
				var amount = cart[1];
				cart_instance.updateCart(qte, amount);
				cart_instance.updateAddTocartHtmlElement(HTMLElement);
			});
		},
		/**
		 * update product form order form
		 * @param string productRef -> product's reference
		 * @param integer qte -> quantity to update
		 */
		updateProduct:function(productRef, qte){
			if (qte <= 0){
				//alert("Veuillez choisir une quantité supérieure à 0 ou supprimez le produit en utilisant la croix");
				return;
			}
			this.productList[productRef] = qte;
		},
		/**
		 * plus one product
		 * @param string productRef -> product's reference
		 * @return true
		 */
		plusOneProduct:function(productRef){
			if (this.productInCart(productRef)){
				this.productList[productRef] = this.productList[productRef]+1;
			} else{
				this.productList[productRef] = 1;
			}
			return true;
		},
		/**
		 * minus one product
		 * return false if product is already at 0 quantity
		 * @param string productRef -> product's reference
		 * @return boolean
		 */
		minusOneProduct:function(productRef){
			if (this.productInCart(productRef) && this.productList[productRef] > 0){
				this.productList[productRef] = this.productList[productRef]-1;
				return true;
			}
			return false;
		},
		supprProduct:function(productRef){
			delete this.productList[productRef];
			cart_instance = this;
			$.post("includes/actions.php", {action:"supprProduct", productRef:productRef}, function(data){
				$('div.commande').html(data);
			}, "text");
		},
		setShippingCost:function(shippingCost){
			this.shippingCost = shippingCost;
			//this.shippingCostSelected = true;
		},
		setShippingCode:function(shippingCode){
			this.shippingCostSelected = false;
			this.shippingCode = "";
			if(shippingCode != "choose" && shippingCode != ""){
				this.shippingCode = shippingCode;
				this.shippingCostSelected = true;
			}
		},
		calcAmount:function(){
			this.qte = 0;
			this.amount = 0;
			var _I = this;
			for (var productRef in this.productList){
				var q = this.productList[productRef];
				this.qte = this.qte + q;
				var p = _I.CAT_getProductPrice(productRef);
				this.amount = this.amount + q*p;
			}
		},
		calcTotalAmount:function(){
			this.totalAmount = this.amount+this.shippingCost+this.VAT;
		},
		/**
		 * 
		 * @param json producList ->{productRef:qte, ....}
		 */
		updateProductList:function(producList){
			this.productList = producList;
		},
		/**
		 * Verify is a product is in cart
		 * @param refProduct
		 * @returns {Boolean}
		 */
		productInCart:function(refProduct){
			if(this.productList[refProduct] == undefined){
				return false;
			}
			return true;
		},
		isOrderEmpty:function(){
			this.calcAmount();
			if (this.qte === 0){
				return true;
			}
			return false;
		},
		isShippingNotSelected:function(){
			if (this.shippingCostSelected === false){
				return true;
			}
			return false;
		}
	};
	CLASS.customerInformation = function(){
	};
	CLASS.customerInformation.prototype = {
			/**
			 * instance of form that contains addresses informations
			 */
			$f:{},
			/**
			 * Form values
			 */
			CI_submitFlag:false,
			/**
			 * object Json pour stocker les valeurs du formulaire
			 */
			CI_formValues:{'shipping':{}, 'invoicing':{}, 'message':{}, 'options':{'invoice':false, 'messageAddressee':false, 'messageTeamStore':false}},
			/**
			 * description des éléments du formulaire avec les attributs obligatoire(true/false) et le type de donnée pour le contrôle
			 */
			CI_formFields:{
						'shipping':{
							'civilite':[true, 'alphanumWS'],'name':[true, 'alphanumWS'],'surname':[true, 'alphanumWS'],
							'company':[false, 'alphanumWS'],
							'email':[true, 'email'],'phone':[true, 'tel'],
							'address':[true, 'alphanumWSWret'],'postalCode':[true, 'alphanumWS'],
							'city':[true, 'alphanumWS'],'country':[true, 'alphanumWS']
						},
						'invoicing':{
							'civilite':[true, 'alphanumWS'],'name':[true, 'alphanumWS'],'surname':[true, 'alphanumWS'],
							'company':[false, 'alphanumWS'],
							'email':[true, 'email'],'phone':[true, 'tel'],
							'address':[true, 'alphanumWSWret'],'postalCode':[true, 'alphanumWS'],
							'city':[true, 'alphanumWS'],'country':[true, 'alphanumWS']
						},
						'message':{
							'addressee':[true, 'alphanumWSWret'],'teamStore':[true, 'alphanumWSWret']
						}, 
						'options':{
							'invoice':false, 'messageAddressee':false, 'messageTeamStore':false}
						},
			CI_formCheck:true,
			CI_formMissingFields:{},
			CI_formErrors:{},
			/*
			 * instancie les bind sur les checkbox de forme de l'entité,
			 * le choix de l'adresse de livraison différente de celle de facturation
			 * les messages 
			 */
			CI_init:function(CIFromPhp, HTMLelement){
				this.$f = HTMLelement;
				this.CI_formValues = CIFromPhp;
				//this.CI_setFormValues();
				var instance = this;
				var $inputstext = this.$f.find('input[type=text]');
				var $inputsCheckbox = this.$f.find('input[type=checkbox]');
				var $inputsRadio = this.$f.find('input[type=radio]');
				var $textareas = this.$f.find('textarea');
				$inputstext.bind('focus', function(){
					var s = $(this).parent('div').prev('div');
					if(s.hasClass('formError')){
						s.removeClass('formError');	
					}
				});
				$inputstext.bind('blur', {_I:instance}, function(e){
					var name = $(this).attr('name');
					var split = name.split('_');
					var f = split[0];
					var n = split[1];
					var cktype = e.data._I.CI_formFields[f][n][1];
					var val = $(this).val();
					e.data._I.CI_formValues[f][n] = val;
					if(val !== ""){
						e.data._I.CI_checkFieldType($(this), cktype, val);
					}
				});
				$inputstext.bind('keyup', {_I:instance}, function(e) {
					var name = $(this).attr('name');
					var split = name.split('_');
					var f = split[0];
					var n = split[1];
					e.data._I.CI_formValues[f][n] = $(this).val();
				});
				$textareas.bind('keyup', {_I:instance}, function(e) {
					var name = $(this).attr('name');
					var split = name.split('_');
					var f = split[0];
					var n = split[1];
					e.data._I.CI_formValues[f][n] = $(this).val();
				});
				$textareas.bind('focus', function(){
					if ($(this).attr('name') == "invoicing_address" || $(this).attr('name') == "shipping_address"){
						var s = $(this).parent('div').prev('div');
					}else{
						var s = $(this).prevAll('span');
					}
					if(s.hasClass('formError')){
						s.removeClass('formError');	
					}
				});
				$textareas.bind('blur', {_I:instance}, function(e){
					var name = $(this).attr('name');
					var split = name.split('_');
					var f = split[0];
					var n = split[1];
					var cktype = e.data._I.CI_formFields[f][n][1];
					e.data._I.CI_formValues[f][n] = $(this).val();
					e.data._I.CI_checkFieldType($(this), cktype, e.data._I.CI_formValues[f][n]);
				});
				$inputsRadio.bind('click', {_I:instance}, function(e){
					var name = $(this).attr('name');
					var split = name.split('_');
					var f = split[0];
					var n = split[1];
					e.data._I.CI_formValues[f][n] = $(this).val();
					var $target = $(this).parent('label').parent('div').prev('div');
					if($target.hasClass('formError')){
						$target.removeClass('formError');
					}
				});
				this.$f.find('div.nextButton').bind('click', {_I:instance}, function(e){
					e.data._I.CI_checkfields();
					e.data._I.HTML_nextStep();
				});
				this.$f.find('div.previousButton').bind('click', {_I:instance}, function(e){
					e.data._I.CI_checkfields();
					e.data._I.HTML_previousStep();
				});
			},
			/**
			 * check for submitted values by the form and stocked in this.CI_formValues
			 * @returns {Boolean}
			 */
			CI_checkfields:function(){
				this.CI_formCheck = true;
				this.CI_formMissingFields = {};
				// valid Shipping informations
				var n = 'shipping';
				for (var info in this.CI_formFields[n]){
					if(this.CI_formFields[n][info][0] == true){
						// champs obligatoire
						this.CI_checkReqField(n, info);
					}
				}
				// vérifier les informations de la facturation si elle est cochée
				if (this.CI_formValues['options']['invoice'] == true){
					var n = 'invoicing';
					for (var info in this.CI_formFields[n]){
						if(this.CI_formFields[n][info][0] == true){
							// champs obligatoire
							this.CI_checkReqField(n, info);
						}
					}	
				}
				// vérifier et traiter la précense des messages au destinataire et à la boutique
				if (this.CI_formValues['options']['messageAddressee'] == true){
					var n = 'message';
					if(this.CI_formFields[n]['addressee'][0] == true){
						// champs obligatoire
						this.CI_checkReqField(n, 'addressee');
					}
				}
				if (this.CI_formValues['options']['messageTeamStore'] == true){
					var n = 'message';
					if(this.CI_formFields[n]['teamStore'][0] == true){
						// champs obligatoire
						this.CI_checkReqField(n, 'teamStore');
					}
				}
				return this.CI_formCheck;
			},
			/** verify if some requiered fields are missing
			* if missing fields : set formCheck var to false and add family(AF,AL,..) and fields name in formMissingFileds object
			* @return bool true|false
			*/ 
			CI_checkReqField:function(f, e){
				if(this.CI_formValues[f][e] == undefined || this.CI_formValues[f][e] == ""){
					if (this.CI_formMissingFields[f] == undefined){
						this.CI_formMissingFields[f] = [];
					}
					this.CI_formMissingFields[f].push(e);
					this.CI_formCheck = false;
					return false;
				}
				return true;
			},
			/**
			 * check content of field against its type
			 */
			CI_checkFieldType:function(elt, type, value){
				var fieldName = elt[0].name;
				var testExp= new CLASS.regExp();
				var test = true;
				switch(type){
					case'alphanumWSWret':
						test = testExp.matchRegularExpression(value, testExp.regExpAlphanumericWithWhitespaceWithReturns);
						break;
					case'alphanumWS':
						test = testExp.matchRegularExpression(value, testExp.regExpAlphanumericWithWhitespace);
						break;
					case'alphabetic':
						test = testExp.matchRegularExpression(value, testExp.regExpAlphabetic);
						break;
					case'alphanum':
						test = testExp.matchRegularExpression(value, testExp.regExpAlphanumeric);
						break;
					case'email':
						test = testExp.matchRegularExpression(value, testExp.regExpEmailAdress);
						break;
					case'codepostal':
						test = testExp.matchRegularExpression(value, testExp.regExpCodePostal);
						break;
					case'tel':
						test = true;
						var tfixe =testExp.isNotTelephone(value, 'fixe');
						var tip = testExp.isNotTelephone(value, 'IP');
						var tport = testExp.isNotTelephone(value, 'port');
						var tnati = testExp.isNotTelephone(value, 'nati');
						var tinte = testExp.isNotTelephone(value, 'inte');
						var tinteWild = testExp.isNotTelephone(value, 'inteWild');
						if(tfixe & tip & tport & tnati & tinte & tinteWild){
							test = false;
						}
						break;
					case'TVAIntra':
						test = testExp.matchRegularExpression(value, testExp.regExpTVAIntracommunautaire);
						break;
					case'none':
						break;
				}
				if (fieldName == "message_addressee" || fieldName == 'message_teamStore'){
					var $target = elt.prevAll('span');
				}else{
					var $target = elt.parent('div').prev('div');
				}
				if (test === false){
					this.CI_formErrors[fieldName] = false;
					if (!$target.hasClass('formError')){
						$target.addClass('formError');
					}
					return false;
				}
				delete this.CI_formErrors[fieldName];
				if ($target.hasClass('formError')){
					$target.removeClass('formError');
				}
				return true;
			},
			CI_hasFormErrors:function(){
			  var prop;
			  var countM = 0;
			  for (prop in this.CI_formMissingFields) {
				  countM++;
			  	}
			  var countE = 0;
			  for (prop in this.CI_formErrors) {
				  countE++;
			  	}
			  	if(countM > 0 || countE > 0){
					return true;
				}
				return false;
			},
			CI_setShippingCountry:function(countryName){
				this.CI_formValues['shipping']['country'] = countryName;
			},
			CI_resetValues:function(set){
				switch(set){
					case 'invoicing':
						this.CI_formValues['invoicing'] = {};
						break;
					case 'message_addressee':
						delete this.CI_formValues['message']['addressee'];
						break;
					case 'message_teamStore':
						delete this.CI_formValues['message']['teamStore'];
						break;
					case 'shipping':
						this.CI_formValues['shipping'] = {};
						break;
					default:
						break;
				}
			}
	};
	CLASS.order = function(){
	};
	CLASS.order.prototype = {
			orderNumber:false,
			cart : {},
			paiement_status:{},
			O_init:function(orderNumber){
				this.orderNumber = orderNumber;
			},
			O_setPaiementStatus:function(paiement, status){
				this.paiement_status[paiement] = status;
			},
			O_save:function(){
				var cart = {
					'productList':this.productList, 
					'shippingCost':this.shippingCost, 
					'qte':this.qte, 
					'amount':this.amount, 
					'totalAmount':this.totalAmount,
					'shippingCode':this.shippingCode
				};
				var order ={'orderNumber':this.orderNumber};
				$.post('includes/actions.php',{action:'saveOrder', ORDER:order, CART:cart, CI:this.CI_formValues}, function(data){
					//alert('data'+data);
				});
			},
			O_record:function(){
				var cart = {
						'productList':this.productList, 
						'shippingCost':this.shippingCost, 
						'qte':this.qte, 
						'amount':this.amount, 
						'totalAmount':this.totalAmount
					};
					var order ={'orderNumber':this.orderNumber};
				$.post('includes/actions.php', {action:'recordOrder', ORDER:order, CART:cart, CI:this.CI_formValues}, function(){
					//alert('sauvée  !!');
				});
			}
	};
	CLASS.browser = function(){
	};
	CLASS.browser.prototype = {
	};
	CLASS.regExp = function(){
		this.regExpEmpty=/^$/g;// Accepte une chaine vide
		this.regExp8Chars=/^[0-9a-zA-Z]{8,}$/g;// Accepte une chaine d'au moins 8 carctères alphanumeriques (pour un mot de passe par exemple)
		// Expressions régulières de test de type de caractère
		this.regExpAlphanumeric=/[0-9a-zA-Záéíóäëiöúàèììù]+/g;// Accepte une chaine alphanumérique
		this.regExpAlphanumericWithWhitespace=/[0-9a-zA-Z áéíóäëiöúàèììù]+/g;	// Accepte une chaine alphanumérique + ' '
		this.regExpAlphanumericWithWhitespaceWithReturns=/([-();:._,0-9a-zA-Z 'áéíóäëiöúàèììù]+\n*){1,10}/g;	// Accepte une chaine alphanumérique + ' ' + \n \r
		this.regExpAlphabetic=/[a-zA-Z]+/g;// Accepte une chaine alphabétique
		this.regExpNumeric=/[0-9]+/g;// Accepte une chaine numérique
		// Expressions régulières de test de type
		this.regExpInt=/^[0-9]+$/g;	// Accepte une chaine de type 'int'
		this.regExpDouble=/^[-+]?[0-9]+(\.[0-9]+)?$/g;// Accepte une chaine de type 'double'
		this.regExpFloat=/^[-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?$/g;	// Accepte une chaine de type 'float'
		this.regExpTime=/^([01][0-9]|2[0123])\:([012345][0-9])(\:([012345][0-9])(.([0-9]{3})+)?)?$/g;		 // Accepte une chaine de type 'time'. Ex : 12:51 ou 21:45:35.654
		this.regExpFrenchDate=/^(0[1-9]|[12][0-9]|3[01])[\- \/\.](0[1-9]|1[012])[\- \/\.](19|20)\d\d$/g;  // date au format jj/mm/aaaa ou jj-mm-aaaa ou jj mm aaaa ou jj.mm.aaaa avec aaaa compris entre 1900 et 2099.
		this.regExpEnglishDate=/^(19|20)\d\d[\- \/\.](0[1-9]|1[012])[\- \/\.](0[1-9]|[12][0-9]|3[01])$/g; // idem ci-dessus mais format anglais (Ex : aaaa/mm/jj)
		this.regExpBoolean=/^true|false$/g;// Accepte une chaine de type 'boolean'
		// Expressions régulières de test de types administratifs français
		this.regExpCodePostal=/^([A-Z]+[A-Z]?\-)?[0-9]{1,2} ?[0-9]{3}$/g;// Accepte une chaine de type 'code postal'. Ex : F-33370 ou 33 370 ou 33370 ou F-1 370
		this.regExpTelephoneFixe=/^(01|02|03|04|05)[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}$/g;	// Accepte un numero de téléphone de type 'fixe'. Ex : 01.34.12.52.30 ou 0134125230
		this.regExpTelephoneIP=/^(08|09)[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}$/g;	// Accepte un numero de téléphone de type 'fixeIP'. Ex : 09.34.12.52.30 ou 0934125230
		this.regExpTelephonePortable=/^(06|07)[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}$/g;// Accepte un numero de téléphone de type 'portable'.
		this.regExpTelephoneNational=/^(0[1234568])[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}$/g;	// Accepte un numero de téléphone de type 'national' y compris numéros en '08'.
		this.regExpTelephoneInternational=/^(\(\+[0-9]{2}\))[ \.\-]?[0-9][ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{2}$/g;// Accepte un numero de téléphone de type 'international'. Ex : (+33) 1 34 12 52 30
		this.regExpTelephoneInternationalWild=/^[0-9()-. ]{4,20}$/g;// Accepte un numero de téléphone de type 'international'. Ex : (+33) 1 34 12 52 30

		this.regExpNumeroSecuriteSociale=/^[12][ \.\-]?[0-9]{2}[ \.\-]?(0[1-9]|[1][0-2])[ \.\-]?([0-9]{2}|2A|2B)[ \.\-]?[0-9]{3}[ \.\-]?[0-9]{3}[ \.\-]?[0-9]{2}$/g; // Accepte un numero de sécurité sociale franÁais. Ex : 1 85 34 33 354 450 45

		this.regExpTVAIntracommunautaire=/^[A-Z]{2}[ \.\-]?[0-9]{2}[ \.\-]?[0-9]{3}[ \.\-]?[0-9]{3}[ \.\-]?[0-9]{3}$/g;		// Accepte un numero de TVA Intra-communautaire. Ex : FR 02 254 254 254
		this.regExpNumeroSiren=/^[0-9]{3}[ \.\-]?[0-9]{3}[ \.\-]?[0-9]{3}$/g;// Accepte un numero SIREN. Ex : 254 254 254
		this.regExpNumeroSiret=/^[0-9]{3}[ \.\-]?[0-9]{3}[ \.\-]?[0-9]{3}[ \.\-]?[0-9]{5}$/g;					// Accepte un numero SIRET. Ex : 254 254 254 12345
		this.regExpCodeApe=/^[0-9]{2}[ \.\-]?[0-9]{1} ?[a-zA-Z]$/g;							// Accepte un code APE. Ex : 25.4Z

		// Expressions réguliéres de test de types liés à internet

		this.regExpEmailAdress=/^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$/g;										// Accepte une adresse email. Ex : toto@toto.com
		this.regExpIpAdress=/\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/g;	// Accepte une adresse ip. Ex : 192.168.0.1
		this.regExpDomainName=/^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/g;													// Accepte un nom de domaine. Ex : toto.com
		this.regExpUrl=/^(((ht|f)tp(s?))\:\/\/)?(([a-zA-Z0-9]+([@\-\.]?[a-zA-Z0-9]+)*)(\:[a-zA-Z0-9\-\.]+)?@)?(www.|ftp.|[a-zA-Z]+.)?[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,})(\:[0-9]+)?\/?/g;		// Accepte une url ftp, http ou https, avec ou sans login/mot de passe, avec ou sans numero de port. Ex : http://www.toto.com, ftp://toto:toto@ftp.toto.com:21/

		this.regExpHexColor=/^#[0-9A-Fa-f]{6}$/g; // Accepte une couleur hexadécimale
	};
	CLASS.regExp.prototype = {
			// Expressions régulières de test de longueur
			
				//Les deux fonction suivantes servent ‡ identifier si une chaine de caractËre est compatible ou non avec une expression rÈguliËre passÈe en paramËtre
			matchRegularExpression:function(valeur, regularExpression){
					var resultat = valeur.match(regularExpression);
					if(resultat!=null && resultat.length==1) return true;
					else return false;
				},
				doesntMatchRegularExpression:function(valeur, regularExpression){
					if(this.matchRegularExpression(valeur, regularExpression)) return false;
					else return true;
				},
				/*
				les fonctions de contrôle suivantes prennent toutes comme argument la valeur de l'attribut "value" d'un champ de formulaire de type "text" ou "password"
				*/
				isEmpty:function(valeur){
					return this.matchRegularExpression(valeur, this.regExpEmpty);
				},
				isNotEmpty:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpEmpty);
				},
				isNot8CharsLength:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExp8Chars);
				},
				isNotAlphanumeric:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpAlphanumeric);
				},
				isNotAlphanumericWithWhitespace:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpAlphanumericWithWhitespace);
				},
				isNotAlphanumericWithWhitespaceWithReturns:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpAlphanumericWithWhitespaceWithReturns);
				},
				isNotAlphabetic:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpAlphabetic);
				},
				isNotNumeric:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpNumeric);
				},
				isNotInt:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpInt);
				},
				isNotDouble:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpDouble);
				},
				isNotFloat:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpInt);
				},
				isNotBoolean:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpBoolean);
				},
				isNotTime:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpTime);
				},
				isNotDate:function(valeur, mode){
					switch (mode)
					{
						case "fr" : 
							return this.doesntMatchRegularExpression(valeur, this.regExpFrenchDate);
							break;
						case "en" :
							return this.doesntMatchRegularExpression(valeur, this.regExpEnglishDate);
							break;
						default : 
							return this.doesntMatchRegularExpression(valeur, this.regExpFrenchDate);
							break;
					}
				},
				isNotCodePostal:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpCodePostal);
				},
				isNotTelephone:function(valeur, mode){
					switch (mode)
					{
						case "fixe" : 
							return this.doesntMatchRegularExpression(valeur, this.regExpTelephoneFixe);
							break;
						case "port" :
							return this.doesntMatchRegularExpression(valeur, this.regExpTelephonePortable);
							break;
						case "IP" :
							return this.doesntMatchRegularExpression(valeur, this.regExpTelephoneIP);
							break;
						case "nati" :
							return this.doesntMatchRegularExpression(valeur, this.regExpTelephoneNational);
							break;
						case "inte" :
							return this.doesntMatchRegularExpression(valeur, this.regExpTelephoneInternational);
							break;
						case "inteWild" :
							return this.doesntMatchRegularExpression(valeur, this.regExpTelephoneInternationalWild);
							break;
						default : 
							return this.doesntMatchRegularExpression(valeur, this.regExpTelephoneNational);
							break;
					}
				},
				isNotNumeroSecuriteSociale:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpNumeroSecuriteSociale);
				},
				isNotTVAIntracommunautaire:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpTVAIntracommunautaire);
				},
				isNotNumeroSiren:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpNumeroSiren);
				},
				isNotNumeroSiret:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpNumeroSiret);
				},
				isNotCodeApe:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpCodeApe);
				},
				isNotEmailAdress:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpEmailAdress);
				},
				isNotIpAdress:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpIpAdress);
				},
				isNotDomainName:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpDomainName);
				},
				isNotUrl:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpUrl);
				},
				isNotHexColor:function(valeur){
					return this.doesntMatchRegularExpression(valeur, this.regExpHexColor);
				}
	};
	CLASS.htmlCart = function(){
		//this.regExpEmpty=/^$/g;// Accepte une chaine vide
	};
	CLASS.htmlCart.prototype = {
		step:0,
		stepFrom:0,
		HTML_init:function(){
			// initialiser les valeurs cart et CI
			this.HTML_updateProducts();
			this.HMTL_updateShippingCountrySelector();
			this.HTML_updateCI();
			// initialiser les actions sur les boutons +/-
			var _I = this;
			var $_products = $('div.product');
			$_products.each(function(i){
				var id = $(this).attr('id');
				var $btmoins = $(this).find('div.addButtons > img:first');
				var $btplus = $(this).find('div.addButtons > img:last');
				$btmoins.bind('mouseenter', function(){
					$(this).attr('src', 'images/moins-up.png');
				});
				$btmoins.bind('mouseleave', function(){
					$(this).attr('src', 'images/moins.png');
				});
				$btmoins.bind('mousedown', function(){
					$(this).attr('src', 'images/moins-down.png');
				});
				$btmoins.bind('mouseup', function(){
					$(this).attr('src', 'images/moins.png');
				});
				$btmoins.bind('click', {_I: _I}, function(){
					_I.minusOneProduct(id);
					_I.HTML_updateProducts();
				});
				
				$btplus.bind('mouseenter', function(){
					$(this).attr('src', 'images/plus-up.png');
				});
				$btplus.bind('mouseleave', function(){
					$(this).attr('src', 'images/plus.png');
				});
				$btplus.bind('mousedown', function(){
					$(this).attr('src', 'images/plus-down.png');
				});
				$btplus.bind('mouseup', function(){
					$(this).attr('src', 'images/plus.png');
				});
				$btplus.bind('click', {_I: _I}, function(){
					_I.plusOneProduct(id);
					_I.HTML_updateProducts();
				});
			});
			// initialiser Shipping cost (step 1)
			$('div.shipping > select').bind('change', {_I: _I}, function(){
				var shippingCountryCode = this.value;
				var shippingCountryName = $(this);
				var sc = _I.CAT_getShippingCost(shippingCountryCode);
				if (sc == undefined){
					var sc = _I.CAT_getShippingCost('ZZ');
				}
				_I.setShippingCost(sc);
				var countryName = "";
				if (shippingCountryCode != "choose"){
					var countryName = $('.shipping option:selected').text();
				}
				_I.setShippingCode(shippingCountryCode);
				_I.CI_setShippingCountry(countryName);
				_I.HTML_updateProducts();
			});
			// initialiser l'action next
			var $_nSteps = $('div.nextstep');
			$_nSteps.each(function(){
				$(this).bind('click', {_I: _I}, function(){
					_I.HTML_nextStep();
				});
			});
			//initialiser les selecteurs
			$('input[type="checkbox"][name^="options_"]').each(function(i){
				$(this).bind('click', {_I: _I}, function(e){
					var name = $(this).attr('name');
					var split = name.split('_');
					var f = split[0];
					var n = split[1];
					if($(this).attr('checked')){
						$('#'+n).slideDown();
						// sauver l'information
						e.data._I.CI_formValues[f][n] = true;
					}else{
						$('#'+n).slideUp();
						// sauver l'information
						e.data._I.CI_formValues[f][n] = false;
						// effacer les informations saisies
						switch(n){
							case "messageTeamStore":
								e.data._I.CI_resetValues('message_teamStore');
								e.data._I.HTML_resetCI('message_teamStore');
								break;
							case "messageAddressee":
								e.data._I.CI_resetValues('message_addressee');
								e.data._I.HTML_resetCI('message_addressee');
								break;
							case "invoice":
								e.data._I.CI_resetValues('invoicing');
								e.data._I.HTML_resetCI('invoicing');
								break;
							default:
								break;
						}
					}
					
				});
			});
			// etape 3 control
			var $next = $('div.review div.nextButton');
			$next.bind('click', {_I: _I}, function(e){
				e.data._I.HTML_nextStep();
			});
			var $prev = $('div.review div.previousButton');
			$prev.bind('click', {_I: _I}, function(e){
				e.data._I.HTML_previousStep();
			});
			// etape 4 paiement
			var $prev = $('div.paiement div.previousButton');
			$prev.bind('click', {_I: _I}, function(e){
				e.data._I.HTML_previousStep();
			});
			var $paypal =$('img.paiementpaypal');
			var $form = $('form[name=PAYPAL]');
			$paypal.bind('click', {form: $form}, function(e){
				e.data.form.submit();
			});
		},
		HTML_nextStep:function(){
			if(this.HTML_controlStep() == false){
				return false;
			}
			if(this.step < 3){
				this.stepFrom = this.step;
				this.step = this.step + 1;
			}
			this.HTML_setStep(this.step);
			return true;
		},
		HTML_previousStep:function(){
			if(this.step > 0){
				this.stepFrom = this.step;
				this.step = this.step - 1;
			}
			this.HTML_setStep(this.step);
			return true;
		},
		HTML_setStep:function(step){
			var $steps = $('div.steps li');
			$steps.each(function(i){
				if(i == step){
					$(this).removeClass('unselected');
				}else{
					$(this).addClass('unselected');
				}
			});
			this.HTML_hideOldStep();
		},
		HTML_controlStep:function(){
			var message = "";
			var error = false;
			switch(this.step){
				case 0:
					if(this.isOrderEmpty()){
						message = message+"<p>Your shopping cart is empty.</p>";
						error = true;
					}
					if(this.isShippingNotSelected()){
						message = message+"<p>You have not selected the shipping country</p>";
						error = true;
					}
					if (message != ""){
						$('div.recaporder div.recapContent').css('display', 'none');
						$('div.recaporder div.error').html(message);
						$('div.recaporder div.error').fadeIn(500).delay(1500).fadeOut(250, function(){
							$('div.recaporder div.recapContent').fadeIn(250);
						});
					}
					break;
				case 1:
					var $err = $('div.CI div.error');
					var test = $err.css('display');
					if (test == 'block'){
						$err.fadeOut(50);
					}
					if(this.CI_hasFormErrors()){
						error = true;
						this.HTML_setCI_errors();
						// afficher les erreurs
						$err.html('Please check form and correct errors.<br />Some requiered fields are missing or some values are incorrects');
						$err.fadeIn(1000);
					}
					break;
				case 2:
					break;
				case 3:
					break;
				default:
					break;
			}
			if (error){
				return false;
			}
			return true;
		},
		HTML_hideOldStep:function(){
			// handle step transition
			// hide old step
			var _I = this;
			switch(this.stepFrom){
				case 0:
					var $target = $('div.products, div.nextStep');
					this.O_save();
					break;
				case 1:
					var $target = $('div.CI');
					this.O_save();
					break;
				case 2:
					var $target = $('div.review');
					break;
				case 3:
					var $target = $('div.paiement');
					break;
			}
			$target.fadeOut(1000, function(){
				_I.HTML_displayNewStep();
			});
		},
		HTML_displayNewStep:function(){
			// handle step transition
			// hide old step
			var _I = this;
			switch(this.step){
				case 0:
					$('div.products').fadeIn(1000);
					$('div.products').css('display', 'inline-block');
					$('div.nextStep').fadeIn(1000);
					break;
				case 1:
					$('div.CI').css('display', 'inline-block');
					$('div.CI').fadeIn(1000);
					break;
				case 2:
					$('div.review').css('display', 'inline-block');
					this.HTML_updateReview();
					$('div.review').fadeIn(1000);
					break;
				case 3:
					//
					$('div.paiement').css('display', 'inline-block');
					this.HTML_preparePayPal();
					$('div.paiement').fadeIn(1000);
					this.O_record();
					break;
			}
		},
		HTML_updateProducts:function(){
			// mise à jour du panier/récpitulatif commande
			this.calcAmount();
			//mettre à jour le tarif de livraison shippingCost
			this.setShippingCost(this.CAT_getShippingCost(this.shippingCode));
			// calcul du montant total
			this.calcTotalAmount();
			$('#quantity').text(this.qte);
			$('#amount_p').text(this.nbreFormate(this.amount));
			$('#amount_s').text(this.nbreFormate(this.shippingCost));
			$('#amount_t').text(this.nbreFormate(this.totalAmount));
			$_p = $('div.product');
			//Mettre à jour les quantités dans les cases des produits
			for(var productRef in this.productList){
				var q = 0;
				if(this.productInCart(productRef)){
					q = this.productList[productRef];
				}
				$('#'+productRef+' > div.addBox > input').val(q);
			}
			// mettre à jour le champs input shipping country dans le formulaire CI (customer information) (section shipping)
			$(':input[name="shipping_country"]').val(this.CI_formValues['shipping']['country']);
			return;
		},
		HMTL_updateShippingCountrySelector:function(){
			//mettre à jour le selecteur shipping country
			if (this.CI_formValues['shipping']['country'] != undefined){
				var country = this.CI_formValues['shipping']['country'];
				var $list = $('div.products div.shipping select option');
				var instance = this;
				$list.each(function(i){
					var t = $(this).text();
					if(t == country){
						$(this).attr('selected', 'selected');
						instance.shippingCostSelected = true;
						return;
					}
				});
			}
		},
		HTML_resetCI:function(set){
			switch(set){
				case 'invoicing':
					var $t = $('#invoice :input');
					$t.val('');
					$t.removeAttr('checked');
					break;
				case 'message_addressee':
					var $t = $(':input[name="message_addressee"]');
					$t.val('');
					break;
				case 'message_teamStore':
					var $t = $(':input[name="message_teamStore"]');
					$t.val('');
					break;
				case 'shipping':
					this.CI_formValues['shipping'] = {};
					break;
				default:
					break;
			}
		},
		HTML_updateReview:function(){
			// mettre à jour la cimmande
			var $t =$('#review_order div.orderLines');
			var $ul = $('<ul></ul>');
			$t.html('');
			$ul.append('<li class="first"><div class="product">Products</div><div class="qte">Qty</div><div class="rPrice">Price</div></li>');
			for(var p in this.productList){
				var price = this.nbreFormate(this.CAT_getProductPrice(p) * this.productList[p]);
				$ul.append('<li><div class="product">'+this.CAT_getProductName(p)+' ('+this.CAT_getProductDetails(p)+')</div><div class="qte">'+this.productList[p]+'</div><div class="rPrice">'+price+'</div></li>');
			}
			$t.append($ul);
			var $total =$('#review_order div.totalOrder');
			var $products = $('<div class="recapLigne">'+this.qte+' Product(s):</div><div class="recapPrice">'+this.nbreFormate(this.amount)+' '+this.currency+'</div>');
			var $shippingCost = $('<div class="recapLigne">shipping Cost: </div><div class="recapPrice">'+this.nbreFormate(this.shippingCost)+' '+this.currency+'</div>');
			var $totalAmount = $('<div class="recapLigne">Total Amount: </div><div class="recapPrice">'+this.nbreFormate(this.totalAmount)+' '+this.currency+'</div>');
			$total.html('');
			$total.append($products, $shippingCost, $totalAmount);
			// mettre à jour les informations client
			// shipping
			for (var i in this.CI_formValues['shipping']){
				var valu = this.CI_formValues['shipping'][i];
				if(i =='address'){
					valu = valu.replace(/\n/,"<br />");
				}
				$('#review_shipping_'+i).html(valu);
			}
			// Afficher les blocs sélectionnés dans l'étape précédente et mettre à jour les informations
			// Invoices
			var $tI = $('#review_invoice');
			if(!$tI.hasClass('hide')){
				$tI.addClass('hide');
			}
			if(this.CI_formValues['options']['invoice']){
				$tI.removeClass('hide');
				for (var i in this.CI_formValues['invoicing']){
					var valu = this.CI_formValues['invoicing'][i];
					if(i =='address'){
						valu = valu.replace(/\n/,"<br />");	
					}
					$('#review_invoicing_'+i).html(valu);
				}
			}
			// Message addressee
			var $tMA = $('#review_messageAddressee'); 
			if(!$tMA.hasClass('hide')){
				$tMA.addClass('hide');
			}
			if(this.CI_formValues['options']['messageAddressee']){
				$tMA.removeClass('hide');
				var valu = this.CI_formValues['message']['addressee'];
				$('#review_message_addressee').html(valu.replace(/\n/,"<br />"));
			}
			// Message team Store
			var $tMS = $('#review_messageTeamStore');
			if(!$tMS.hasClass('hide')){
				$tMS.addClass('hide');
			}
			if(this.CI_formValues['options']['messageTeamStore']){
				$tMS.removeClass('hide');
				var valu = this.CI_formValues['message']['teamStore'];
				$('#review_message_teamStore').html(valu.replace(/\n/,"<br />"));
			}
			
			// invoice
		},
		HTML_updateCI:function(){
			// mettre à jour les informations du client
			// mettre à jour les informations client
			// shipping
			for (var i in this.CI_formValues['shipping']){
				var valu = this.CI_formValues['shipping'][i];
				var $t = $(':input[name="shipping_'+i+'"]');
				if(i == 'civilite'){
					$t.each(function(i){
						if(valu == $(this).val()){
							$(this).attr('checked', 'checked');
							return false;
						}
					});
				}else{
					$t.val(valu);	
				}
			}
			// message addressee
			if(this.CI_formValues['options']['messageAddressee']){
				var $t = $('#messageAddressee');
				if($t.hasClass('hide')){
					$t.removeClass('hide');
				}
				if(this.CI_formValues['message']['addressee'] != undefined){
					$(':input[name="message_addressee"]').val(this.CI_formValues['message']['addressee']);	
				}
				$(':input[name="options_messageAddressee"]').attr('checked', 'checked');
				$t.css('display', 'block');
			}
			// message team store
			if(this.CI_formValues['options']['messageTeamStore']){
				var $t = $('#messageTeamStore');
				if($t.hasClass('hide')){
					$t.removeClass('hide');
				}
				if(this.CI_formValues['message']['teamStore'] != undefined){
					$(':input[name="message_teamStore"]').val(this.CI_formValues['message']['teamStore']);	
				}
				$(':input[name="options_messageTeamStore"]').attr('checked', 'checked');
				$t.css('display', 'block');
			}
			// invoice 
			if(this.CI_formValues['options']['invoice']){
				var $t = $('#invoice');
				if($t.hasClass('hide')){
					$t.removeClass('hide');
				}
				for (var i in this.CI_formValues['invoicing']){
					var valu = this.CI_formValues['invoicing'][i];
					var $t = $(':input[name="invoicing_'+i+'"]');
					if(i == 'civilite'){
						$t.each(function(i){
							if(valu == $(this).val()){
								$(this).attr('checked', 'checked');
								return false;
							}
						});
					}else{
						$t.val(valu);	
					}
				}
				$(':input[name="options_invoice"]').attr('checked', 'checked');
				$t.css('display', 'block');
			}
		},
		HTML_setCI_errors:function(){
			for(var f in this.CI_formMissingFields){
				for(var e in this.CI_formMissingFields[f]){
					var name = f+'_'+this.CI_formMissingFields[f][e];
					var $t = $(':input[name="'+name+'"]').first();
					if(this.CI_formMissingFields[f][e] == 'civilite'){
						var $target = $(':input[name="'+name+'"]').first().parent('label').parent('div').prev('div');
					}else if (this.CI_formMissingFields[f][e] == 'addressee' || this.CI_formMissingFields[f][e] == 'teamStore'){
						var $target = $(':input[name="'+name+'"]').prevAll('span');
					}else{
						var $target = $(':input[name="'+name+'"]').first().parent('div').prev('div');
					}
					if(!$target.hasClass('formError')){
						$target.addClass('formError');
					}
				}
			}
			for(var name in this.CI_formErrors[f]){
				var $target = $('input[name="'+name+'"]').parent('div').prev('div');
				if(!$target.hasClass('formError')){
					$target.addClass('formError');
				}
			}
		},
		HTML_preparePayPal:function(){
			//var folderPays = {'fr':"francais", 'es':'espagnol', 'en':'anglais'};
			var paypalLC = {'fr':"FR", 'es':'ES', 'en':'GB', 'us':'US'};
			$('form[name=PAYPAL]').html('');
			if(this.paiement_status['PAYPAL'] == 'test'){
				var business = 'aqua_1307387496_biz@e64.net';
				$('form[name=PAYPAL]').attr('action', 'https://www.sandbox.paypal.com/cgi-bin/webscr');
			}else{
				var business = 'info@aquamusique.com';
			}
			$('form[name=PAYPAL]').append('<input type="hidden" name="business" value="'+business+'">');
			$('form[name=PAYPAL]').append('<input type="hidden" name="cmd" value="_cart"> ');
			$('form[name=PAYPAL]').append('<input type="hidden" name="upload" value="1"> ');
			$('form[name=PAYPAL]').append('<input type="hidden" name="lc" value="'+paypalLC['us']+'"> ');
			$('form[name=PAYPAL]').append('<input type="hidden" name="custom" value="'+this.orderNumber+'"> ');
			$('form[name=PAYPAL]').append('<input type="hidden" name="currency_code" value="USD">');
			$('form[name=PAYPAL]').append('<input type="hidden" name="return" value="http://www.underwaterspeaker.com/paiement-accepted.html">');
			$('form[name=PAYPAL]').append('<input type="hidden" name="cancel_return" value="http://www.underwaterspeaker.com/paiement-canceled.html">');
			$('form[name=PAYPAL]').append('<input type="hidden" name="notify_url" value="http://www.underwaterspeaker.com/shop/paiement-paypal-ipn.php">');
			
			// add items to form
			var n = 1;
        	for (var i in this.productList){
        		var pName = this.CAT_getProductName(i)+'('+this.CAT_getProductDetails(i)+')';
        		var pPrice = this.CAT_getProductPrice(i);
        		var pQte = this.productList[i];
        		if (pQte > 0){
        			$('form[name=PAYPAL]').append('<input type="hidden" name="item_name_'+n+'" value="'+pName+'"><input type="hidden" name="amount_'+n+'" value="'+pPrice+'.00"><input type="hidden" name="quantity_'+n+'" value="'+pQte+'">');
        			n = n+1;
        		}
        		
        	}
        	
        	// add shipping tax
        	var shippingCostQuantity = 1;
       		$('form[name=PAYPAL]').append('<input type="hidden" name="item_name_'+n+'" value="Shipping cost"><input type="hidden" name="amount_'+n+'" value="'+this.shippingCost+'.00"><input type="hidden" name="quantity_'+n+'" value="'+shippingCostQuantity+'">');
       		
		},
		nbreFormate:function(num) {
			return this.number_format(num, "2", ".", ",");
			switch(langue){
				case 'FR':
					return this.number_format(num, "2", ",", " ");
					break;
				case 'IT':
				case 'DE':
				case 'ES':
					return this.number_format(num, "2", ",", ".");
					break;
				default:
					return this.number_format(num, "2", ".", ",");
					break;
			}
		 },
		 number_format:function(numberToFormat, dec, sep, sepMill){
			 numberToFormat = numberToFormat.toString();
			 // concernant la partie décimals du nombre 
			 // Si cette partie comporte moins de dec chiffres, elle est complétée avec des zéros 
			 // si elle a plus de dec chiffres, elle n'est pas arrondie et est retournée tel quelle
			var tp = numberToFormat.split(".");
			//return (tp[0] + sep + "000");
			if (tp.length == 1){
				Decimales = "";
				 for (z = 0; z < dec; z++) {
				 	//alert (i);
		  			Decimales += "0";
		  			}
				 var r = this.separeMilliers(numberToFormat, sepMill) +sep+Decimales;
		 		return r;
		 	}else if (tp[1].length < dec){
		 		lf = dec-tp[1].length;
		 		Decimales = tp[1];
				 for (ndeci = tp[1].length; ndeci < dec; ndeci++) {
		  			Decimales += "0";
		  			}
		 		return (this.separeMilliers(tp[0], sepMill) + sep + Decimales);
		 	}else if (tp[1].length >= dec){
			 	//Decimales = tp[1];
			 	return (this.separeMilliers(tp[0], sepMill) + sep + tp[1]);
		 	}
			return (this.separeMilliers(tp[0], sepMill) + sep + Decimales);
		},
		separeMilliers:function(sNombre, separateurMilliers) {
				//alert ('separe Millers ' +sNombre + '/'+separateurMilliers);
				if (sNombre < 999 ){
					return sNombre;
				}
				 var sRetour = "";
				 while (sNombre.length % 3 != 0) {
				 	sNombre = "0"+sNombre;
				 	}
				 for (numlen = 0; numlen < sNombre.length; numlen += 3) {
				 	if (numlen == sNombre.length-1) separateurMilliers = '';
				 		sRetour += sNombre.substr(numlen, 3)+separateurMilliers;
				 	}
				 while (sRetour.substr(0, 1) == "0") {
					 sRetour = sRetour.substr(1);
				 	}
				 return sRetour.substr(0, sRetour.lastIndexOf(separateurMilliers));
		},
		replaceReturn:function(str){
			 var str = str.replace(/\n/,"<br />");
			 return str;
		}
	};
	CLASS.catalog = function(){
		//this.regExpEmpty=/^$/g;// Accepte une chaine vide
		this.catalog = {
				'MOBILE_SHELL_BLUE':Array("Mobile shell underwater speaker", "blue", 239, ""), 
				'MOBILE_SHELL_RED':Array("Mobile shell underwater speaker", "red", 239, ""),
				'MOBILE_SHELL_GREEN':Array("Mobile shell underwater speaker", "green", 239, ""),
				'MOBILE_SHELL_YELLOW':Array("Mobile shell underwater speaker", "yellow", 239, ""),
				'FIXED_UNIT':Array("Fixed unit underwater speaker", "inox", 450, "")
		};
		this.shippingCostTable = {
				'AD':[31,39],'AE':[256,350],'AF':[145,209],'AG':[103,159],'AI':[103,159],'AL':[119,162],'AM':[145,209],'AN':[103,159],'AO':[145,209],'AR':[103,159],'AT':[61,87],'AU':[145,209],'AW':[103,159],'AZ':[145,209],'BA':[119,162],'BB':[103,159],'BD':[145,209],'BE':[61,87],'BF':[256,350],'BG':[119,162],'BH':[256,350],'BI':[145,209],'BJ':[145,209],'BM':[103,159],'BN':[145,209],'BO':[103,159],'BR':[103,159],'BS':[103,159],'BT':[145,209],'BW':[145,209],'BY':[119,162],'BZ':[103,159],'CA':[89,117],'CG':[145,209],'CH':[82,116],'CL':[103,159],'CM':[256,350],'CN':[145,209],'CO':[103,159],'CR':[103,159],'CU':[103,159],'CV':[145,209],'CZ':[119,162],'DE':[61,87],'DJ':[145,209],'DK':[82,116],'DM':[103,159],'DO':[103,159],'DZ':[256,350],'EC':[103,159],'EE':[119,162],'EG':[256,350],'ER':[145,209],'ES':[31,39],'ET':[145,209],'FI':[82,116],'FJ':[145,209],'FM':[145,209],'FR':[62,87],'GA':[256,350],'GB':[61,87],'GD':[103,159],'GE':[145,209],'GF':[145,209],'GH':[145,209],'GI':[31,39],'GM':[145,209],'GN':[145,209],'GP':[103,109],'GR':[61,87],'GT':[103,159],'GU':[145,209],'GW':[145,209],'GY':[103,159],'HK':[119,162],'HN':[103,159],'HR':[119,162],'HT':[103,159],'HU':[119,162],'ID':[119,162],'IE':[82,116],'IL':[145,209],'IN':[145,209],'IQ':[145,209],'IS':[103,159],'IT':[61,87],'JM':[103,159],'JO':[145,209],'JP':[119,162],'KE':[145,209],'KG':[145,209],'KH':[145,209],'KR':[119,162],'KW':[256,350],'KY':[103,159],'KZ':[145,209],'LA':[145,209],'LB':[145,209],'LC':[103,159],'LI':[82,116],'LK':[145,209],'LR':[145,209],'LS':[145,209],'LT':[119,162],'LU':[61,87],'LY':[145,209],'MC':[61,87],'MD':[119,162],'MG':[145,209],'MH':[145,209],'ML':[145,209],'MN':[145,209],'MO':[145,209],'MQ':[103,159],'MR':[145,209],'MS':[103,159],'MT':[82,116],'MU':[145,209],'MV':[145,209],'MW':[145,209],'MX':[89,117],'MY':[119,162],'MZ':[145,209],'NA':[145,209],'NC':[145,209],'NE':[145,209],'NG':[145,209],'NI':[103,159],'NL':[103,159],'NO':[82,116],'NP':[145,209],'NZ':[145,209],'OM':[256,230],'PA':[103,159],'PE':[103,159],'PF':[145,209],'PG':[145,209],'PK':[145,209],'PL':[119,162],'PM':[145,209],'PR':[103,159],'PT':[31,39],'PW':[145,209],'PY':[103,159],'QA':[256,350],'RO':[119,162],'RU':[119,162],'RW':[145,209],'SA':[256,350],'SC':[145,209],'SE':[82,116],'SG':[119,162],'SN':[145,209],'SR':[103,159],'SY':[145,209],'SZ':[145,209],'TC':[82,116],'TG':[145,209],'TH':[119,162],'TN':[256,350],'TR':[82,116],'TW':[119,162],'UA':[119,162],'UG':[145,209],'US':[82,113],'UY':[103,159],'VE':[103,159],'VN':[145,209],'YE':[256,350],'YT':[145,209],'YU':[119,162],'ZA':[256,350],'ZM':[145,209],'ZR':[145,209],'ZW':[145,209],'ZZ':[145,209]
		};
	};
	CLASS.catalog.prototype = {
		CAT_getProductInfos:function(productRef){
			var i = this.catalog[productRef];
			return i;
		},
		CAT_getProductPrice:function(productRef){
			var p = this.catalog[productRef][2];
			return p;
		},
		CAT_getProductName:function(productRef){
			var p = this.catalog[productRef][0];
			return p;
		},
		CAT_getProductDetails:function(productRef){
			var p = this.catalog[productRef][1];
			return p;
		},
		CAT_getShippingCost:function(countryCode){
			if (countryCode == "choose"){
				return 0;
			}
			if (countryCode == ""){
				return 0;
			}
			if(this.qte == 0){
				return 0;
			}
			if(this.qte == 1){
				return this.shippingCostTable[countryCode][0];
			}
			if(this.qte >= 2){
				return this.shippingCostTable[countryCode][1];
			}
		}
	};
	CLASS.formulaire = function(){
	};
	CLASS.formulaire.prototype = {
			/**
			 * @var boolean
			 * if set to true form can be send else fomr must not be sent
			 */
			formCheck:false,
			formMissingFields:{},
			formErrors:{},
			/**
			 * check content of field against its type
			 * @param elt -> instance de jquery de l'élément HTML du formaulaire 
			 * @param type -> type de valeur (voir la liste du switch, qui peut être étendue)
			 * @param value -> valeur de l'élément du formulaire
			 */
			FO_checkFieldType:function(elt, type, value){
				var fieldName = elt[0].name;
				var testExp= new CLASS.regExp();
				var test = true;
				switch(type){
					case'alphanumWSWret':
						test = testExp.matchRegularExpression(value, testExp.regExpAlphanumericWithWhitespaceWithReturns);
						break;
					case'alphanumWS':
						test = testExp.matchRegularExpression(value, testExp.regExpAlphanumericWithWhitespace);
						break;
					case'alphabetic':
						test = testExp.matchRegularExpression(value, testExp.regExpAlphabetic);
						break;
					case'alphanum':
						test = testExp.matchRegularExpression(value, testExp.regExpAlphanumeric);
						break;
					case'email':
						test = testExp.matchRegularExpression(value, testExp.regExpEmailAdress);
						break;
					case'codepostal':
						test = testExp.matchRegularExpression(value, testExp.regExpCodePostal);
						break;
					case'tel':
						test = true;
						var tfixe =testExp.isNotTelephone(value, 'fixe');
						var tip = testExp.isNotTelephone(value, 'IP');
						var tport = testExp.isNotTelephone(value, 'port');
						var tnati = testExp.isNotTelephone(value, 'nati');
						var tinte = testExp.isNotTelephone(value, 'inte');
						var tinteWild = testExp.isNotTelephone(value, 'inteWild');
						if(tfixe & tip & tport & tnati & tinte & tinteWild){
							test = false;
						}
						break;
					case'TVAIntra':
						test = testExp.matchRegularExpression(value, testExp.regExpTVAIntracommunautaire);
						break;
					case'none':
						break;
				}
				delete this.formErrors[fieldName];
				if (test === false){
					this.formErrors[fieldName] = false;
				}
				return test;
			},
			FO_setError:function($target){
				if (!$target.hasClass('formError')){
					$target.addClass('formError');
				}
				return false;
			},
			/** verify if a specific requiered field is missing
			* if missing fields : add fields name in formMissingFileds object
			* @return bool true|false
			*/ 
			checkReqField:function(e){
				if(this.formMissingFields[e] != undefined){
					delete this.formMissingFields[e];
				}
				if(this.formValues[e] == undefined || this.formValues[e] == ""){
					this.formMissingFields[e] = true;
					return false;
				}
				return true;
			},
			/**
			 * check for missing requiered fields
			 * @returns {Boolean} true if some req fields ar missing else false if ok
			 */
			checkReqFields:function(){
				var hasError = false;
				this.formMissingFields = {};
				for (var info in this.formFields){
					if(this.formFields[info][0] == true){
						// champs obligatoire
						if(this.checkReqField(info) === false){
							hasError = true;
						}
						
					}
				}
				return hasError;
			},
			hasNoErrors:function(){
				  var prop;
				  var countM = 0;
				  for (prop in this.formMissingFields) {
					  countM++;
				  	}
				  var countE = 0;
				  for (prop in this.formErrors) {
					  countE++;
				  	}
				  	if(countM > 0 || countE > 0){
						return false;
					}
					return true;
			}
	};
	CLASS.HTML_contact = function(){
	};
	CLASS.HTML_contact.prototype = {
			/**
			 * object Json pour stocker les valeurs du formulaire
			 */
			formValues:{'nom':'', 'prenom':'', 'email':'', 'telephone':'', 'subject':'', 'commentaires':''},
			/**
			 * description des éléments du formulaire avec les attributs obligatoire(true/false) et le type de donnée pour le contrôle
			 */
			formFields:{
				'nom':[true, 'alphanumWS'],
				'prenom':[true, 'alphanumWS'],
				'email':[true, 'email'],
				'telephone':[false, 'tel'],
				'subject':[true, 'alphanumWS'],
				'commentaires':[true, 'alphanumWSWret']
			},
			/**
			 * @param HTML_CONTACT_FORM instanc jQuery du formulaire de contact
			 */
			HTML_CO_init:function(HTML_CONTACT_FORM){
				this.$f = HTML_CONTACT_FORM;
				var instance = this;
				this.$f.bind("submit", {_I:instance}, function(e) {
						var t="";
					  e.data._I.checkReqFields();
					  var test = e.data._I.hasNoErrors();
					  if (test){
						  $.post("includes/actions.php", {action:'contact',data:e.data._I.formValues}, function(data){
							  //alert("yoooo");
							  instance.success(data);
						  }, "text");
					  }
					  return false;
					});
				var $inputstext = this.$f.find('input[type=text]');
				var $inputsCheckbox = this.$f.find('input[type=checkbox]');
				var $inputsRadio = this.$f.find('input[type=radio]');
				var $textareas = this.$f.find('textarea');
				$inputstext.bind('focus', function(){
					var $t = $(this).parent('td').prev('td');
					if($t.hasClass('formError')){
						$t.removeClass('formError');	
					}
				});
				$inputstext.bind('blur', {_I:instance}, function(e){
					var name = $(this).attr('name');
					var cktype = e.data._I.formFields[name][1];
					var val = $(this).val();
					e.data._I.formValues[name] = val;
					if(val !== ""){
						var test = e.data._I.FO_checkFieldType($(this), cktype, val);
						if(test === false){
							var $t = $(this).parent('td').prev('td');
							e.data._I.FO_setError($t);
						}
					}
				});
				$inputstext.bind('keyup', {_I:instance}, function(e) {
					var name = $(this).attr('name');
					e.data._I.formValues[name] = $(this).val();
				});
				$textareas.bind('keyup', {_I:instance}, function(e) {
					var name = $(this).attr('name');
					e.data._I.formValues[name] = $(this).val();
				});
				$textareas.bind('focus', function(){
					var $t = $(this).parent('td').prev('td');
					if($t.hasClass('formError')){
						$t.removeClass('formError');	
					}
				});
				$textareas.bind('blur', {_I:instance}, function(e){
					var name = $(this).attr('name');
					var cktype = e.data._I.formFields[name][1];
					var val = $(this).val();
					e.data._I.formValues[name] = val;
					var test = e.data._I.FO_checkFieldType($(this), cktype, val);
					if(test === false){
						var $t = $(this).parent('td').prev('td');
						e.data._I.FO_setError($t);
					}
				});
			},
			success:function(data){
				switch(data){
					case "success":
						$("#form").slideUp(function(){
							$("#success").slideDown();
						});
						break;
					case "error":
						$("#form").slideUp(function(){
							$("#error").slideDown();
						});
						break;
					default:
						break;
				}
			}
	};
})();

