

/**
 * Contrairement au moteur meh, on préfère créer 2 contexte (un pour la page de formulaire et un pour la page de résultat)
 * Cela évite de charger des js inutiles dans la page de formulaire. Chacun son contexte!
 */
(function() {
	var WIN = this,
			EASY = WIN.ev,
			ev=WIN.ev,
			window=this;

	// Si les namespaces/classes nécessaires ne sont pas chargées : exception
	if (!EASY) {throw new Error("Le namespace 'ev' doit exister");}
	// On s'assure que le namespace EASY.mev existe
	if (!EASY.mev) { EASY.mev = {}; }
	//Si la classe Context est définie on sort
	if (EASY.mev.Criteres) {return;}

	/**
	 * Expression régulière représentant une clé de
	 * critères.<br>
	 * 9 groupes :
	 *  - type de parcours (0-AS, 1-AR, 2-PC)
	 *  - code IATA ville départ (aller)
	 *  - code IATA ville arrivée (aller)
	 *  - date aller
	 *  - [optionel] code IATA ville départ (retour)
	 *  - [optionel] code IATA ville arrivée (retour)
	 *  - [optionel] date retour
	 *  - pax (adultes, enfants, bébés)
	 *  - classe voyageur (0-IND, 1-ECO, 2-AFF, 3-PRE)
	 */

	var REGEXP_CRITERES_UKEY = /([0-2])([A-Z]{3})([A-Z]{3})([0-9]{8}),([A-Z]{3})?([A-Z]{3})?([0-9]{8})?,([0-9]+,[0-9]+,[0-9]+),([0-3])/,

			/**
	 * Expression régulière représentant une date au
	 * format yyyyMMdd.<br>
	 * 3 groupes :
	 *  - year (4 chiffres)
	 *  - month (2 chiffres)
	 *  - day (2 chiffres)
	 */
			REGEXP_DATE = /([0-9]{4})([0-9]{2})([0-9]{2})/,

			/**
	 * Expression régulière représentant les pax
	 * adultes, enfants et bébés.<br>
	 * 3 groupes :
	 *  - pax adultes
	 *  - pax enfants
	 *  - pax bébés
	 */
			REGEXP_PAX = /([0-9]+),([0-9]+),([0-9]+)/,

			/**
	 * Expression régulière représentant un champ
	 * 'data'.<br>
	 * 3 groupes :
	 *  - id de la ville ou de l'aéroport
	 *  - code IATA de la ville ou de l'aéroport
	 *  - nom de la ville ou de l'aéroport
	 */
			REGEXP_DATA = /^[av]:([0-9]*)\|c:([A-Z]*)\|t:(.*)$/i;
	/**
	 * Extrait le champ texte du parametre data
	 * @param {string} data chaine de caractère contenant le champs data d'un lieu.
	 * @return {string} le champ text de data ou null si non trouvé.
	 */
	function getTextFromData(data) {
		if (data && REGEXP_DATA.test(data)) {
			return RegExp.$3;
		}
		return null;
	}
	/**
	 * Extrait le champ code du parametre data
	 * @param {string} data chaine de caractère contenant le champs data du lieu.
	 * @return {string||null}le champ code de data ou null si non trouvé.
	 */
	function getIataFromData(data) {
		if (data && REGEXP_DATA.test(data)) {
			return RegExp.$2;
		}
		return null;
	}

	/**
	 * Extrait le champ id du parametre data
	 * @param {string} data chaine de carractère contenant le champs data du lieu.
	 * @return {string} le champ id de data ou null si non trouvé.
	 */
	function getIdFromData(data) {
		if (data && REGEXP_DATA.test(data)) {
			return RegExp.$1;
		}
		return null;
	}

	/**
	 *
	 * @param {Object} params Objet contenant les critères de recherche.
	 */
	EASY.mev.Criteres = function(params) {
		this.ukey = null;
		this.type = null;
		this.departAller = null;
		this.dataDepartAller = null;
		this.dataDepartAller2 = null;
		this.arriveeAller = null;
		this.dataArriveeAller = null;
		this.dataArriveeAller2 = null;
		this.dateAller = null;
		this.dataDepartRetour = null;
		this.departRetour = null;
		this.dataArriveeRetour = null;
		this.arriveeRetour = null;
		this.dateRetour = null;
		this.paxAdultes = null;
		this.paxEnfants = null;
		this.paxBebes = null;
		this.classe = null;
		this.isBuzzCompatible = null;


		if (params) {
			this.ukey = params.ukey || null;
			this.type = params.type || null;
			this.departAller = params.departAller || null;
			this.dataDepartAller = params.dataDepartAller || null;
			this.dataDepartAller2 = params.dataDepartAller2 || null;
			this.arriveeAller = params.arriveeAller || null;
			this.dataArriveeAller = params.dataArriveeAller || null;
			this.dataArriveeAller2 = params.dataArriveeAller2 || null;

			this.dateAller = params.dateAller || null;

			this.dataDepartRetour = params.dataDepartRetour || null;
			this.departRetour = params.departRetour || null;
			this.dataArriveeRetour = params.dataArriveeRetour || null;
			this.arriveeRetour = params.arriveeRetour || null;


			this.dateRetour = params.dateRetour || null;


			this.paxAdultes = params.paxAdultes || null;
			this.paxEnfants = params.paxEnfants || null;
			this.paxBebes = params.paxBebes || null;
			this.classe = params.classe || null;
			this.isBuzzCompatible = params.isBuzzCompatible || null;
		}

		/**
		 * Initialise les critères à partir d'une
		 * clé unique.
		 * @param {String} ukey clé unique à interpréter.
		 */
		this.initFromUniqueKey = function(ukey) {

			if (!REGEXP_CRITERES_UKEY.test(ukey)) {
				EASY.log.warn('EASY.mev.Criteres#initFromUniqueKey()> Clé de critères indéchiffrable : ' + ukey);
				return null;
			}
			var tp = RegExp.$1, // type de parcours : 0-AS, 1-AR, 2-PC
					cda = RegExp.$2, // code IATA ville départ (aller)
					caa = RegExp.$3, // code IATA ville arrivée (aller)
					da = RegExp.$4, // date aller
					cdr = RegExp.$5, // [OPTIONEL] code IATA ville départ (retour)
					car = RegExp.$6, // [OPTIONEL] code IATA ville arrivée (retour)
					dr = RegExp.$7, // [OPTIONEL] date retour
					px = RegExp.$8, // pax (adultes, enfants, bébés)
					cls = RegExp.$9, // classe voyageur (0-IND, 1-ECO, 2-AFF, 3-PRE)
					// différents pax
					pa = 1,
					pe = 0,
					pb = 0;
			//extraction des dates
			if (REGEXP_DATE.test(da)) {
				da = da.replace(REGEXP_DATE, '$3/$2/$1');
			}
			if (REGEXP_DATE.test(dr)) {
				dr = dr.replace(REGEXP_DATE, '$3/$2/$1');
			}
			// extraction des pax
			if (REGEXP_PAX.test(px)) {
				pa = RegExp.$1;
				pe = RegExp.$2;
				pb = RegExp.$3;
			}
			// enregistrement des critères
			this.ukey = ukey;
			this.type = tp;
			this.departAller = cda;
			this.arriveeAller = caa;
			this.dateAller = da;
			this.departRetour = cdr;
			this.arriveeRetour = car;
			this.dateRetour = dr;
			this.paxAdultes = pa;
			this.paxEnfants = pe;
			this.paxBebes = pb;
			this.classe = cls;
			return this;
		};

		/**
		 * Permet de copier les propriétés de l'objet
		 * critères donné vers l'objet courant.
		 * @param {object }c Object critère avec lequel  il faut synchronisé.
		 */
		this.updateFrom = function(c) {
			EASY.tools.copy(this, c);
		};

		/**
		 * Permet de savoir si le jeu de critères est correct
		 * ('true') ou pas encore initialisé ('false').
		 */
		this.isSet = function() {
			return this.ukey !== null;
		};

		/***
		 * Génération de la la liste des paramètres pour l'interrogation d'une page de résultat MEV2.
		 *  * http://www.easyvols.org/rue89/mev/results.jsp?
		 * clientId=1&type=1&departAllerIata=PAR&arriveeAllerIata=LON&jourAller=30
		 * &moisAller=09/2011&jourRetour=07&moisRetour=10/2011&paxAdultes=1&paxEnfants=0&paxBebes=0&classe=1
		 */
		this.inUrlParamsV2 =function() {
			var s = 'type=' + this.type,
			t1 = null, t2 = null, iata = null,
			moisAller=this.dateAller.split('/')[1]+'/'+this.dateAller.split('/')[2],
			jourAller=this.dateAller.split('/')[0],
			jourRetour=this.dateAller.split('/')[1],
			moisRetour=this.dateRetour.split('/')[1]+'/'+this.dateRetour.split('/')[2];
			
			s +='&departAllerIata='+getIataFromData(this.dataDepartAller);
			s +='&arriveeAllerIata='+getIataFromData(this.dataArriveeAller);
			s +='&moisAller=' + moisAller;
			s += '&jourAller=' + jourAller;
			s += '&jourRetour=' + jourRetour;
			s += '&moisRetour=' + moisRetour;
			s += '&paxEnfants=' + (this.paxEnfants || 0);
			s += '&paxBebes=' + (this.paxBebes || 0);
			s += '&classe=' + (this.classe || 1);
			/* Preset de filtre aeroport depart Aller*/
			return s;
			
		};
		
		/**
		 * Construit une chaine corespondant aux paramètres
		 * à passer dans l'url pour ces critères.
		 */
		this.inUrlParams = function() {
			var s = 'type=' + this.type,
			t1 = null, t2 = null, iata = null;
			s +=(this.dataDepartAller && ('&departAllerData=' + this.dataDepartAller)) || (this.departAller && ('&departAller=' + this.departAller)) || '';
			s +=(this.dataArriveeAller && ('&arriveeAllerData=' + this.dataArriveeAller)) || (this.arriveeAller && ('&arriveeAller=' + this.arriveeAller)) || '';
			s +='&dateAller=' + this.dateAller;
			if (this.type) {
				if (this.type === 2) {
					s += (this.dataDepartRetour && ('&arriveeDepartData=' + this.dataDepartRetour)) || (this.departRetour && ('&departRetour=' + this.departRetour)) || '';
					s += (this.dataArriveeRetour && ('&arriveeRetourData=' + this.dataArriveeRetour)) || (this.arriveeRetour && ('&arriveeRetour=' + this.arriveeRetour)) || '';
				}
				s += '&dateRetour=' + this.dateRetour;
			}

			s += '&paxAdultes=' + (this.paxAdultes || 1);
			s += '&paxEnfants=' + (this.paxEnfants || 0);
			s += '&paxBebes=' + (this.paxBebes || 0);
			s += '&classe=' + (this.classe || 1);
			/* Preset de filtre aeroport depart Aller*/

			if (this.dataDepartAller2) {
				s += '&departAllerData2=' + this.dataDepartAller2;
			}
			if (this.dataArriveeAller2) {
				s += '&arriveeAllerData2=' + this.dataArriveeAller2;
			}
			if (this.dataDepartAller2) {
				t1 = this.dataDepartAller2.split('|');
				t2 = t1[1].split(':');
				iata = t2[1];
				s = EASY.tools.setParamInAnchor(s, 'AD', 'IN|' + iata + '|');
			}
			/* Preset de filtre aeroport arrivee aller*/
			if (this.dataArriveeAller2) {
				t1 = this.dataArriveeAller2.split('|');
				t2 = t1[1].split(':');
				iata = t2[1];
				s = EASY.tools.setParamInAnchor(s, 'AA', 'IN|' + iata + '|');
			}
			return s;
		};
		
		/**
		 * Test la validité des criteres de recherche.
		 * Renvoi un objet status contenant les éventuels champs en erreur.
		 *	dateAllerObj = dateDepart;
		 *	dateRetourObj = dateRetour;
		 */
		this.isValid=function() {
			var errors=[];
			// Depart vide
			if( !(this.dataDepartAller&&this.dataDepartAller.length>3)) {
				errors.push({field:'dataDepartAller',type:'empty'});
			}
			// arrivée vide
			if( !(this.dataArriveeAller&&this.dataArriveeAller.length>3) && this.type) {
				errors.push({field:'dataArriveeAller',type:'empty'});
			}
			// Départ et arrivée égaux.
			if(  ( this.dataArriveeAller&&this.dataArriveeAller.length>0) && ( this.dataDepartAller&&this.dataDepartAller.length>0)) {
				if(this.dataArriveeAller===this.dataDepartAller) {
					errors.push({field:'dataLieu',type:'equals'});
				}
			}
			
			// Date retour antérieure à la date aller.
			if(this.dateAllerObj.getTime()>this.dateRetourObj.getTime()) {
				errors.push({field:'date',type:'bad'});
			}
			return errors;
		};

		this.toString = function() {
			var s = 'mev.Criteres{';
			s += 'type: ' + this.type;
			s += ' - departAller: ' + this.departAller;
			s += ' - arriveeAller: ' + this.arriveeAller;
			s += ' - dateAller: ' + this.dateAller;
			if (this.type) {
				if (this.type === 2) {
					s += ' - departRetour: ' + this.departRetour;
					s += ' - arriveeRetour ' + this.arriveeRetour;
				}
				s += ' - dateRetour: ' + this.dateRetour;
			}
			s += ' - pax: ' + this.paxAdultes + ', ' + this.paxEnfants + ', ' + this.paxBebes;
			s += ' - classe: ' + this.classe;
			return s + '}';
		};

		/**
		 * Méthodes permettant de récupérer les nom de ville depart/arrivee
		 */
		var VILLE_UNDEFINED = 'undefined';

		this.getNomVilleDepartAller = function() {
			return getTextFromData(this.dataDepartAller) || this.departAller || VILLE_UNDEFINED;
		};
		this.getNomVilleArriveeAller = function() {
			return getTextFromData(this.dataArriveeAller) || this.arriveeAller || VILLE_UNDEFINED;
		};
		/**
		 *
		 */
		this.getNomLieuDepartAller = function() {
			if (!this.dataDepartAller2) {
				return this.getNomVilleDepartAller();
			}else {
				return getTextFromData(this.dataDepartAller2);
			}
		};

		/**
		 *
		 */
		this.getNomLieuArriveeAller = function() {
			if (!this.dataArriveeAller2) {
				return this.getNomVilleArriveeAller();
			}else {
				return getTextFromData(this.dataArriveeAller2);
			}
		};

		/**
		 * Méthodes permettant de récupérer les iata de ville depart/arrivee
		 */
		this.getIataVilleDepartAller = function() {
			return getIataFromData(this.dataDepartAller) || this.departAller || VILLE_UNDEFINED;
		};
		this.getIataVilleArriveeAller = function() {
			return getIataFromData(this.dataArriveeAller) || this.arriveeAller || VILLE_UNDEFINED;
		};

		/**
		 * Méthodes permettant de récupérer les ids de ville depart/arrivee
		 */
		this.getIdVilleDepartAller = function() {
			return getIdFromData(this.dataDepartAller) || this.departAller || VILLE_UNDEFINED;
		};
		this.getIdVilleArriveeAller = function() {
			return getIdFromData(this.dataArriveeAller) || this.arriveeAller || VILLE_UNDEFINED;
		};
		this.getIdVilleDepartRetour = function() {
			return getIdFromData(this.dataDepartRetour) || this.departRetour || VILLE_UNDEFINED;
		};
		this.getIdVilleArriveeRetour = function() {
			return getIdFromData(this.dataArriveeRetour) || this.arriveeRetour || VILLE_UNDEFINED;
		};

		/**
		 * Retourne une chaine de texte représentant le type de parcours
		 */
		this.getTypeName = function() {
			switch (this.type) {
				case 0: return 'AS';
				case 1: return 'AR';
				case 2: return 'PC';
				default: return 'NONE';
			}
		};

		this.getClasseName = function() {
			switch (this.classe) {
				case 0: return 'IND';
				case 1: return 'ECO';
				case 2: return 'PRE';
				case 3: return 'AFF';
				default: return 'NONE';
			}
		};

		/**
		 * @return {string} Retourne l'axe associé à la recherche (ou null).
		 */
		this.getAxe = function() {
			var axe = this.getIataVilleDepartAller() + this.getIataVilleArriveeAller();
			if (/[a-zA-Z]{6}/.test(axe)) {
				return axe.toUpperCase();
			}
			return null;
		};
	};
	EASY.mev.Criteres.getTextFromData = getTextFromData;
	EASY.mev.Criteres.getIataFromData = getIataFromData;
	
	
	
	
	/**
	 *Parcours la chaine passée en paramètre et remplace les valeurs suivantes par le caractère correspondant.
	 *- %E9 - 'é'
	 *  - %E8 - 'è'
	 *  - %EF - 'ï'
	 *  - %FC - 'ü'
	 *
	 * @param {Object} url URL à échapper.
	 */
	function unscapeSpecialChar(url) {
		var out;
		out = url.replace(/%E9/g, 'é').replace(/%E8/g, 'è').replace(/%EF/g, 'ï').replace(/%FC/g, 'ü').replace(/%ED/g, 'í');
		return out;
	}
	
	/**
	 * Méthode conversion des informations disponibles
	 * dans l'URL en jeu de critères.
	 * FIXME pas à sa place ! à mettre dans mev
	 * @param {!string} url URL à lire.
	 */
	function urlToCriteres(url) {
		// objet Critères à retourner

		var c = new ev.mev.Criteres(), params = ev.tools.getUrlParameters(decodeURIComponent(unscapeSpecialChar(url)));

		if (params.type === 0 || params.type === '0') {
			c.type = 0;
		}
		else {
			c.type = (params.type && parseInt(params.type, 10)) || 1;
		}
		c.paxAdultes = params.paxAdultes;
		c.paxEnfants = params.paxEnfants;
		c.paxBebes = params.paxBebes;
		c.classe = params.classe;
		c.dataDepartAller = (params.departAllerData && params.departAllerData.replace(/\+/g, ' ')) || (params.departAllerIata && params.departAllerIata.replace(/\+/g, ' '));
		c.dataArriveeAller = (params.arriveeAllerData && params.arriveeAllerData.replace(/\+/g, ' ')) || (params.arriveeAllerIata && params.arriveeAllerIata.replace(/\+/g, ' '));

		if (params.departAllerData2) {
			c.dataDepartAller2 = params.departAllerData2;
		}
		if (params.arriveeAllerData2) {
			c.dataArriveeAller2 = params.arriveeAllerData2;
		}
		/** Ces deux champs doivent contenir le texte du data2 si défini, c'est à dire intérgogation par ville d'un aeroport.*/
		c.departAller = ev.mev.Criteres.getTextFromData(c.dataDepartAller) || params.departAller;
		c.arriveeAller = ev.mev.Criteres.getTextFromData(c.dataArriveeAller) || params.arriveeAller;
		c.dateAller = params.dateAller ||( params.jourAller && params.moisAller && window.convertToStringFr(params.jourAller, params.moisAller));
		c.dataDepartRetour = params.departRetourData && params.departRetourData.replace(/\+/g, ' ');
		c.dataArriveeRetour = params.arriveeRetourData && params.arriveeRetourData.replace(/\+/g, ' ');
		c.departRetour = ev.mev.Criteres.getTextFromData(c.dataDepartRetour) || params.departRetour;
		c.arriveeRetour = ev.mev.Criteres.getTextFromData(c.dataArriveeRetour) || params.arriveeRetour;
		c.dateRetour = params.dateRetour || (params.jourRetour && params.moisRetour && window.convertToStringFr(params.jourRetour, params.moisRetour));
		return c;
	}
	
	EASY.mev.Criteres.urlToCriteres=urlToCriteres;

	EASY.log.debug('ev.mev.Criteres ok');
}());

