/** 
	Ajax
	
	@example : 
		var xhr = new Ajax({
			method:'post',
			async : true,
			noCache : true,
			onSuccess : function(xhr) { // on xhr is complete and is OK
				alert(xhr.responseText)
			},
			onError : function(xhr) { // when xhr is complete but not OK
				alert(xhr.responseText)
			},
			onStart : function(xhr) { // before the request is launched, you can modify the XHR
				xhr.method = 'get'; //ceci est un exemple
			},
			data : {
				'var1': 'val1',
				'name' : 'jhon'
			}
		})
		xhr.send();
			
**/

var Ajax = function() { this.initialize.apply(this, arguments);}; //only call the initialize
Ajax.prototype = {
	options : {
		method : 'get',
		url : '',
		async : true,
		noCache : true,
		data : {}
	},
	
	constructor : Ajax,
	initialize : function(options) { //constructor
		var _self = this;
		this.setOptions(options);
		this.xhr = this.getXHR();
		this.xhr.onreadystatechange = function() {
			_self.onReadyStateChange();
		};
	},
	
	onReadyStateChange : function(fromAsync) {
		if(!this.options.async && !fromAsync) {return;} //si mode synchrone, alors cette fonction ne doit pas etre executee
		if (this.xhr.readyState == 4) {/* 4 : etat "complete" */
			if (this.xhr.status == 200) { /* 200 : code HTTP pour OK */
				this.fireEvent('onSuccess');
			} else {
				this.fireEvent('onError');
			}
		}
	},
	
	send : function(data) {
		var o = this.options;
		this.setData(data);
		this.fireEvent('onStart');
		switch(this.options.method.toLowerCase()) {
			case "get":
				var url = this.dataStr.length>0 ? o.url + "?" + this.dataStr : o.url;
				this.xhr.open("GET", this.addNoCache(url), o.async);
				this.xhr.send(null);
				break;
			case "post":
				this.xhr.open("POST", this.addNoCache(o.url), o.async);
				this.xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				this.xhr.send(this.dataStr);
				break;
			default :
				return false;
		}
		if (!o.async) {
			this.onReadyStateChange(true);
		}
	},
	
	
	addData : function(data) {
		var i;
		if (!data) {return;}
		if (typeof data=='string') {
			var dataArr = data.split('&');
			data={};
			for (i=0; i<dataArr.length; i++) {
				var vals = dataArr[i].split('=');
				data[vals[0]] = vals[1];
			}
		}
		for (i in data) {
			if (data[i]!==null) {
				this.options.data[i] = data[i];
			}
		}
	},
	
	setData : function(data) {
		if (typeof data=='string') {
			this.dataStr = data;
		} else {
			this.addData(data);
			var dataArr = [];
			for (var i in this.options.data) {
				if (typeof this.options.data[i]!='function') {
					dataArr.push(i+'='+this.options.data[i]);
				}
			}
			this.dataStr = dataArr.join('&');
		}
	},
	
	addNoCache : function(url) {
		if (this.options.noCache) {
			if (url.indexOf("?")==-1) {
				url+="?";
			} else if (url.charAt(url.length-1)!="&") {
				url+="&";
			}
			url += "nocache"+ parseInt(Math.random()*1000000,10)+ "=" + parseInt(Math.random()*1000000,10);
		}
		return url;
	},
	
	fireEvent : function(event) {
		if (this.options[event] && typeof this.options[event]=='function') {
			this.options[event](this.xhr);
		}
	},
	
	getXHR : function() {
		if(window.XMLHttpRequest) {
			return new XMLHttpRequest();
		} else {
			if(window.ActiveXObject) {
				var x = ['Msxml2', 'Microsoft'];
				for (var i=0; i<x.length; i++) {
					try {
						return new ActiveXObject(x[i]+'.XMLHTTP');
					} catch (e) {}
				}
			}
		}
		return null;
	},
	
	setOptions : function(options) {
		if (!options){return;}
		var savedOpt = this.options;
		this.options = {};
		for (var i in savedOpt) this.options[i] = savedOpt[i];
		for (var i in options) this.options[i] = options[i];
	}
};



/* XMLF : 
	objet de parcours du DOM XML 
	getContent(node) : retourne la valeur du noeud. // gere les values simples ou les CDATA
	xml2obj(node) : retourne un objet depuis le noeud XML passé en parametre
*/
var XMLF = {
	xml2obj : function(node, arrayForcedNodes) {
		var arrayForced = arrayForcedNodes ? new RegExp('\\b(' + arrayForcedNodes.join('|') + ')\\b') : null;
		var x2o = XMLF.xml2obj;
		var obj = {};
		
		var xmlNodes = 0;
		for (var i=0; i<node.childNodes.length; i++) {
			var n = node.childNodes[i];
			var name = n.nodeName;
			if (n.nodeType==1) {
				xmlNodes++;
				if (obj[name]==null) {
					var tmpObj = x2o(n,arrayForcedNodes);
					obj[name] = arrayForced && name.match(arrayForced) ? [tmpObj] : tmpObj;
				} else {
					if(!(obj[name] instanceof Array)) {
						obj[name]=[obj[name]];
					}
					obj[name].push(x2o(n,arrayForcedNodes));
				}
			}
		}
		if (xmlNodes==0) {
			var val = XMLF.getContent(node);
			
			
			if (!val) {
				if (node.attributes.length==0) {
					val = '';
				} else {
					var val = XMLF.getAttributes(node);
				}
			} else if (val.match(/^\s*true|false\s*$/))  {
				val=eval(val);
			}
			return val;
		} else if(node.attributes && node.attributes.length>0) {
				obj.attr = XMLF.getAttributes(node);
		}
		
		return obj
	},
	getContent : function(node) {
		var str = [];
		for (var i=0; i<node.childNodes.length; i++) {
			str.push(node.childNodes[i].nodeValue);
		}
		return str.join('');
	},
	
	getAttributes : function(node) {
		var val = {};
		for (var i=0; i<node.attributes.length; i++) {
			var attr = node.attributes[i];
			val[attr.nodeName] = attr.nodeValue;
		}
		return val;
	}
}



var mobileList = {
	options : {},
	
	mobiles : [], //liste des tous les mobiles ==> liste d'objets Mobiles
	mobilesById : {}, //list des mobiles par leur ID
	
	filterEngagement : '',
	filterOffer : '',
	filters : {
		photo : false,
		mp3 : false,
		design : false,
		simplicite : false,
		promo : false
	},
	allFiltersOff : false,
	xml : null,
	
	init : function() {
		var cm = FW.$('containerMobiles');
		this.containerMobiles = cm.el;
		var _self = this;
		
		// actions
		new Ajax({
			method:'post',
			url : mobileApplication.options.templatesUrl,
			onSuccess :  function(xhr) { // when xhr is complete and is OK
				_self.actionsOnResponse(xhr);
			},
			onError : function(xhr) { // when xhr is complete but not OK
				//alert(xhr.responseText)
			}
		}).send();
	},
	
	actionsOnResponse : function(xhr) {
		this.templates = XMLF.xml2obj(xhr.responseXML).templates;
		this.createContainer();
		this.getMobileTemplate();		
		this.getMobileList();
	},
	
	createContainer:function() {
		this.containerMobiles.innerHTML = this.templates.phoneListeContainer;
	},
	getMobileTemplate:function() {
		this.listMobilesCtn = FW.$('listeMobiles').el;
		this.mobileTemplate = this.templates.phoneListeTemplate;
	},
	getMobileList : function() {
		var _self = this;
		new Ajax({
			method:'post',
			url : mobileApplication.options.mobileListUrl,
			onSuccess :  function(xhr) { // when xhr is complete and is OK
				_self.setMobileListInfos(xhr);
				mobileApplication.checkEngagementSelectors();
				
			},
			onError : function(xhr) { // when xhr is complete but not OK
				//alert(xhr.responseText)
			}
		}).send();
		
	},
	
	setMobileListInfos : function(xhr) {
		this.mobileListStr = xhr.responseText;
		var mobiles = this.mobileListStr.split(/[\r\n]/g);
		
		//traitement des headers, on cree une hashmap ou la cle sera le titre de la colonne et la valeur le numero de la colonne
		var headers = mobiles[0].split('|');
		this.mobileListCols = {};
		for (var i=0; i<headers.length; i++) {
			this.mobileListCols[headers[i].replace(/^'/,'').trim()] = i;
		}
		
		// creation de la liste des mobiles a partir de tableau de mobiles, chaque ligne de tableau devient un objet MobilePhone
		this.mobiles = [];
		for (var i=1; i<mobiles.length; i++) {
			if (/^(.+\|){3,}/.test(mobiles[i])) {
				var line = mobiles[i].split('|');
				
				var mobile = new MobilePhone(this.mobileListCols,line);
				this.mobilesById[mobile.prop.CodeLogipro] = mobile;
				this.mobiles.push(mobile);
			}
		}
		//lancement premiere fiche de details mobiles
		if (mobileApplication.formOffer){
			this.mobiles[0].prop.currentMobilePhone = true;
			detailMobile.show(this, this.mobiles[0].prop.CodeLogipro);
		}
		
		
	},
	
	/* generateMobileList 
		genere la liste des mobiles selon les criteres de filtrage 
	*/
	
	generateMobileList : function() {
		
		this.listMobilesCtn.innerHTML = '';
		var htmlMobileList = [];
		// recuperation des proprietes demandees par le template HTML d'un mobile
		var colsNeeded = this.mobileTemplate.match(/__([a-z0-9\_]+)__/gi);
		
		// on parcoure la liste des mobiles
		for(var i=0; i<this.mobiles.length; i++) {
			var mobile = this.mobiles[i];
			// si le mobile n'est pas filtre on l'affiche
			if (!this.isFiltered(mobile)) {
				var mobileTemplate = this.mobileTemplate;
				for(var j=0; j<colsNeeded.length; j++) {
					var colName = colsNeeded[j].replace(/__/g,'');
					mobileTemplate = mobileTemplate.replace(new RegExp('__' + colName + '__', 'g'), mobile.getProperty(colName));					
				}
				
				htmlMobileList.push(mobileTemplate);
			}
		}
		this.listMobilesCtn.innerHTML = htmlMobileList.join('');
		this.setEvents();
	},
	
	/* isFiltered
		filtre un mobile par rapport à ses criteres et ceux configures sur listeMobile.
		si tous les criteres sont off, alors on le mobile n'est pas filtre.
		
	*/
	isFiltered : function(mobile) {
		if (mobile.prop.simCard) {
			return false;
		}
		if (mobile.getPrice().toString().toUpperCase()=='NC') //si le mobile n'a pas de prix, alors il n'est pas prevu dans l'engagement
			return true;
		if (this.allFiltersOff) { 
			return false;
		}
		for(var i in this.filters) {
			if(this.filters[i]==true && mobile.prop[i]==false)
				return true;
		}
		return false;
	},
	
	setFilter : function(filterName, value) {
		this.allFiltersOff = true;
		this.filters[filterName] = value;
		
		for (var i in this.filters) {
			if(this.filters[i]==true) {
				this.allFiltersOff = false;
				break;
			}
		}
	},
	
	cleanArray : function(array) {
		var aReturn = [];
		for (var i=0; i<array.length; i++) {
			var exists = false;
			for (var j=0; j<aReturn.length; j++) {
				if (aReturn[j]==array[i]) {
					exists = true;
				}
			}
			if (!exists) {
				aReturn.push(array[i]);
			}
		}
		return aReturn;
	},
	
	setEvents : function() {
		var lis = this.listMobilesCtn.getElementsByTagName('li');
		for (var i=0; i<lis.length; i++) {
			var div = FW.$(lis[i]).getElement('div');
			div.addEvent('mouseover', function(block){
				return function() {
					FW.$(block.parentNode).addClass('hover');
				}
			}(div.el));
			div.addEvent('mouseout', function(block){
				return function() {
					FW.$(block.parentNode).removeClass('hover');
				}
			}(div.el));
		}
		
	}
}

/***************
* MobilePhone : 
*	Objet representant un mobile
*	@important :
*	cet objet contiendra 2 objets 
*		prop 	: 	contient tous les attributs lies au mobile.
*					Le nom d'un attribut est le nom de la colonne du tableau (represente par le fichier txt)
*		dynProp :	contient des fonctions ou la cle est la meme que dans le template d'un telephone.
*					la fonction sera executee pour recuperer la bonne valeur. C'est utile quand la propriete 
*					a recuperer est dite "dynamique", comme le prix par exemple.
*		
*	@methods :
*******************/ 
var MobilePhone = function() { this.initialize.apply(this, arguments);}; //only call the initialize
MobilePhone.prototype = {
	dynProp : {
		/* DYN_PRICE :	
				retourne le meilleur prix quand on est en mode tous les mobiles
				et dans le mode ou on connait l'engagement, on ne retourne que le prix concernant l'engagement
		*/
		'DYN_PRICE' : function() { 
			var price = this.getPrice();
			// gestion du des nombres a virgule afin de leur rajouter le 0
			// ex : 29.9 ==>29.90
			if (parseFloat(price)==price && price.toString().match(/^\d+\.\d$/)) //si nombre flottant et qu'il nous manque la partie decimal ne fait que 1 chiffre
				price = price+'0';
			
			// gestion de la taille du prix afin de le faire rentrer dans la boite du prix
			// en fonction du nombre de caracteres, le font-size change, donc pour 0, 1, ou 2, chiffres, c'est 100%, pour 3,4 chiffres c'est 80%, etc
			var fontSizeArr = [100,100,100,100,90,77,77,77];
			var fontSize = fontSizeArr[(price+'').length];
			price = isNaN(price) ? price+'' : price + ' &euro;';
			
			return  '<span style="font-size:' + fontSize + '%;">' + price.replace('.', ',') + '</span>';
		},
		'DYN_MENTIONS' : function() {
			if (this.prop.mentionSpeciales.toUpperCase() != 'NC'){
				var mentions = this.prop.mentionSpeciales.split(',');
				var arr = [];
				mentions.each(function(mention){
					var mentionUrl = mention.split(':')[0];
					var mentionLabel = mention.split(':')[1];
					var html = '<p><img src="' + mentionUrl + '"/><label>' + mentionLabel + '</label></p>';
					arr.push(html)
				})
				return arr.join('');
			}else{
				return ''
			}
			
		},
		/* retourne la bonne classe CSS appliquee sur le LI */
		'DYN_PROMO' : function() {
			return this.prop.promo ? 'promo' : '';
		},
		'DYN_URL_PHONE' : function() {
			return mobileApplication.formOffer ? 'phones/phonesSmall' : 'phones';
			//return (this.prop.Marque+'-'+this.prop.Libelle).replace(/\s/g,'-');
		},
		'DYN_CURRENT' : function() {
			return this.prop.currentMobilePhone ? 'current' : '';
		},
		'DYN_OFFRESPECIALE' : function() {
			return this.prop.offreSpeciale ? 'offreSpeciale' : '';
		},
		'DYN_NOUVEAUTE' : function() {
			return this.prop.nouveaute ? 'nouveaute' : '';
		},
		'DYN_MOBILEID' : function() {
			return this.prop['CodeLogipro'];
		},
		'DYN_SIMCARD' : function() {
			return this.prop.simCard ? 'simCard' : '';
		},
		'DYN_ACTION_CLICK' : function() {
			if (mobileApplication.formOffer){
				return 'onclick="detailMobile.show(this, \'' + this.prop.CodeLogipro + '\')"';
			}else{
				return '';
			}
		}
	},
	
	constructor : MobilePhone,
	initialize : function(propNames, arrayProp) { //constructor
		this.prop = {};
		for (var i in propNames) {
			if (propNames[i]<arrayProp.length) {
				var val = arrayProp[propNames[i]];
				if (val.match(/^true|false$/)) { //si on est en presence d'un booleen, on transforme la chaine en booleen
					this.prop[i] = eval(val);
				} else if(/^prix/i.test(i)) { //si colonne de prix, on gere la valeur comme un prix 'NC' ou un flottant
					var price = val.match(/^(NC|[0-9,.]+)/g);
					if (!price) price == 'NC';
					var price = price[0].match(/NC/) ? 'NC' : parseFloat(price[0].replace(/\,/g, '.'),10);
					this.prop[i] = price;
				} else { // on ne fait rien
					this.prop[i] = val;
				}
			}
		}
	},
	
	getProperty : function(propName) {
		if (this.prop[propName]!=null) {
			return this.prop[propName];
		} else if(this.dynProp[propName]!=null) {
			return this.dynProp[propName].apply(this);
		} else {
			return '';
		}
	},
	
	getPrice : function() {
		var price = 0;
		var pricesProp = ['Prix process TTC','Prix 12 TTC','Prix 24 TTC'];

		
		//gestion offre
		if (mobileList.filterOffer){
			price = this.prop['offre' + mobileList.filterOffer[0] + mobileList.filterOffer[1] + 'Mois'];
		}else{
			switch(mobileList.filterEngagement) {
				case 'sans' : 
					price = this.prop['Prix process TTC'];
					break;
				case 'carterecharge' : 
					price = this.prop['Prix process TTC'];
					break;
				case '12' : 
					price = this.prop['Prix 12 TTC'];
					break;
				case '24' : 
					price = this.prop['Prix 24 TTC'];
					break;


				// on est en mode ou on choisi un mobile sans connaitre aucun forfait, donc on affiche le prix le plus petit
				// on doit connaitre a l'avance le nom des colonnes des prix. Seuls les prix TTC sont conserves
				default :
					for(var i=0; i<pricesProp.length; i++) {
						var propName = pricesProp[i];
						if(this.prop[propName] && !isNaN(this.prop[propName])) {
							var val = this.prop[propName];
							if (price==0 || val<price) price=val;
						}
					}
			}
		}
		
		
		
		return price;
	}
	
}


/* fixImageMobile
	fonction executee depuis le onerror des images, cela permet de gerer les erreurs 404 sur les images des mobiles
 */
function fixImageMobile(img) {
	img.parentNode.className+=' noImg';
	img.parentNode.innerHTML = 'Photo Indisponible';
}


/* fiche mobile : objet contenant toutes les fonctions appel et generation de la fiche mobile */
var ficheMobile = {
	prop : {}, //proprietes du mobile recuperees depuis le XML
	dynProp : { //proprietes dynamiques qui permettent de retourer les bonnes valeurs quand plusieurs criteres rentrent en compte
		'DYN_PROMO' : function() {
			return this.prop.promo ? 'promo' : '';
		},
		'DYN_NOUVEAUTE' : function() {
			return this.prop.nouveaute ? 'nouveaute' : '';
		},
		'DYN_OFFRESPECIALE' : function() {
			return this.prop.offreSpeciale ? 'offreSpeciale' : '';
		},
		'DYN_CARACTERISTIQUES' : function() {
			var listCarac = [];
			
			this.prop.caracteristiques.caracteristique.each(function(carac, i) {
				listCarac.push('<li class="subSwap'+ (i%2==0 ? ' even' : '') +'"><a href="#" class="swapContent">'+carac.attr.title+'</a><ul class="contentSwapped">');
				carac.prop.each(function(prop) {
					listCarac.push('<li>'+prop.value+'</li>');
				});
				listCarac.push('</ul></li>');
			});
			return listCarac.join('');
		},
		'DYN_MENTIONS' : function(){
			var listMention = [];
			this.prop.mentionSpeciales.mention.each(function(mention){
				var elm = '<li><img src="/images/pictos/' + mention.url + '" alt="' + mention.label + '" /><label>' + mention.label + '</label></li>';
				listMention.push(elm);
			})
			return listMention.join('');
		} /*,
		'DYN_VISUELS' : function(){
			var visuelsToDisplay = [];
			var listeVisuels = [];
			this.prop.visuels.visuel.each(function(visuel){
				if (eval(visuel.current)){
					var img = '<img id="visuelAgrandi" alt="' + visuel.desc + '" src="/images/phones/' + visuel.url + '"/>';
					visuelsToDisplay.push(img);
				}
				var classTOUse = visuel.current ? 'current' : '';
				var miniImg = '<li class=' + classTOUse +'><a onmouseover="simpleImgChangePath(this);return false;" rel="' + visuel.url + '" href="#" title="' + visuel.desc + '"><img alt="' + visuel.desc + '" src="/images/phones/mini/' + visuel.miniUrl + '"/></a></li>';
				listeVisuels.push(miniImg);
			})
			visuelsToDisplay.push('<ul class="mobilePicker">');
			listeVisuels.push('</ul>');
			visuelsToDisplay.push(listeVisuels.join(''));
			return visuelsToDisplay.join('');
		}*/
	},
	show: function(link, mobileId) {
		var _self = this;
		this.mobileFicheTemplate = mobileList.templates.phoneCardTemplate;
		
		// ouverture du layer avec un loader 
		$layer.open({
			content : '<div id="layerInfoMobileContent" class="load"></div>', //div affichant un petit loader ajax
			mask:true,
			closingWording : ''
		})
		
		new Ajax({
			url : mobileApplication.options.mobileInformationsUrl,
			onSuccess : function(xhr) {
				_self.prop = XMLF.xml2obj(xhr.responseXML, ['spec','idas','accessibilite','mention','forfait','caracteristique','prop']).mobile;
				_self.generate();
				FW.$('layerInfoMobileContent').removeClass('load');
			}
		}).send({logipro:mobileId});
	},
	
	generate : function() {	
		var d = new Date().getTime();
		var _self = this;
		var ficheTemplate = this.mobileFicheTemplate.replace(/[\r\n\s]+/g,' ');
		/* for statements */
		var forLoops = ficheTemplate.match(/\{\%for.*%}.*{%forend%\}/gi);
		
		if (forLoops) {
			forLoops = forLoops.join('').split('{%forend%}');
			forLoops.each(function(forLoop) {
				forLoop += '{%forend%}';
				var re = forLoop.match(/\{\%for\s+(.+)\s+in\s+(.*)\%\}\s*(.*)\s*\{%forend%\}/i);
				
				if (re) {
					var forLoopMatch = re[0];
					var key = re[1];
					var property= re[2];
					var repeatStr = re[3];
					key = key.trim();
					property = property.trim();
					var oddEvenMatches = repeatStr.match(/\{\$oddeven\?[\w\s]*\|[\w\s]*\$\}/gi);
					
				
					var out = [];
					var matches = repeatStr.match( new RegExp('\\{\\{('+key+ '|'+property.replace(/\./g,'\\.')+'.'+key+'(\\.[a-z0-9-\s_]+)?)\\}\\}','gi'));
					
					
					
					if (matches) {
						var propertyObj = eval('_self.prop.' + property);
						
						var count = 0;
						for (var subProp in propertyObj) {
							if (typeof propertyObj[subProp]!='function') {
								
								var str = repeatStr;
								matches.each(function(theMatch) {
									matchRe = new RegExp(theMatch.replace(/([\{\}\.])/g,'\\$1'));
									
									if(theMatch.match(new RegExp('\\{\\{'+property.replace(/\./g,'\\.')+'\\.'+key+'\\.(.+)\\}\\}','gi'))) {
										var m = RegExp.$1.trim();
										str = str.replace(matchRe,propertyObj[subProp][m]);
									} else {
										if (theMatch.match(new RegExp('\\{\\{'+property.replace(/\./g,'\\.')+'\\.'+key+'\\}\\}','gi'))) {
											str = str.replace(matchRe,propertyObj[subProp]);
										} else {
											str = str.replace(matchRe,subProp);
										}
									}
								});
								if (oddEvenMatches)
									oddEvenMatches.each(function(oddeven) {
										oddeven.match(/\{\$oddeven\?([\w\s]*)\|([\w\s]*)\$\}/gi)
										var odd = RegExp.$1;
										var even = RegExp.$2;
										
										str = str.replace(RegExp.lastMatch, count%2?even:odd);
										
									});
									
								out.push(str);
								count++;
							}
							
						}
					}
					ficheTemplate = ficheTemplate.replace(forLoopMatch, out.join(''));
				}
			});
		}
		
		/* singles properties */
		var propsNeeded = this.mobileFicheTemplate.match(/__([a-z0-9\_]+)__/gi);
		propsNeeded.each(function(prop) {
			ficheTemplate = ficheTemplate.replace(new RegExp(prop,'g'), _self.getProperty(prop.replace(/__/g,'')));
		});
		/* injection template */
		FW.$('layerInfoMobileContent').el.innerHTML = ficheTemplate;
		
		/* addEvents et autres data, ici on peut reutiliser le FW.initializer, et gerer les actions/events comme modules */
		FW.initializer.launch(FW.$('layerInfoMobileContent').el);
	},

	getProperty : function(propName){
		if (this.prop[propName]!=null){
			return this.prop[propName];
		} else if(this.dynProp[propName]!=null) {
			return this.dynProp[propName].apply(this);
		} else {
			return '';
		}
	}
}


/* detail mobile : objet contenant toutes les fonctions appel et generation des details mobile */
var detailMobile = {
	prop : {}, //proprietes du mobile recuperees depuis le XML
	dynProp : { //proprietes dynamiques qui permettent de retourer les bonnes valeurs quand plusieurs criteres rentrent en compte
		'DYN_MOBILEID' : function() {
			return this.prop['id'];
		},
		'DYN_PRICE' : function() {
			return mobileList.mobilesById[this.currentMobile].getPrice();
		}
	},
	refreshPrice: function(){
		if (FW.$('monPrix').el) FW.$('monPrix').el.innerHTML = mobileList.mobilesById[this.currentMobile].getPrice();
	},
	show: function(link, mobileId) {
		var _self = this;

		this.currentMobile = mobileId;
		
		if(link.tagName == 'LI'){
			this.currentStatus = link.className.match(/\bcurrent\b/) ? true : false;
		}
		
		if (!mobileApplication.formOffer || this.currentStatus) return;
		
		
		this.detailFicheTemplate = mobileList.templates.phoneDetailTemplate;
		FW.$('detailMobile').addClass('load');
		
		new Ajax({
			url : mobileApplication.options.mobileInformationsUrl,
			onSuccess : function(xhr) {
				_self.prop = XMLF.xml2obj(xhr.responseXML, ['spec','idas','accessibilite','mention','forfait','caracteristique','prop']).mobile;
				_self.generate();
				
			}
		}).send({logipro:mobileId});

		for (i in mobileList.mobilesById) {
			if (mobileList.mobilesById[i].prop.currentMobilePhone){
				mobileList.mobilesById[i].prop.currentMobilePhone = false;
				switchOffPhoneStatusCurrent(i);
			}
		}
		mobileList.mobilesById[mobileId].prop.currentMobilePhone = true;
		switchOnPhoneStatusCurrent(mobileId);
	},
	
	generate : function() {	
		var d = new Date().getTime();
		var _self = this;
		var detailTemplate = this.detailFicheTemplate.replace(/[\r\n\s]+/g,' ');
		/* for statements */
		var forLoops = detailTemplate.match(/\{\%for.*%}.*{%forend%\}/gi);
		
		if (forLoops) {
			forLoops = forLoops.join('').split('{%forend%}');
			forLoops.each(function(forLoop) {
				forLoop += '{%forend%}';
				var re = forLoop.match(/\{\%for\s+(.+)\s+in\s+(.*)\%\}\s*(.*)\s*\{%forend%\}/i);
				
				if (re) {
					var forLoopMatch = re[0];
					var key = re[1];
					var property= re[2];
					var repeatStr = re[3];
					key = key.trim();
					property = property.trim();
					var oddEvenMatches = repeatStr.match(/\{\$oddeven\?[\w\s]*\|[\w\s]*\$\}/gi);
					
				
					var out = [];
					var matches = repeatStr.match( new RegExp('\\{\\{('+key+ '|'+property.replace(/\./g,'\\.')+'.'+key+'(\\.[a-z0-9-\s_]+)?)\\}\\}','gi'));
					
					
					
					if (matches) {
						var propertyObj = eval('_self.prop.' + property);
						
						var count = 0;
						for (var subProp in propertyObj) {
							if (typeof propertyObj[subProp]!='function') {
								
								var str = repeatStr;
								matches.each(function(theMatch) {
									matchRe = new RegExp(theMatch.replace(/([\{\}\.])/g,'\\$1'));
									
									if(theMatch.match(new RegExp('\\{\\{'+property.replace(/\./g,'\\.')+'\\.'+key+'\\.(.+)\\}\\}','gi'))) {
										var m = RegExp.$1.trim();
										str = str.replace(matchRe,propertyObj[subProp][m]);
									} else {
										if (theMatch.match(new RegExp('\\{\\{'+property.replace(/\./g,'\\.')+'\\.'+key+'\\}\\}','gi'))) {
											str = str.replace(matchRe,propertyObj[subProp]);
										} else {
											str = str.replace(matchRe,subProp);
										}
									}
								});
								if (oddEvenMatches)
									oddEvenMatches.each(function(oddeven) {
										oddeven.match(/\{\$oddeven\?([\w\s]*)\|([\w\s]*)\$\}/gi)
										var odd = RegExp.$1;
										var even = RegExp.$2;
										
										str = str.replace(RegExp.lastMatch, count%2?even:odd);
										
									});
									
								out.push(str);
								count++;
							}
							
						}
					}
					detailTemplate = detailTemplate.replace(forLoopMatch, out.join(''));
				}
			});
		}
		
		/* singles properties */
		var propsNeeded = this.detailFicheTemplate.match(/__([a-z0-9\_]+)__/gi);
		propsNeeded.each(function(prop) {
			detailTemplate = detailTemplate.replace(new RegExp(prop,'g'), _self.getProperty(prop.replace(/__/g,'')));
		});
		FW.$('detailMobile').removeClass('load');
		/* injection template */
		FW.$('detailMobile').el.innerHTML = detailTemplate;
				
	},

	getProperty : function(propName){
		if (this.prop[propName]!=null){
			return this.prop[propName];
		} else if(this.dynProp[propName]!=null) {
			return this.dynProp[propName].apply(this);
		} else {
			return '';
		}
	}
}



var mobileApplication = {
	options : {
		templatesUrl : 'ajax/templates.xml',
		mobileListUrl : 'ajax/param_mobile.txt',
		mobileInformationsUrl : 'ajax/ficheMobile.xml' //en prod cela correspond a : popup.asp
	},

	formEngagement : null,
	formOffer : null,
	init : function() {
		this.initTopFilterBar();
		this.formEngagement = FW.$('formEngagement').el;
		this.formOffer = FW.$('formOffer').el;
		
		this.initEngagementSelectors();
		this.initOfferSelectors();
		
		
		
		
		mobileList.init(); 
		//la methode mobileList.init() fait des appels ajax, et sur le dernier appel (chargement liste mobiles), 
		// sur success de la requete, la fonction mobileApplication.checkEngagementSelectors() est appelée
		
		
	},
	
	initTopFilterBar : function() {
		FW.$('topFilterBar').getElements({nodeName:'li'}).each(function(li) {
			// on applique une action seulement sur les LI qui ont la classe filter_XXXXXXXX
			if (li.className.match(/\bfilter_([a-z0-9]+)\b/i)) {
				// on recupere ce XXXX qui correspond au critere auquel se rapporte le filtre.
				// ce critere etant automatiquement lie au mobile depuis le nom des colonnes du fichier TXT
				li.workingFilter = RegExp.$1; 
				li.filterSelected = false; // le LI n'est pas selectionne par defaut
				FW.$(li).addEvent('click', function(e) { //action sur le LI
					FW.event.stop(e); 
					li.filterSelected = !li.filterSelected; //changement de l'etat
					li.filterSelected ? 
						FW.$(li).addClass('selected') : 
						FW.$(li).removeClass('selected');
							
					mobileList.setFilter(li.workingFilter, li.filterSelected);
					mobileList.generateMobileList();
				});
			}
		})
	},
	
	initOfferSelectors : function() {
		var _self = this;
		if (!this.formOffer) return;
		['field_offer45min','field_offer60min','field_offer120min'].each(function(id) {
			
			var offerMin = id.split('offer')[1];
			var offerMonths = FW.$(id + 'Engagement').el.value;
			//initial launch
			if (FW.$(id).el.checked){
				mobileList.filterOffer = [offerMin, offerMonths];
			}
			//ajout evenements
			FW.$(id).addEvent('click',function(){
				var offerMin = id.split('offer')[1];
				var offerMonths = FW.$(id + 'Engagement').el.value;
				mobileList.filterOffer = [offerMin, offerMonths];
				mobileList.generateMobileList();
				detailMobile.refreshPrice();
			})
			FW.$(id + 'Engagement').addEvent('change', function(){
				var offerMin = id.split('offer')[1];
				FW.$(id).el.checked = true;
				var offerMonths = FW.$(id + 'Engagement').el.value;
				mobileList.filterOffer = [offerMin, offerMonths];
				mobileList.generateMobileList();
				detailMobile.refreshPrice();
			})	
		});
	},
	initEngagementSelectors : function() {
		var _self = this;
		if (!this.formEngagement) return;
		FW.$('field_typeForfait').el.onchange = function() {
			if(this.value=='') return;
			_self.setEngagementValueFromSelect(this.value);
			mobileList.generateMobileList();
		};
		['field_engagement12mois','field_engagement24mois'].each(function(id) {
			FW.$(id).el.onclick = function() {
				_self.setEngagementValueFromCheckBox(this.value);
				mobileList.generateMobileList();
			};
		});
	},
	
	setEngagementValueFromSelect : function(value) {
		if (this.formEngagement) {
			if(value=='sansengagement' || value=="carterecharge") { /* la carte recharge et le terme sans engagement entraine la meme gestion derriere */
				mobileList.filterEngagement = 'sans';
				FW.$('checkboxes_engagement').el.style.display = 'none';
				return true;
			} else {
				FW.$('checkboxes_engagement').el.style.display = '';
				if(FW.$('field_engagement12mois').el.checked)
					mobileList.filterEngagement = '12';
				if(FW.$('field_engagement24mois').el.checked)
					mobileList.filterEngagement = '24';
				return false	
			}
		} else {
			mobileList.filterEngagement = '';
		}
		
	},
	
	setEngagementValueFromCheckBox : function(value) {
		mobileList.filterEngagement = value;
	},
	
	checkEngagementSelectors : function() {
		var _self = this;
		if (FW.$('formEngagement').el) {
			if (!this.setEngagementValueFromSelect(FW.$('field_typeForfait').el.value)) {
				['field_engagement12mois','field_engagement24mois'].each(function(id) {
					if (FW.$(id).el.checked) 
						_self.setEngagementValueFromCheckBox(FW.$(id).el.value);
				});
			}
		} else {
			mobileList.filterEngagement = '';
		}
		mobileList.generateMobileList();
	}
}
/*
//fonction permettant de modifier le mobile dans la fiche produit
function simpleImgChangePath(a){
	var url = a.rel;
	var alt = a.title;
	var imgToChange = FW.$('ficheMobile_visuelAgrandi').el;
	//TODO changer ici le répertoire pour utilisation du caching
	imgToChange.src = '/fiche_mobile/layer/' + url;
	imgToChange.alt = alt;
	
	//swapClass
	FW.$(a.parentNode.parentNode).getElements('li').each(function(li){
		li.className ='';
	})
	a.parentNode.className = 'current';
}*/


//fonction permetaatn de modifier le statut current d'un telephone
function switchOnPhoneStatusCurrent(elm){
	var oLis = FW.$('listeMobiles').getElements('li');
	if (oLis.length > 0){
		oLis.each(function(li){
			if (li.getAttribute('phonenumber') == elm){
				FW.$(li).addClass('current');
			}
		})
	}

}
//fonction permetaatn de modifier le statut current d'un telephone
function switchOffPhoneStatusCurrent(elm){
	var oLis = FW.$('listeMobiles').getElements('li');
	if (oLis.length > 0){
		oLis.each(function(li){
			if (li.getAttribute('phonenumber') == elm){
				FW.$(li).removeClass('current');
			}
		})
	}

}



if (!window.console) {
	window.console = {
		log : function() {},
		dir : function() {}
	}
}



