

/**
 * Technique de closure, permet de déclarer des
 * fonctions visibles seulement dans la fonction
 * anonyme.
 */
(function() {
	//"use strict";
	var WIN = this,
			DOC = WIN.document,
			EASY = WIN.ev,
			LOG = EASY && EASY.log,
			DOM = EASY && EASY.dom,
			TOOLS = EASY && EASY.tools,
			MEV = EASY && EASY.mev,
			HUB;

	// Si les namespaces/classes nécessaires ne sont pas chargées : exception
	if (!EASY) {throw "Le namespace 'ev' doit exister";}
	if (!LOG) {throw "Le namespace 'ev.log' doit exister";}
	if (!DOM) {throw "Le namespace 'ev.dom' doit exister";}
	if (!TOOLS) {throw "Le namespace 'ev.tools' doit exister";}
	if (!MEV) {throw "Le namespace 'ev.mev' doit exister";}
	if (!MEV.Vol) {throw new Error("La classe 'ev.mev.Vol' doit exister");}

	// Si le namespace ev.mev.hub est déjà déclaré, on sort
	if (MEV.hub) { return; }
	HUB = (MEV.hub = {});

	/**
	 * Méthode utilitaire privée permettant de CACHER
	 * un onglet et son panneau de titres.
	 * @param {String/Object} _pnl : l'onglet concerné (ou son id).
	 */
	function hidePanel(_pnl) {
		_pnl = DOM.element(_pnl);
		var pnlTitres = DOM.element(_pnl.id + 'Titres');
		if (_pnl) {
			if (pnlTitres) {
				pnlTitres.style.display = 'none';
			}
			_pnl.style.display = 'none';
		}
	}

	/**
	 * Méthode utilitaire privée permettant de MONTRER
	 * un onglet et son panneau de titres.
	 * @param {String/Object} _pnl : l'onglet concerné (ou son id).
	 */
	function showPanel(_pnl) {
		_pnl = DOM.element(_pnl);
		var pnlTitres = DOM.element(_pnl.id + 'Titres');
		if (_pnl) {
			if (pnlTitres) {
				pnlTitres.style.display = 'block';
			}
			_pnl.style.display = 'block';
		}
	}

	/**
	 * Permet de changer d'onglet (modification des classes
	 * de style).
	 * @param {Object} elmtContentToDisplay : le bloc contenant les resultats à afficher.
	 * @param {Object} elmtTabToChangeClass : le titre sur lequel on a clické.
	 */
	MEV.swithBuzz = function(elmtContentToDisplay, elmtTabToChangeClass) {
		var i,panels = ['buzzVille', 'buzzDates', 'buzzComp', 'buzzTarif'];
		for (i = panels.length - 1; i >= 0; --i) {
			hidePanel(panels[i]);
		}
		showPanel(elmtContentToDisplay);

		DOM.removeClass(DOM.element('villeBZMEV'), 'selected');
		DOM.removeClass(DOM.element('dateBZMEV'), 'selected');
		DOM.removeClass(DOM.element('compBZMEV'), 'selected');
		DOM.removeClass(DOM.element('tarifsBZMEV'), 'selected');
		DOM.addClass(elmtTabToChangeClass, 'selected');
	};
	// ALready defined in HUB for compatibility purpose.
	HUB.swithBuzz=MEV.swithBuzz;

	/**
	 * Méthode permettant de mettre à jour l'événement
	 * 'onclick' de l'élément donné. Le nouvel événement
	 * consiste à ouvrir une nouvelle fenetre pour
	 * afficher la page de tracking/redirection si elle
	 * existe (champ 'urlInfos' du resultat donné).
	 * Méthode privée. (accessible seulement dans la
	 * fonction anynome)
	 * @param {Object} elem : élément duquel il faut
	 *     redéfinir l'action 'onclick'.
	 * @param {Object} resultat : resultat dans lequel se
	 *     trouve le lien vers la page à ouvrir.
	 */
	/* COMMENTEE CAR NON UTILISEE
	function updateOnClick(elem, resultat) {
		if (!resultat.urlInfos) { return; }
		elem.onclick = function() {
			WIN.open(resultat.urlInfos);
		};
	}
	*/
	/**
	 * Fixe le contenu d'un element HTML
	 * avec les resultats donnés.
	 * Méthode privée. (accessible seulement dans la
	 * fonction anynome)
	 * @param {DOMElement} container l'élément HTML conteneur.
	 * @param {Array} results les resultats à insérer.
	 */
	/* COMMMENTEE CAR NON UTILISEE, VERIFIER SON UTILITE.
	function setBuzzContentVille(container, results) {
	
		container = DOM.element(container);
		var i;
		for (i = 0; i < results.length; i++) {
			var elm_li = DOC.createElement('li');
			DOM.addClass(elm_li, 'buzzResults');
			updateOnClick(elm_li, results[i]);

			var elm_p_nomVilleDepart = DOC.createElement('p');
			DOM.addClass(elm_p_nomVilleDepart, 'villeBZT');
			elm_p_nomVilleDepart.innerHTML = 'Vol au départ de <strong>' + results[i].getNomVilleDepart() + '</strong>';//FIXME multilangue
			elm_li.appendChild(elm_p_nomVilleDepart);

			var elm_div_dateDeparts = DOC.createElement('div');
			DOM.addClass(elm_div_dateDeparts, 'dateBZT');
			var elm_p_dateDepartAller = DOC.createElement('p');
			elm_p_dateDepartAller.innerHTML = results[i].dateDepartAller;
			elm_div_dateDeparts.appendChild(elm_p_dateDepartAller);
			var elm_p_dateDepartRetour = DOC.createElement('p');
			elm_p_dateDepartRetour.innerHTML = results[i].dateDepartRetour;
			elm_div_dateDeparts.appendChild(elm_p_dateDepartRetour);
			elm_li.appendChild(elm_div_dateDeparts);

			var elm_img_compagnie = DOC.createElement('img');
			DOM.addClass(elm_img_compagnie, 'compBZT');
			var comp = results[i].getCompagnie();
			elm_img_compagnie.setAttribute('src', '/base/imgs/logos/compagniesAeriennes/' + comp.code + '.gif');
			elm_img_compagnie.setAttribute('alt', comp.nom);
			elm_img_compagnie.setAttribute('title', comp.nom);
			elm_li.appendChild(elm_img_compagnie);

			var elm_p_prix = DOC.createElement('p');
			DOM.addClass(elm_p_prix, 'prixBZT');
			elm_p_prix.innerHTML = results[i].prixInt;
			elm_li.appendChild(elm_p_prix);

			container.appendChild(elm_li);
		}
	}
*/
	/**
	 * Fixe le contenu d'un element HTML
	 * avec les resultats donnés.
	 * Méthode privée. (accessible seulement dans la
	 * fonction anynome)
	 * @param {DOMElement} container l'élément HTML conteneur.
	 * @param {Array} results les resultats à insérer.
	 */
	/* COMMENTEE CAR NON UTILISEE, VERIFIER SON UTILITE.
	function setBuzzContentDate(container, results) {
		container = DOM.element(container);
		var i;
		for (i = 0; i < results.length; i++) {
			var elm_li = DOC.createElement('li');
			DOM.addClass(elm_li, 'buzzResults');
			updateOnClick(elm_li, results[i]);

			var elm_div_dateDeparts = DOC.createElement('div');
			DOM.addClass(elm_div_dateDeparts, 'dateBZT');
			var elm_p_dateDepartAller = DOC.createElement('p');
			elm_p_dateDepartAller.innerHTML = results[i].dateDepartAller;
			elm_div_dateDeparts.appendChild(elm_p_dateDepartAller);
			var elm_p_dateDepartRetour = DOC.createElement('p');
			elm_p_dateDepartRetour.innerHTML = results[i].dateDepartRetour;
			elm_div_dateDeparts.appendChild(elm_p_dateDepartRetour);
			elm_li.appendChild(elm_div_dateDeparts);

			var elm_p_nomVilleDepart = DOC.createElement('p');
			DOM.addClass(elm_p_nomVilleDepart, 'villeBZT');
			elm_p_nomVilleDepart.innerHTML = 'Vol au départ de <strong>' + results[i].nomVilleDepart + '</strong>';//FIXME multilangue
			elm_li.appendChild(elm_p_nomVilleDepart);

			var elm_img_compagnie = DOC.createElement('img');
			DOM.addClass(elm_img_compagnie, 'compBZT');
			var comp = results[i].getCompagnie();
			elm_img_compagnie.setAttribute('src', '/base/imgs/logos/compagniesAeriennes/' + comp.code + '.gif');
			elm_img_compagnie.setAttribute('alt', comp.nom);
			elm_img_compagnie.setAttribute('title', comp.nom);
			elm_li.appendChild(elm_img_compagnie);

			var elm_p_prix = DOC.createElement('p');
			DOM.addClass(elm_p_prix, 'prixBZT');
			elm_p_prix.innerHTML = results[i].prixInt;
			elm_li.appendChild(elm_p_prix);

			container.appendChild(elm_li);
		}
	}
*/
	/**
	 * Permet de lancer l'invocation du pré-chargement du
	 * buzz distant (Buzz Top Multi-axe).
	 * @param {Integer} site : id du site actuel.
	 * @param {String} axesProperty : propriété contenant
	 *     les axes cherchés.
	 * @param {Integer} limit : nombre de résultat par axe.
	 */
	MEV.preloadTopMulti = function(site, axesProperty, limit) {
		LOG.warn('HUB.preloadTopMulti('+axesProperty+'): invoking buzzVilles ('+limit+')...');
		MEV.buzz.invokePreloadTopMulti(site, TOOLS.getParameter('clientId'), 'buzzVilles' + limit, axesProperty, limit);
	};

	// ALready defined in HUB for compatibility purpose.
	HUB.preloadTopMulti=MEV.preloadTopMulti;

	/**
	 * Permet de lancer l'invocation du pré-chargement du
	 * buzz distant (Buzz Next Dates).
	 * @param {Integer} site : id du site actuel.
	 * @param {String} axeProperty : propriété contenant
	 *     l'axe cherché.
	 * @param {Integer} limit : nombre de résultats
	 *     (=nombre de dates).
	 */
	MEV.preloadNextDates = function(site, axeProperty, limit) {
		LOG.warn('HUB.preloadNextDates('+axeProperty+'): invoking buzzDates ('+limit+')...');
		MEV.buzz.invokePreloadNextDates(site, TOOLS.getParameter('clientId'), 'buzzDates' + limit, axeProperty, limit);
	};
	
	// ALready defined in HUB for compatibility purpose.
	HUB.preloadNextDates=MEV.preloadNextDates;

	/**
	 * Contient l'élément à afficher lorsque l'on charge un Buzz.<br>
	 * C'est le panneau d'attente du Buzz.<br>
	 * Cette variable est renseignée en postLoad par la fonction
	 * #ev.mev.hub.activateBuzzClickEvent().
	 */
	var buzzWaitPanel;
	/**
	 * Contient l'objet ev.effects.Opacity qui gère le panneau
	 * d'attente du Buzz.<br>
	 * Cette variable est renseignée en postLoad par la fonction
	 * #ev.mev.hub.activateBuzzClickEvent().
	 */
	var opacityBuzzWaitingPanel;

	/**
	 * Fixe le comportement des onglets donnés (buzzVille et
	 * buzzDates) pour qu'ils puissent être "cliquables".
	 * @param {Integer} _siteId : identifiant numérique du site.
	 * @param {String} _villeCode : code IATA de la ville (de la page hub courante).
	 * @param {String} _pageInfos : page de tracking/redirection.
	 * @param {String} _ongletBuzzVille : id de l'onglet BuzzVille.
	 * @param {String} _ongletBuzzDates : id de l'onglet BuzzDates.
	 */
	MEV.activateBuzzClickEvent = function(_siteId, _villeCode, _pageInfos, _ongletBuzzVille, _ongletBuzzDates, _buttonMoreResults) {
		buzzWaitPanel = DOM.element('buzzWaitPanel');
		if (buzzWaitPanel && EASY.effects && EASY.effects.Opacity) {
			opacityBuzzWaitingPanel = new EASY.effects.Opacity(buzzWaitPanel, 500);
		}
		
		_ongletBuzzVille = DOM.element(_ongletBuzzVille);
		if (_ongletBuzzVille) {
			_ongletBuzzVille.onclick = function() {
				HUB.buzzTopMulti(_siteId, 'hub.axes.' + _villeCode, 1, _pageInfos, 'buzzVille', _ongletBuzzVille);
			};
			_ongletBuzzVille.style.display = 'block';
		}
		_ongletBuzzDates = DOM.element(_ongletBuzzDates);
		if (_ongletBuzzDates) {
			
			_ongletBuzzDates.onclick = function() {
				HUB.buzzNextDates(_siteId, 'hub.axe.' + _villeCode, 9, _pageInfos, 'buzzDates', _ongletBuzzDates);
			};
			_ongletBuzzDates.style.display = 'block';
		}
		_buttonMoreResults = DOM.element(_buttonMoreResults);
		if (_buttonMoreResults) {
			_buttonMoreResults.onclick = function() {
				HUB.buzzMoreResults(_siteId, _villeCode, _pageInfos);
			};
			_buttonMoreResults.style.display = 'block';
		}
	};
	
	// ALready defined in HUB for compatibility purpose.
	HUB.activateBuzzClickEvent=MEV.activateBuzzClickEvent;

	/**
	 * Déclaration d'une méthode privée à exécuter
	 * après récupération d'un Buzz pour afficher
	 * ses résultats grâce au "template"
	 * correspondant.
	 * @param {DOMElement} _cible : élément dans lequel il faut
	 *     placer les résultats obtenus.
	 * @param {Object} _template : template à utiliser pour ce Buzz.
	 * @param {Array} _results : tableau de resultats du Buzz.
	 * @param {Object} _clickedElement : élément sur lequel on a clické (optionel).
	 */
	function fillBuzz(_cible, _template, _results, _clickedElement) {
		if (_results) {
			var t1 = new Date().getTime();
			_template.refreshView(_results);
			var t2 = new Date().getTime();
			LOG.warn('fillBuzz()> refreshView : ' + (t2 - t1));
			if (_clickedElement) {
				/**
			 * Nouvel évenement onclick pour cet élément (onglet à priori).
			 * Nous n'aurons plus besoin de charger le Buzz
			 * lors des futurs clics sur cet élément.
			 */
				_clickedElement.onclick = function() {
					// affichage de l'onglet clické
					HUB.swithBuzz(_cible, _clickedElement);
				};
			}
		}
	}

	function addVolHandler(vol, method, value){
		if (!vol[method]) {
			vol[method] = function() {
				return value;
			};
		}
	}

	/**
	 * Déclaration d'une méthode privée à exécuter
	 * après récupération d'un Buzz pour afficher
	 * ses résultats grâce au "template"
	 * correspondant.
	 * @param {DOMElement} _cible : élément dans lequel il faut
	 *     placer les résultats obtenus.
	 * @param {Object} _template : template à utiliser pour ce Buzz.
	 * @param {Array} _results : tableau de resultats du Buzz.
	 * @param {Object} _clickedElement : élément sur lequel on a clické (optionel).
	 */
	function fillNewBuzz(_cible, _template, _results, _clickedElement) {
		if (_results) {
			var t0 = new Date().getTime(),axe;

			var vols = [], a, n, i;
			for (axe in _results.vols) {
				if (_results.vols.hasOwnProperty(axe)) {
					a = _results.vols[axe];
					n = a.length;
					for (i = 0; i < n; ++i) {
						addVolHandler(a[i], 'getAxeDepart', a.depart);
						addVolHandler(a[i], 'getAxeArrivee', a.arrivee);
						vols.push(a[i]);
					}
				}
			}

			var t1 = new Date().getTime();
			_template.refreshView(vols);
			var t2 = new Date().getTime();
			LOG.warn('fillNewBuzz()> refreshView : ' + (t2 - t0) + ' = ' + (t1 - t0) + ' + ' + (t2 - t1));
			if (_clickedElement) {
				/**
			 * Nouvel évenement onclick pour cet élément (onglet à priori).
			 * Nous n'aurons plus besoin de charger le Buzz
			 * lors des futurs clics sur cet élément.
			 */
				_clickedElement.onclick = function() {
					// affichage de l'onglet clické
					HUB.swithBuzz(_cible, _clickedElement);
				};
			}
		}
	}

	/**
	 * Affiche le panneau d'attente de téléchargement de Buzz.
	 */
	function showBuzzWaitingPanel() {
		if (!buzzWaitPanel) { return; }
		if (opacityBuzzWaitingPanel) {
			opacityBuzzWaitingPanel.reset();
		}
		buzzWaitPanel.style.display = 'block';
	}

	/**
	 * Cache le panneau d'attente de téléchargement de Buzz.
	 */
	function hideBuzzWaitingPanel() {
		if (!buzzWaitPanel) { return; }
		if (opacityBuzzWaitingPanel) {
			opacityBuzzWaitingPanel.decrease();
			WIN.setTimeout(function() {
				buzzWaitPanel.style.display = 'none';
			}, 500);
		}
		else {
			buzzWaitPanel.style.display = 'none';
		}
	}

	/**
	 * Permet de lancer l'invocation du buzz distant
	 * (Buzz Top) et d'afficher les résultats obtenus.
	 * @param {Integer} _site : id du site actuel.
	 * @param {String} _axeProperty : propriété contenant
	 *     l'axe cherché.
	 * @param {Integer} _limit : nombre de résultats.
	 * @param {String} _pageInfos : page de tracking/redirection.
	 * @param {DOMElement} _cible : élément dans lequel il faut
	 *     placer les résultats obtenus.
	 * @param {DOMElement} _clickedElement : l'élément sur
	 *     lequel on a clické.
	 * @param {Function} _doAfter : fonction à exécuter après
	 *     récupération et affichage du Buzz.
	 */
	MEV.buzzTop = function(_site, _axeProperty, _limit, _pageInfos, _cible, _clickedElement, _doAfter) {
		_cible = DOM.element(_cible);
		// panneau d'attente
		showBuzzWaitingPanel();
		// affichage de l'onglet clické
		if (_clickedElement) {
			HUB.swithBuzz(_cible, _clickedElement);
		}
		// "callback" pour après invocation RJS
		function doAfter(_results) {
			if (typeof(_doAfter) === 'function') {
				fillBuzz(_cible, HUB.templManagerBuzzVolTarif, _results, _clickedElement);
				// on passe le nombre de résultat(s) obtenu(s) (dans le "callback")
				_doAfter(_results ? _results.length : 0);
			}
			hideBuzzWaitingPanel();
		}
		// appel du Buzz distant (RJS)
		MEV.buzz.invokeTopMulti(_site, TOOLS.getParameter('clientId'), 'buzzTarif' + _limit, _axeProperty, _limit, _pageInfos, doAfter);
	};

	// ALready defined in HUB for compatibility purpose.
	HUB.buzzTop=MEV.buzzTop;

	/**
	 * Permet de lancer l'invocation du buzz distant
	 * (Buzz Top Multi-axe) et d'afficher les résultats
	 * obtenus.
	 * @param {Integer} _site : id du site actuel.
	 * @param {String} _axesProperty : propriété contenant
	 *     les axes cherchés.
	 * @param {Integer} _limit : nombre de résultats par axe.
	 * @param {String} _pageInfos : page de tracking/redirection.
	 * @param {DOMElement} _cible : élément dans lequel il faut
	 *     placer les résultats obtenus.
	 * @param {DOMElement} _clickedElement : l'élément sur
	 *     lequel on a clické.
	 * @param {Function} _doAfter : fonction à exécuter après
	 *     récupération et affichage du Buzz.
	 */
	MEV.buzzTopMulti = function(_site, _axesProperty, _limit, _pageInfos, _cible, _clickedElement, _doAfter) {
		_cible = DOM.element(_cible);
		// panneau d'attente
		showBuzzWaitingPanel();
		// affichage de l'onglet clické
		if (_clickedElement) {
			HUB.swithBuzz(_cible, _clickedElement);
		}
		// "callback" pour après invocation RJS
		function doAfter(_results) {
			try {
				LOG.warn('HUB.buzzTopMulti(): doAfter... results: '+(_results&&_results.vols&&_results.vols.length));
				try {
					fillNewBuzz(_cible, HUB.templManagerBuzzVolVille, _results, _clickedElement);
					if (typeof(_doAfter) === 'function') {
						// on passe le nombre de résultat(s) obtenu(s) (dans le "callback")
						_doAfter( (_results && _results.vols && _results.vols.length ) || 0);
					}
				}
				catch (errAfter) {
					LOG.error('HUB.buzzTopMulti(): Error on after : '+ errAfter);
				}
				hideBuzzWaitingPanel();
			}
			catch (ex) {
				LOG.fatal('HUB.buzzTopMulti(): Catched except : ' + ex);
			}
		}
		LOG.warn('HUB.buzzTopMulti('+_axesProperty+'): invoking buzzVilles ('+_limit+')...');
		// appel du Buzz distant (RJS)
		MEV.buzz.invokeTopMulti(_site, TOOLS.getParameter('clientId'), 'buzzVilles' + _limit, _axesProperty, _limit, _pageInfos, doAfter);
	};

	// ALready defined in HUB for compatibility purpose.
	HUB.buzzTopMulti=MEV.buzzTopMulti;

	/**
	 * Permet de lancer l'invocation du buzz distant
	 * (Buzz Next Dates) et d'afficher les résultats
	 * obtenus.
	 * @param {Integer} _site : id du site actuel.
	 * @param {String} _axeProperty : propriété contenant
	 *     l'axe cherché.
	 * @param {Integer} _limit : nombre de résultats
	 *     (=nombre de dates).
	 * @param {String} _pageInfos : page de tracking/redirection.
	 * @param {DOMElement} _cible : élément dans lequel il faut
	 *     placer les résultats obtenus.
	 * @param {DOMElement} _clickedElement : l'élément sur
	 *     lequel on a clické.
	 * @param {Function} _doAfter : fonction à exécuter après
	 *     récupération et affichage du Buzz.
	 */
	MEV.buzzNextDates = function(_site, _axeProperty, _limit, _pageInfos, _cible, _clickedElement, _doAfter) {
		_cible = DOM.element(_cible);
		// panneau d'attente
		showBuzzWaitingPanel();
		// affichage de l'onglet clické
		if (_clickedElement) {
			HUB.swithBuzz(_cible, _clickedElement);
		}
		// "callback" pour après invocation RJS
		function doAfter(_results) {
			try {
				LOG.warn('HUB.buzzNextDates(): doAfter... results: '+(_results&&_results.vols&&_results.vols.length));
				try {
					fillNewBuzz(_cible, HUB.templManagerBuzzVolDate, _results, _clickedElement);
					if (typeof(_doAfter) === 'function') {
						// on passe le nombre de résultat(s) obtenu(s) (dans le "callback")
						_doAfter((_results && _results.vols && _results.vols.length) || 0);
					}
				}
				catch (errAfter) {
					LOG.error('HUB.buzzNextDates(): Error on after : '+ errAfter);
				}
				hideBuzzWaitingPanel();
			}
			catch (ex) {
				LOG.fatal('HUB.buzzNextDates(): Catched except : ' + ex);
			}
		}
		LOG.warn('HUB.buzzNextDates('+_axeProperty+'): invoking buzzDates ('+_limit+')...');
		// appel du Buzz distant (RJS)
		MEV.buzz.invokeNextDates(_site, TOOLS.getParameter('clientId'), 'buzzDates' + _limit, _axeProperty, _limit, _pageInfos, doAfter);
	};
	
	// ALready defined in HUB for compatibility purpose.
	HUB.buzzNextDates=MEV.buzzNextDates;

	/**
	 * Permet de lancer l'invocation du buzz distant
	 * (Buzz Compagnies) et d'afficher les résultats
	 * obtenus.
	 * @param {Integer} _site : id du site actuel.
	 * @param {String} _axeProperty : propriété contenant
	 *     l'axe cherché.
	 * @param {Integer} _limit : nombre de résultats
	 *     (=nombre de compagnies aériennes).
	 * @param {String} _pageInfos : page de tracking/redirection.
	 * @param {DOMElement} _cible : élément dans lequel il faut
	 *     placer les résultats obtenus.
	 * @param {DOMElement} _clickedElement : l'élément sur
	 *     lequel on a clické.
	 * @param {Function} _doAfter : fonction à exécuter après
	 *     récupération et affichage du Buzz.
	 */
	MEV.buzzComp = function(_site, _axeProperty, _limit, _pageInfos, _cible, _clickedElement, _doAfter) {
		_cible = DOM.element(_cible);
		// panneau d'attente
		showBuzzWaitingPanel();
		// affichage de l'onglet clické
		if (_clickedElement) {
			HUB.swithBuzz(_cible, _clickedElement);
		}
		// "callback" pour après invocation RJS
		function doAfter(_results) {
			fillBuzz(_cible, HUB.templManagerBuzzVolComp, _results, _clickedElement);
			if (typeof(_doAfter) === 'function') {
				// on passe le nombre de résultat(s) obtenu(s) (dans le "callback")
				_doAfter(_results ? _results.length : 0);
			}
			hideBuzzWaitingPanel();
		}
		// appel du Buzz distant (RJS)
		MEV.buzz.invokeCompagnies(_site, TOOLS.getParameter('clientId'), 'buzzComp' + _limit, _axeProperty, _limit, _pageInfos, doAfter);
	};
	
	// ALready defined in HUB for compatibility purpose.
	HUB.buzzComp=MEV.buzzComp;

	/**
	 * Cette méthode prend en paramètre la liste d'onglets
	 * qui existent.
	 * Elle retourne l'élément qui possède la classe de
	 * style 'selected' (ou null si classe non trouvée).
	 * Méthode privée. (accessible seulement dans la
	 * fonction anynome)
	 */
	function getSelectedBuzzElement() {
		var cnt = arguments.length,i;
		for (i = 0; i < cnt; ++i) {
			//      LOG.info(i+' - '+arguments[i]+' : '+arguments[i].style.display+'='+(arguments[i].style.display!=='none'));
			if (arguments[i].style.display !== 'none') { return arguments[i]; }
		}
		return null;
	}

	/**
	 * Permet de récupérer les résultats présents
	 * dans un conteneur de Buzz.
	 * @param {DOMElement} _elt : element conteneur de resultats de Buzz.
	 */
	function resultsInBuzz(_elt) {
		var children = _elt.childNodes;
		var childCnt = children.length;
		var results = [],i;

		for (i = 0; i < childCnt; ++i) {

			if (!children[i].tagName) {
				continue;
			}else if (children[i].nodeType !== 1) {
				continue;
			}else if (/(buzzvoltarif|buzzvolville|buzzvoldate|buzzvolcomp)/i.test(children[i].tagName)) {
				var firstSub = children[i].firstChild;
				if (firstSub && firstSub.nodeType === 1) {
					if (DOM.hasClass(firstSub, 'buzzResults')) {
						results.push(firstSub);
						//              LOG.debug('resultsInBuzz('+_elt.id+') ¤ template found - '+firstSub.nodeType+'> tagName='+firstSub.tagName+' => Recorded');
					}
				}
			} else if (DOM.hasClass(children[i], 'buzzResults')) {
				results.push(children[i]);
				//LOG.debug('resultsInBuzz('+_elt.id+')> tagName='+children[i].tagName+' => Recorded');
			}
		}
		return results;
	}

	/**
	 * FIXME doc
	 * @param {Element} _elt nettoie tous les espaces blancs dans l'élément DOM donné.
	 */
	function cleanWhitespace(_elt) {
		// If no element is provided, do the whole HTML document
		_elt = _elt || DOC;
		// Use the first child as a starting point
		var cur = _elt.firstChild;
		var next;
		// Go until there are no more child nodes
		while (cur) {
			next = cur.nextSibling;
			// If the node is a text node, and it contains nothing but whitespace
			if (cur.nodeType === 3 && !(/\S/.test(cur.nodeValue))) {
				// Remove the text node
				_elt.removeChild(cur);
			}
			// Otherwise, if it's an element
			else if (cur.nodeType === 1) {
				// Recurse down through the document
				cleanWhitespace(cur);
			}
			cur = next; // Move through the child nodes
		}
	}

	/**
	 * Permet de créer un slider pour l'élément donné
	 * si celui-ci n'en a pas.
	 * @param {DOMElement} _elt : element (conteneur de
	 *     resultats buzz) qui deviendra extensible.
	 * @param {Integer} _nb : nombre de resultats de buzz
	 *     à contenir losque le conteneur aura une taille
	 *     maxi.
	 */
	function checkSlider(_elt, _nb) {
		if (!_elt.$$slider) { // si aucun Slider n'est créé, on en crée un
			cleanWhitespace(_elt);
			var actualCapacity = 9;
			var actualHeight = parseInt(WIN.getStyleValue(_elt, 'height').replace(/px/, ''), 10);
			//      LOG.info('checkSlider('+_elt.id+','+_nb+')> actualHeight : '+actualHeight);
			var resultsArr = resultsInBuzz(_elt);
			var nbResults = resultsArr.length;
			//      LOG.info('checkSlider('+_elt.id+','+_nb+')> nbResults : '+nbResults);
			var resultHeight = 0;
			if (nbResults > 0 && resultsArr[0] && DOM.hasClass(resultsArr[0], 'buzzResults')) {
				resultHeight = parseInt(WIN.getStyleValue(resultsArr[0], 'height').replace(/px/, ''), 10);
			}
			//      LOG.info('checkSlider('+_elt.id+','+_nb+')> resultHeight : '+resultHeight);
			var titreHeight = 0;
			if (_elt.firstChild && _elt.firstChild.nodeType === 1 && DOM.hasClass(_elt.firstChild, 'titres')) {
				titreHeight = parseInt(WIN.getStyleValue(_elt.firstChild, 'height').replace(/px/, ''), 10);
			}
			if (resultHeight > 0) {
				//        titreHeight=actualHeight-resultHeight*nbResults;
				titreHeight = actualHeight - resultHeight * actualCapacity;
			}
			//      LOG.info('checkSlider('+_elt.id+','+_nb+')> titreHeight : '+titreHeight);
			var maxHeight = titreHeight + (actualHeight - titreHeight) * 2;
			if (resultHeight > 0) {
				maxHeight = actualHeight + (_nb - actualCapacity) * resultHeight;
			}
			//      LOG.info('checkSlider('+_elt.id+','+_nb+')> maxHeight : '+maxHeight);
			_elt.style.minHeight = actualHeight + 'px';
			_elt.style.maxHeight = maxHeight + 'px';
			_elt.$$slider = new EASY.effects.Slider(_elt, 1200); // fermé par défaut
		}
	}

	/**
	 * Permet de charger plus de résultats dans l'onglet
	 * de Buzz ouvert.
	 * Elle remplira l'element de la liste qui possède la
	 * classe de style 'selected'.
	 * @param {Integer} _site : id du site actuel.
	 * @param {Object} _destination : code IATA de la destination
	 *     (à partir duquel on récupère le bon nom de propriété).
	 * @param {String} _pageInfos : page de tracking/redirection.
	 */
	MEV.buzzMoreResults = function(_site, _destination, _pageInfos) {
		var selectedBuzzContent = getSelectedBuzzElement.apply(this, DOM.element('buzzTarif', 'buzzVille', 'buzzDates', 'buzzComp'));
		if (!selectedBuzzContent) { return; }
		//    LOG.info('mev.hub.buzzMoreResults('+_destination.id+')> selected : '+selectedBuzzContent.id);
		if (selectedBuzzContent.$$EV_LOADING !== undefined) {   //      if(!selectedBuzzContent.$$EV_LOADING){
			//        LOG.error('BREAK (deja vu ici !)');
			//      }
			return; }
		selectedBuzzContent.$$EV_LOADING = true;
		/**
		 * "callback" pour après invocation RJS.
		 * Permet de fixer l'état de panneau de
		 * Buzz ($$EV_LOADING) selon le résultat
		 * de l'invocation.
		 * @param {Integer} _nbResults : le nombre de résultat(s) obtenu(s).
		 */
		function doAfter(_nbResults) {
			if (_nbResults) {
				selectedBuzzContent.$$EV_LOADING = false;
				checkSlider(selectedBuzzContent, Math.max(9, _nbResults));
				selectedBuzzContent.$$slider.open();
			}
			else {
				LOG.error('Impossible de charger le Buzz (timeout)');
				// si l'invocation échoue, on le fera une autre fois
				selectedBuzzContent.$$EV_LOADING = undefined;
			}
		}
		// Choix de l'action selon l'onglet visible
		switch (selectedBuzzContent.id) {
			case 'buzzTarif':
				// appel du Buzz distant (RJS)
				HUB.buzzTop(_site, 'hub.axe.' + _destination, 18, _pageInfos, selectedBuzzContent, null, doAfter);
				break;
			case 'buzzVille':
				// appel du Buzz distant (RJS)
				HUB.buzzTopMulti(_site, 'hub.axes.' + _destination, 3, _pageInfos, selectedBuzzContent, null, doAfter);
				break;
			case 'buzzDates':
				// appel du Buzz distant (RJS)
				HUB.buzzNextDates(_site, 'hub.axe.' + _destination, 18, _pageInfos, selectedBuzzContent, null, doAfter);
				break;
			case 'buzzComp':
				// appel du Buzz distant (RJS)
				HUB.buzzComp(_site, 'hub.axe.' + _destination, 18, _pageInfos, selectedBuzzContent, null, doAfter);
				break;
			default:
				break;
		}
	};
	
	// ALready defined in HUB for compatibility purpose.
	HUB.buzzMoreResults=MEV.buzzMoreResults;
	
}()); // exécution de la fonction anonyme ici

