(function(){
	// Si les namespaces/classes nécessaires ne sont pas chargées : exception
	if(!window.ev){throw new Error("Le namespace 'ev' doit exister");}
	if(!ev.rjs){throw new Error("Le namespace 'ev.rjs' doit exister");}
	// On s'assure que le namespace ev.meh existe
	if(!ev.meh){ ev.meh={}; }
	//Si la classe Context est définie on sort
	if(ev.meh.Context){return;}
		
	// on teste d'abord l'existance des classes nécessaires
	Classe.checkDefined("ev.me.Compte");
	Classe.checkDefined("ev.me.SetCompteMethod");
	Classe.checkDefined("ev.meh.Criteres");
	Classe.checkDefined("ev.meh.SetCriteresMethod");
	Classe.checkDefined("ev.meh.GetCriteresMethod");
	// on teste ensuite l'existance du namespace ev.meh.Recherche
	if(!ev.meh.Recherche){throw new Error("Le namespace 'ev.meh.Recherche' n'est pas défini!");}
			
	// Initialisation des chemins utiles
	var enginePath="/hotels";
	var searchPath=enginePath+"/recherche/MEH";
		
	/**
	 * Classe permettant de stoker les informations 
	 * générales du moteur MEH3.
	 */
	ev.meh.Context=function(){
		if(arguments.callee.singletonInstance){
			// si le singleton a été instancié on le retourne directement.
			return arguments.callee.singletonInstance;
		}	
		// sinon, definition de l'instance
	
		arguments.callee.singletonInstance=this;

		// FIXME à supprimer !
		this.BASE_XML="/rjs/meh";
		
		this.PAGE_INDEX="formulaire.html";
		this.PAGE_RESULTS="result.html";
		this.PAGE_INFOS="infos.html";
		
		var target="";
	
		var compte=new ev.me.Compte();
		var criteres=new ev.meh.Criteres();
		
		var rjsLocator=new ev.rjs.Locator(30000);
	
		/**
		 * Expression régulière représentant la clé crikey d'un jeu de criteres
		 * 
		 * ex : Criteres{idVille,dateDebut,dateFin,nbChambres,nbEtoiles,paxAdultes,paxEnfants}
		 */
		REGEXP_ID_VILLE=/Criteres{([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^}]*)}/;
		
		/**
		 * Permet de récuperer la clé crikey dans un jeu de criteres
		 * @param {Object} Critere
		 */
		this.getIdVille=function(cr){
			var idVille=0;
			if(REGEXP_ID_VILLE.test(cr)){
				// on récupère le groupe correspondant à l'id de la ville dans la clé des critères
				idVille=RegExp.$1;
				ev.log.info('ev.meh.Context().getIdVille() > idVille : "'+idVille+'"');
			}
			else{
				ev.log.error('ev.meh.Context().getIdVille() > No idVille in criteres!');
			}
			return idVille;
		};
	
		/** Constante globale qui identifie l'URL racine des fichiers rjs.
		 * Il faut vérifier que la source ici définie, correspond effectivement
		 * à une localisation valable de fichiers rjs.
		 */
		var URL_RJS_ROOT=(function(){
			//FIXME a supprimer dés que les dev sont finis
			if(new RegExp("http://seoul").test(window.location.href)){
				ev.log.debug('Configuration RJS pour SEOUL! (Développement)');
				return "http://seoul.esv.lcom:85";
			}
			ev.log.debug('Configuration BuzzRJS pour PRODUCTION!');
			switch(window.lang){
				case "es_ES":
					return "http://www.easyviajar.com";
				case "it_IT":
					return "http://www.easyviaggio.com";
				case "en_GB":
					return "http://www.easyvoyage.co.uk";
				case "de_DE":
					return "http://www.easyvoyage.de";
				case "fr_FR":
					return "http://www.easyvoyage.com";
				default:
					return "http://www.easyvoyage.com";
			}
		})(); // exécution de la procédure ici
		
		/**
		 * Surcharge pour le vol.
		 * @param {Object} method chemin de la méthode à appeler
		 *   sur le service de recherche (ERA)
		 */
		this.getEraPath_recherche=function(method){
			return searchPath+method;
		};

		/**
		 * Permet de récupérer le compte courant de la page.
		 */
		this.getCompte=function(){
			return compte;
		};
	
		/**
		 * Permet de récupérer les critères courant de la page.
		 */
		this.getCriteres=function(){
			return criteres;
		};
		
		/**
		 * Permet de récupérer la valeur de la variable target
		 */
		this.getTarget=function(){
			return target;
		};

		/**
		 * Retourne le gestionnaire de RJS global.
		 */
		this.getRjsLocator=function(){
			return rjsLocator;
		};
	
		/**
		 * Permet de récupérer le jeu de criteres courant de la page
		 * et de lancer la recherche.
		 * NB : Ne doit être appelée qu'une seule fois.
		 */
		this.lancerRecherche=function(){
			ev.log.info("ev.meh.Context.lancerRecherche() - criteres: "+criteres.toString());
			new ev.meh.GetCriteresMethod(searchPath+"/criteres.rjs", criteres, this.onCriteresRetreived);
		};
		
		/**
		 * permet de lancer la recherche soit a partir des parametres presents dans l'url soit a partir des criteres settés en session
		 */
		this.launchSearch=function(){
			ev.log.info("ev.meh.Context.launchSearch() - criteres: "+criteres.toString());
			if(ev.meh.launchSearchWithUrlParams()){
				// on lance la recherche à partir des parametres contenus dans l'url
				//ev.meh.Recherche.startRechercheWithCritere(ev.meh.Context().getCriteres());// on lance la recherche	
				new ev.meh.GetCriteresMethod(searchPath+"/criteres.rjs", criteres, this.onCriteresRetreived);
			
			}else{
				// on lance la recherche à partir des criteres settés dans la session auparavant
				new ev.meh.GetCriteresMethod(searchPath+"/criteres.rjs", criteres, this.onCriteresRetreived);
			}
		};
	
		/**
		 * Utilisation du jeu de criteres, une fois 
		 * qu'il est récupéré et démarrage recherche.
		 */
		this.onCriteresRetreived=function(){
			ev.log.info('criteres retreived : '+criteres.toString());
			// lancement de la recherche
			ev.meh.Recherche.startRecherche();
			ev.meh.Context().initForm();
		};
		
		this.initForm=function(){
				ev.log.debug("ev.meh.Context.initForm() - criteres: "+criteres.toString());
				// Alimenter le formulaire à partir de l'objet
				if(document.getElementById("lieuMEH")){
					document.getElementById("lieuMEH").value=criteres.ville;
				}
				if(document.getElementById("jourDebutMEH")&&document.getElementById("moisDebutMEH")){
					Date.convertDateToSelector(criteres.dateDebut, "jourDebutMEH", "moisDebutMEH");
				}
				if(document.getElementById("jourFinMEH")&&document.getElementById("moisFinMEH")){
					Date.convertDateToSelector(criteres.dateFin, "jourFinMEH", "moisFinMEH");
				}
				if(document.getElementById("chambres")){
					document.getElementById("chambres").value=criteres.chambres;
				}
				if(document.getElementById("paxAdultes")){
					document.getElementById("paxAdultes").value=criteres.paxAdultes;	
				}
				if(document.getElementById("paxEnfants")){
					document.getElementById("paxEnfants").value=criteres.paxEnfants;	
				}
				if(document.getElementById("etoiles")){
					document.getElementById("etoiles").value=criteres.etoiles;		
				}
		};
	
		/**
		 * FIXME
		 */
		this.setCriteres=function(){
			ev.log.debug("Envoi des criteres...");
			new ev.meh.SetCriteresMethod(searchPath+"/criteres/creer.rjs?"+criteres.inUrlParams(), criteres, this.onCriteresRecorded);
		};
	
		/**
		 * FIXME
		 */
		this.onCriteresRecorded=function(){
			ev.log.info('criteres recorded : '+criteres.toString());
			ev.log.debug("Ouverture page resultats...");
//			window.location.href=ev.meh.Context().PAGE_RESULTS;
								
			// Envoi vers page de résultats avec encodage de l'URL (pour être sûr d'avoir la session ERA sur la page suivante)
			//FIXME à valider
			if(target=="_blank"){//on ouvre la page de résultat dans un nouvel onglet (pour les affiliés)
				window.open(ev.requestManager.encodeAnchor(ev.meh.Context().PAGE_RESULTS), '_blank');
			}
			else{
				window.location.href=ev.requestManager.encodeAnchor(ev.meh.Context().PAGE_RESULTS);
			}
		};
	
		/**
		 * Permet de choisir le chemin des pages XML.
		 * @param {String} _baseXML : chemin des XML
		 * 
		 * FIXME à supprimer !
		 */
		this.setBaseXML=function(_baseXML){
			this.BASE_XML=_baseXML;
		};
	
		/**
		 * Permet de choisir le chemin de la page d'index.
		 * @param {String} _page : page d'index
		 */
		this.setPageIndex=function(_page){
			this.PAGE_INDEX=_page;
		};
	
		/**
		 * Permet de choisir le chemin de la page de resultats.
		 * @param {String} _page : page de resultats
		 */
		this.setPageResults=function(_page){
			this.PAGE_RESULTS=_page;
		};
	
		/**
		 * Permet de choisir le chemin de la page de redirection partenaire.
		 * @param {String} _page : page de redirection
		 */
		this.setPageInfos=function(_page){
			this.PAGE_INFOS=_page;
		};
	
		/**
		 * Permet de choisir le site et le code client
		 * du compte courant.
		 *
		 * Une fois les données fixées, cette méthode
		 * envoie la nouvelle définition de compte dans
		 * la session.
		 *
		 * @param _site : ID du site
		 * @param _codeClient : code client du compte (si on souhaite utiliser le compte principal du site, ce paramètre est facultatif)
		 */
		this.setCompteBySiteAndCode=function(_site, _codeClient){
			if(_site){
				// init du compte à partir des paramètres donnés
				compte.setBySiteAndCode(_site, _codeClient);
	
				// envoi du compte au serveur (via timeline)
				this.recordCompte();
			}
		};
		/**
		 * Permet de choisir si la page de résultat s'ouvre dans une nouvelle fenêtre
		 *
		 * @param _target : attribut target de open.window
		 */
		this.setTarget=function(_target){
			if(_target){
				target=_target;
			}
		};
		
		
		/**
		 * Permet de choisir le compte client courant à
		 * partir de son identifiant numérique.
		 *
		 * Une fois les données fixées, cette méthode
		 * envoie la nouvelle définition de compte dans
		 * la session.
		 *
		 * @param _client : ID du compte client
		 */
		this.setCompteByClient=function(_client){
			if(_client){
				// init du compte à partir du paramètre donné
				compte.setCompteByClient(_client);
	
				// envoi du compte au serveur (via timeline)
				this.recordCompte();
			}
		};
	
		/**
		 * Méthode privée permettant d'effectuer la requête réelle
		 * d'enregistrement du compte vers le serveur.
		 */
		this.recordCompte=function(){
			ev.log.info("recordCompte() - compte: "+compte.toString());
			new ev.me.SetCompteMethod(enginePath+"/compte/choisir.rjs?urlInfos=infos.jsp", compte, this.onCompteRecorded);
		};

		/**
		 * FIXME
		 */
		this.onCompteRecorded=function(){
			ev.log.info('compte recorded : '+compte.toString());
		};

		// on retourne l'instance créée
		return this;
	};

	// instanciation du singleton
	ev.meh.Context.__singletonInstance=new ev.meh.Context();
	ev.log.debug("ev/meh/Context.js ok");
}());