/**
* Ce fichier fait parti d'un package, toute modification doit entrainer la génération
* d'un nouveau package pour être pris en compte.
* voir l'objet ObjFichierPackage pour connaitre la marche à suivre pour regénérer un package
* @since 20/05/2009 Olivier REYT <reyt@benchmark.fr> 
*/

if(typeof benchmark == "undefined") var benchmark = new Object();
if(typeof benchmark.framework == "undefined") benchmark.framework = new Object();
if(typeof benchmark.framework.net == "undefined") benchmark.framework.net = new Object();

/**
 * L'ObjControleurAjax3 permet de gerer les appels ajax.
 *
 * - Il permet d'eviter les appels simultané pour une même requête ajax
 * - Il permet de gérer automatiquement les requêtes crossdomaines
 * - Il permet de gérer automatiquement le sablier d'attente
 *
 * L'instance pEvent (Objet benchmark.framework.util.Event) contient les paramètres suivant :
 * (cela peut varier en fonction des différents événements)
 * - xhr
 * - id
 * - json
 * - msg
 * - currentTarget
 *	
 * <code>
 *	
 *	jQuery(function($){ 
 *
 *		   	$("a.envoyer[@f_ajax]").bind("click", function(){
 *				benchmark.framework.net.ObjControleurAjax3.appelScriptAction(
 *					this,
 *					// Attention, les paramètres supplémentaires directement ajoutés dans l'URL doivent être encodés avec encodeURIComponent()
 *					monurl+separateur+'f_param='+encodeURIComponent($("#montext").val()),
 *					{
 *						COMPLET: 'DEFAUT',
 *						SUCCES: [ecouteurPersoSucces1, 'DEFAUT'],
 *						//AVANT_ENVOI: [ecouteurPersoAvantEnvoi],
 *						ERREUR: 'DEFAUT'
 *					},
 *					{ // Données supplémentaires envoyées au contrôleur
 *						'from_client':$("#montext").val(),
 *						'vctrla':3,
 *						'test_object': {
 *							'titi':'toto',
 *							'tutu':{
 *								'toutou':'chien',
 *								'tata':'tante'
 *							}
 *						},
 *						'test_array':
 *							['mon chien', ['mon poison rouge', 'mon chat'], 'mon lapin']
 *					}
 *				);
 *				return false;
 *			});
 *
 *	});
 * </code>
 * @version $Id:$
 */

 /**
  * Le constructeur de la classe. Chaque Url d'action a son propre objet dédié a sa gestion
  * @param String pUrlAction l'url d'appl ajax
  * @param json pDonneeSupplementaire Données supplémentaires que le contrôleur doit envoyer à l'action.
  */
benchmark.framework.net.ObjControleurAjax3 = function(pUrlAction, pDonneeSupplementaire) {
	this._urlAction = pUrlAction; // Url de la requête Ajax
	this._urlActionDejaLance = false; // détermine si la requête est en cours ou pas
	this._eventDispatcher = new benchmark.framework.util.EventDispatcher();
	this._idRequete = benchmark.framework.net.ObjControleurAjax3.getIdRequete(pUrlAction, pDonneeSupplementaire); // identifiant de la requête ajax
	this._crossDomain = false; // dit si la requête est crossdomain ou non
	this._curElem = null; // element DOM associé à la requête courante
	this._pDonneeSupplementaire = pDonneeSupplementaire; // Mise en place des données supplémentaires
	// détermine si on est cross domain ou pas
	var domaine_courant = document.location.toString();
	domaine_courant = domaine_courant.substring(0, domaine_courant.indexOf("/", 7));
	var domaine_url_action = this._urlAction;
	if(this._urlAction.indexOf("/") == 0){
		domaine_url_action = domaine_courant;
	}else{
		domaine_url_action = domaine_url_action.substring(0, domaine_url_action.indexOf("/", 7));
	}
	if(domaine_courant != domaine_url_action){
		this._crossDomain = true;
	}else{
		this._crossDomain = false;
	}
};

/**#@+
 * les constantes definissant les evenements lié à l'ObjGestionAjax
 */
/**
 * Liste des événements utilisés dans une requête Ajax
 *
 * - COMPLET : est lancé quand le script ajax est fini d'execute
 * - SUCCES : est lancé quand le script ajax est fini d'execute avec succès
 * - ERREUR : est lancé quand le script ajax est fini d'execute
 * - AVANT_ENVOI : est lancé quand le script ajax est fini d'execute
 *
 *
 * L'objet d'evenement associé a les attributs suivant : 
 * - evt.type => le type d'evenement (ici COMPLET)
 * - evt.xhr => l'objet XmlHttpRequest associe
 * - evt.msg => le message de retour
 * - evt.target => la cible d'envoi (le dispatcher)
 * - evt.currentTarget => l'element DOM appelant
 */
benchmark.framework.net.ObjControleurAjax3.EVENEMENT = {
	"COMPLET":"COMPLET",
	"SUCCES":"SUCCES",
	"ERREUR":"ERREUR",
	"AVANT_ENVOI":"AVANT_ENVOI"
};

/**
 * attribut statique contenant la referance au objet creer via la methode get
 */
benchmark.framework.net.ObjControleurAjax3.ECOUTEURPARDEFAUT = 'DEFAUT';
/**#@-*/

/**
 * attribut statique contenant la reference au objet creer via la methode get
 */
benchmark.framework.net.ObjControleurAjax3.listeInstance = {};

/**
 * attribut statique contenant une reference plus réduite que l'id de la requete
 */
benchmark.framework.net.ObjControleurAjax3.listeIdReduitRequete = new Array();

/**
 * attribut statique contenant le nom du parametre permettant de définir un callback pour le getScript (écouteur SUCCESS)
 */
benchmark.framework.net.ObjControleurAjax3.PARAM_JSON_CALLBACK = 'jsoncallback';

/**
 * attribut statique contenant le nom du parametre permettant de transmettre l'id réduit de la requête Ajax
 */
benchmark.framework.net.ObjControleurAjax3.PARAM_ID_REQUETE = 'pa_idreqajax';

/**
 * Methode statique permettant de recuperer une instance d'ObjControleurAjax3 en fonction d'une url d'action
 * @param string pUrlAction URL de l'action
 * @param json pEvtHandler Liste des handler pour les évènements de la requête Ajax.
 * - Si on ne définit pas de handler, la classe utilisera celui par défaut.
 * - Pour ne pas exécuter de handler il suffit de définir sa valeur à chaîne vide ou null.
 * @param json pDonneeSupplementaire Données supplémentaires que le contrôleur doit envoyer à l'action.
 */
benchmark.framework.net.ObjControleurAjax3.get = function(pUrlAction, pEvtHandler, pDonneeSupplementaire){
	var id_requete = benchmark.framework.net.ObjControleurAjax3.getIdRequete(pUrlAction, pDonneeSupplementaire);
	
	if(!benchmark.framework.net.ObjControleurAjax3.listeInstance[id_requete]){
		var instance = new benchmark.framework.net.ObjControleurAjax3(pUrlAction, pDonneeSupplementaire);
		// On stock l'indentifiant réduit de la requête
		benchmark.framework.net.ObjControleurAjax3.listeIdReduitRequete.push(id_requete) ;
		for(var type in pEvtHandler){
			instance.removeEventListener(type);
			instance.addEventListener(type, pEvtHandler[type]);
		}
		benchmark.framework.net.ObjControleurAjax3.listeInstance[id_requete] = instance;
	}
	return benchmark.framework.net.ObjControleurAjax3.listeInstance[id_requete];
};

/**
 * Methode statique permettant de recuperer une instance d'ObjControleurAjax3 en fonction de son ID réduit
 * @param integer idReduitRequete id Reduit de la Requete
 * @return ObjControleurAjax3|false instance de controleur Ajax si elle existe sinon false
 */
benchmark.framework.net.ObjControleurAjax3.getFromIdReduitRequete = function(idReduitRequete){
	if(benchmark.framework.net.ObjControleurAjax3.listeInstance[benchmark.framework.net.ObjControleurAjax3.listeIdReduitRequete[idReduitRequete]] == null){
		return false;
	}
	return benchmark.framework.net.ObjControleurAjax3.listeInstance[benchmark.framework.net.ObjControleurAjax3.listeIdReduitRequete[idReduitRequete]];
};

/**
 * Methode static permettant de déréférencer un objet ObjControleurAjax3
 * @param string pUrlAction URL de l'action
 * @param json pDonneeSupplementaire Données supplémentaires que le contrôleur doit envoyer à l'action.
 */
benchmark.framework.net.ObjControleurAjax3.supprime = function(pUrlAction, pDonneeSupplementaire){
	var id_requete = benchmark.framework.net.ObjControleurAjax3.getIdRequete(pUrlAction, pDonneeSupplementaire);
	if(benchmark.framework.net.ObjControleurAjax3.listeInstance[id_requete]){
		delete benchmark.framework.net.ObjControleurAjax3.listeInstance[id_requete];
	}
};

/**
 * Methode static permettant de convertir récursivement un Object en chaîne pour le transmettre dans une URL
 * Les données sont encodées avec la fonction encodeURIComponent()
 */
benchmark.framework.net.ObjControleurAjax3.objectToUrlParam = function(pNomObject, pDonneeObject){
	var url = '';
	if(typeof(pDonneeObject) == "object"){
		for(var key_pDonneeObject in pDonneeObject){
			if(typeof(pDonneeObject[key_pDonneeObject]) == "object"){
				if(pNomObject == null){
					url = url + benchmark.framework.net.ObjControleurAjax3.objectToUrlParam(key_pDonneeObject, pDonneeObject[key_pDonneeObject]);
				}else{
					url = url + benchmark.framework.net.ObjControleurAjax3.objectToUrlParam(pNomObject + '[' + key_pDonneeObject + ']', pDonneeObject[key_pDonneeObject]);
				}
			}else{
				if(pNomObject != null){
					url = url + '&' + pNomObject + '[' + key_pDonneeObject + ']=' + encodeURIComponent(pDonneeObject[key_pDonneeObject]);
				}else{
					url = url + '&' + key_pDonneeObject + '=' + encodeURIComponent(pDonneeObject[key_pDonneeObject]);
				}
			}
		}
		return url;
	}
};

/**
 * Methode statique permettant de recuperer une instance d'ObjControleurAjax3 en fonction d'une url d'action
 * @param DOM pCurElem élément du dom sur lequel nous avons cliqué
 * @param string pUrlAction URL de l'action
 * @param json pEvtHandler Liste des handler pour les évènements de la requête Ajax.
 * - Si on ne définit pas de handler, aucun ne sera appelé. Il est possible d'appeler les handler par défaut en utilisant la
 * constante de classe benchmark.framework.net.ObjControleurAjax3.ECOUTEURPARDEFAUT.
 * - Les écouteurs en sont pas des chaînes de caractères mais des fonctions. Ils ne doivent pas être mise entre simple ou double quote.
 * - Pour les requêtes cross domain, si l'écouteur de l'événement SUCCES n'est pas définit ici, c'est celui définit dans le contrôleur 
 * Ajax PHP qui est appelé (si la méthode ->setCallBack est appelée). Néanmoins il est préférable de définir l'écouteur en JavaScript
 * @param json pDonneeSupplementaire Données supplémentaires que le contrôleur doit envoyer à l'action. Ces données ainsi que les paramètres 
 * présent dans l'URL seront envoyés, si possible en POST. La différence avec les paramètres présent dans l'URL, c'est que tous les caractères
 * sont autorisés dans les données supplémentaires par exemple le "&".
 * Les données supplémentaires ont la priorité par rapport aux paramètres présent dans l'URL 
 * @param boolean asynchrone Détermine si la requête Ajax est asynchrone ou pas. Par défaut, elle est asynchrone. Les requêtes synchrones
 * sont utiles lorsqu'elles sont exécutée sur l'événement unload de la page par exemple.
 * @param integer alerte_duree Détermine au bout de combien de miliseconde une requête GetScript (inter-domaine) 
 * est considérée comme en échec. Par défaut c'est 5000ms.
 */
benchmark.framework.net.ObjControleurAjax3.appelScriptAction = function(pCurElem, pUrlAction, pEvtHandler, pDonneeSupplementaire, asynchrone, alerte_duree){
	return benchmark.framework.net.ObjControleurAjax3.get(
		pUrlAction, 
		pEvtHandler,
		pDonneeSupplementaire
	).appelScript(
		pCurElem, 
		asynchrone, 
		alerte_duree
	);
};
	
/**
 * Permet de calculer l'identifiant de la requête Ajax en fonction de son URL action
 * @param string pUrlAction URL de l'action
 * @param json pDonneeSupplementaire Données supplémentaires que le contrôleur doit envoyer à l'action.
 * @return string id de la requête
 */
benchmark.framework.net.ObjControleurAjax3.getIdRequete = function(pUrlAction, pDonneeSupplementaire){
	// calcul de l'ID de la requête Ajax
	// on réduit un peu la longueur de la requete en enlevant les caractères qui ne semblent pas déterminant pour l'unicité
	return (pUrlAction + benchmark.framework.net.ObjControleurAjax3.objectToUrlParam(null, pDonneeSupplementaire)).replace(
		/[&\[\]%=\/:.?]/g,
		function(match){
			return '';
		}
	);
};

/**#@+
 * écouteurs par défaut
 */

/**
 * Handler par défaut pour l'événement AVANT_ENVOI
 * @param benchmark.framework.util.Event pEvent Instance de l'événement de la requête Ajax courante
 */
benchmark.framework.net.ObjControleurAjax3.handlerEvtAvant_envoi = function(pEvent){
	// Suppression des messages précédents
	$("#message_de_confirmation").remove();
	$("#message_de_confirmation_alerte").remove();
	$("#message_de_confirmation_erreur").remove();

	// Affichage du sablier si on est capable de déterminer la position de l'élément.
	if (!$(pEvent.currentTarget).findPos){
		return;
	}else{
		var coords = $(pEvent.currentTarget).findPos();
	}
	// Si la tétière est présente, on décale de 92 pixel vers le haut
	/** @todo voir si ce décalage est encore utile ? */
	var offset_y = -12;
	if($("#tetiere-box").get()[0]){
		offset_y = -92;
	}
	// Affichage du sablier
	$("body").append("<img id=\"ajax_icone_chargement_"+pEvent.id+"\" style=\"float:left; z-index:1000; position:absolute; top:"+(coords.y+offset_y)+"px; left:"+(coords.x-25)+"px;\" src=\"/framework/lib/js/image/chargement.gif\"/>");
};

/**
 * Handler par défaut pour l'événement COMPLET
 * @param benchmark.framework.util.Event pEvent Instance de l'événement de la requête Ajax courante
 */
benchmark.framework.net.ObjControleurAjax3.handlerEvtComplet = function(pEvent){
	$("img[id='ajax_icone_chargement_"+pEvent.id+"']").remove();
	// Test la validitée du formatage de la réponse
	if(pEvent.xhr == null){
		return true;
	}else if(typeof(pEvent.xhr) == "object" && pEvent.xhr.type == "GET"){
		return true;
	}else if(typeof(pEvent.xhr) == "object" && typeof(pEvent.xhr.responseText) == "string") {
		// XmlHttpRequest
		if(pEvent.xhr.responseText.indexOf("code_retour") != 2){
			alert("Une erreur de donnée empêche l'exécution de votre action !\n");
			// On stop le traitement de la requête Ajax
			pEvent.xhr.abort();
		}
	} else if(typeof(pEvent.xhr) == "object" && typeof(pEvent.xhr.code_retour) == "string") {
		// JSon
		return true;
	} else if(typeof(pEvent.xhr) == "string") {
		// Chaine
		if(pEvent.xhr.indexOf("code_retour") != 2){
			alert("Une erreur de donnée empêche l'exécution de votre action !\n");
		}
	} else {
		alert("Une erreur de donnée empêche l'exécution de votre action !\n");
	}
};

/**
 * Handler par défaut pour l'événement SUCCES
 * 
 * L'ID css "message_de_confirmation" est utilisé pour l'affichages des blocs de confirmation.
 * Dans les cas ou le code de retour est 0 (erreur) alors c'est l'ID "message_de_confirmation_alerte" qui est utilisé
 * 
 * @param benchmark.framework.util.Event pEvent Instance de l'événement de la requête Ajax courante
 */
benchmark.framework.net.ObjControleurAjax3.handlerEvtSucces = function(pEvent){
	var id_message = "message_de_confirmation";

	// On test le retour de l'action
	if(pEvent.json.code_retour == "0"){
		id_message = "message_de_confirmation_alerte";
	}
	$("body").prepend("<span id=\""+id_message+"\" href=\"javascript: void(0);\" onclick=\"this.style.display='none'\" alt=\"fermer\" title=\"fermer\"><pre>"+pEvent.json.message_retour+"</pre><br></span>");
};

/**
 * Handler par défaut pour l'événement ERREUR
 * @param benchmark.framework.util.Event pEvent Instance de l'événement de la requête Ajax courante
 */
benchmark.framework.net.ObjControleurAjax3.handlerEvtErreur = function(pEvent){
	// Traitement des erreurs en fonction des codes HTTP
	// Les codes gérés par la classes ObjControleurAjax3 sont les suivants : 200, 400, 403, 404, 407 et 500
	if(pEvent.xhr.status == 500){
		alert("Erreur : Erreur interne !\n");
	}else if(pEvent.xhr.status != 200){
		alert("Une erreur empêche l'exécution de votre action !\n");
	}else{
		// Le status est égal à 200 donc pas de problème mais JQuery appel tout de même cette méthode callback
		// ??????????????
		//alert("Une erreur incompréhensible empêche l'exécution de votre action !\n");
	}
};

/**
 * Handler des appels jsonp permettant de dispatcher l'événement success sur les autres handler délcarés
 * @param json json Object json contenant le message du serveur
 * @param integer idReduitRequete Id de la requête Ajax dans sa version réduite
 */
benchmark.framework.net.ObjControleurAjax3._handlerEvtSuccessDispatcher = function(json, idReduitRequete){
	// On récupère l'instance courante du controelur Ajax
	var instance = benchmark.framework.net.ObjControleurAjax3.getFromIdReduitRequete(idReduitRequete);
	var evt = new benchmark.framework.util.Event(benchmark.framework.net.ObjControleurAjax3.EVENEMENT.AVANT_ENVOI);
	evt.xhr = null;
	evt.id = instance._idRequete;
	evt.msg = '';
	evt.json = json;
	evt.type = benchmark.framework.net.ObjControleurAjax3.EVENEMENT.SUCCES;
	evt.currentTarget = instance._curElem;

	// On appel les différents handleurs getScript
	instance.dispatchEvent(evt);
};

benchmark.framework.net.ObjControleurAjax3.prototype = {
	
	/**
	 * cette methode est appelé pour controler que plusieurs appels
	 * d'une même url action ne se fait pas en meme temps
	 * @param DOM pCurElem élément du dom sur lequel nous avons cliqué
	 * @param json pDonneeSupplementaire Données supplémentaires que le contrôleur doit envoyer à l'action. Ces données ainsi que les paramètres 
	 * présent dans l'URL seront envoyés, si possible en POST. La différence avec les paramètres présent dans l'URL, c'est que tous les caractères
	 * sont autorisés dans les données supplémentaires par exemple le "&".
	 * @param boolean asynchrone Détermine si la requête Ajax est asynchrone ou pas. Par défaut, elle est asynchrone. Les requêtes synchrones
	 * sont utiles lorsqu'elles sont exécutée sur l'événement unload de la page par exemple.
	 * @param integer alerte_duree Détermine au bout de combien de miliseconde une requête GetScript (inter-domaine) 
	 * est considérée comme en échec. Par défaut c'est 5000ms.
	 */
	appelScript: function (pCurElem, asynchrone, alerte_duree) {
		if(!this._urlActionDejaLance){ // aucune requête identique n'est en cours
			this._urlActionDejaLance = true;
			this._curElem = pCurElem;
			// détermine si des paramètres sont présents ou pas
			var separation = this._urlAction.indexOf("?");
			// Url complété appelée
			var url = null;

			if(this._crossDomain == true){
				// Domaines différents => on utilise getScript
				// Création de l'événement utilisé par les différentes étapes de la requête getScript
				var evt = new benchmark.framework.util.Event(benchmark.framework.net.ObjControleurAjax3.EVENEMENT.AVANT_ENVOI);
				evt.xhr = null;
				evt.id = this._idRequete;
				evt.msg = '';
				evt.currentTarget = pCurElem;

				//beforeSend:
				evt.type = benchmark.framework.net.ObjControleurAjax3.EVENEMENT.AVANT_ENVOI;
				this.dispatchEvent(evt);
				
				// Variable utilisée pour détecter certaines erreurs du getScript
				var getScript_ok = 'ko';
				
				// Si des callback sont définit pour l'événement success alors on l'ajout à l'URL
				var callBackName = ''; // Nom de l'écouteur
				url = this._urlAction;
				// On complète l'URL avec l'écouteur pour l'événement SUCCESS
				if(this.hasEventListener(benchmark.framework.net.ObjControleurAjax3.EVENEMENT.SUCCES)){
					var separateur = '&';
					if(separation == -1){
						separateur = '?';
					}

					// On ajoute le nom du callback
					url = url + separateur + benchmark.framework.net.ObjControleurAjax3.PARAM_JSON_CALLBACK + '=' + 'benchmark.framework.net.ObjControleurAjax3._handlerEvtSuccessDispatcher';

					// Récupération de l'ID requête dans sa version réduite
					for (idReduit in benchmark.framework.net.ObjControleurAjax3.listeIdReduitRequete) {
						if (benchmark.framework.net.ObjControleurAjax3.listeIdReduitRequete[idReduit] == this._idRequete) {
							// On ajoute l'ID de la requête
							url = url + '&' + benchmark.framework.net.ObjControleurAjax3.PARAM_ID_REQUETE + '=' + idReduit;
							break;
						}
					}
				}
				// Ajout des données supplémentaires
				if(typeof(this._pDonneeSupplementaire) == "object"){
					url = url + benchmark.framework.net.ObjControleurAjax3.objectToUrlParam(null, this._pDonneeSupplementaire);
				}

				$.getScript(url, benchmark.framework.util.delegate(this, function(){
					getScript_ok = 'ok';
					//complete
					evt.type = benchmark.framework.net.ObjControleurAjax3.EVENEMENT.COMPLET;
					this.dispatchEvent(evt);
				}));

				if(!(alerte_duree>0)){
					alerte_duree = 5000;
				}
				setTimeout(function(){
					if(getScript_ok == 'ko'){
						//error
						evt.type = benchmark.framework.net.ObjControleurAjax3.EVENEMENT.ERREUR;
						this.dispatchEvent(evt);
					}
				}, alerte_duree);
				// la requête n'est plus en cours
				this._urlActionDejaLance = false;
			
			}else{
				var donnee = {};
				// Test si des paramètres sont présents
				if(separation != -1){
					url = this._urlAction.substring(0, separation);
					donnee = benchmark.framework.chaine.ObjChaine.urlParamToJson(this._urlAction.substring(separation+1, this._urlAction.length));
				}else{
					url = this._urlAction;
				}
				// Ajout des données supplémentaires
				for (var i_fusion in this._pDonneeSupplementaire){
					donnee[i_fusion] = this._pDonneeSupplementaire[i_fusion];
				}

				// asynchrone ou pas ?
				if(asynchrone != false){
					asynchrone = true;
				}
				// Domaines identiques => on lance une requête Ajax classqiue
				$.ajax({
					type: "POST",
					dataType: "json",
					url: url,
					async: asynchrone,
					data: benchmark.framework.net.ObjControleurAjax3.objectToUrlParam(null,donnee),
					beforeSend: benchmark.framework.util.delegate(this, function(xhr){
							var evt = new benchmark.framework.util.Event(benchmark.framework.net.ObjControleurAjax3.EVENEMENT.AVANT_ENVOI);
							evt.xhr = xhr;
							evt.id = this._idRequete;
							evt.currentTarget = pCurElem;
							this.dispatchEvent(evt);
					}),
					complete: benchmark.framework.util.delegate(this, function(xhr, msg){
							var evt = new benchmark.framework.util.Event(benchmark.framework.net.ObjControleurAjax3.EVENEMENT.COMPLET);
							evt.xhr = xhr;
							evt.id = this._idRequete;
							evt.msg = msg;
							evt.currentTarget = pCurElem;
							this.dispatchEvent(evt);
							this._urlActionDejaLance = false;
					}),
					success: benchmark.framework.util.delegate(this, function(json){
							var evt = new benchmark.framework.util.Event(benchmark.framework.net.ObjControleurAjax3.EVENEMENT.SUCCES);
							evt.json = json;
							evt.id = this._idRequete;
							evt.currentTarget = pCurElem;
							this.dispatchEvent(evt);
					}),
					error: benchmark.framework.util.delegate(this, function (xhr, msg, exception){
						if(xhr.status != 200) {
							var evt = new benchmark.framework.util.Event(benchmark.framework.net.ObjControleurAjax3.EVENEMENT.ERREUR);
							evt.xhr = xhr;
							evt.id = this._idRequete;
							evt.msg = msg;
							evt.currentTarget = pCurElem;
							evt.exception = exception;
							this.dispatchEvent(evt);
						}
					})
				});
			}
		}
	},

	/**
	 * permet d'ajouter un ecouteur pour un evenement donnée au gestionnaire d'evenement
	 * @param pEventType string le type d'evenement ecouté
	 * @param string|array pFunction nom ou tableau de nom de fonction pour l'ecouteur
	 * @return boolean true si l'ecouteur n'est pas déja present et est bien ajouté, false sinon
	 */
	addEventListener: function(pEventType, pFunction){
		// La fonction ne travail que sur des tableaux pour éviter la duplication de code
		if (!(pFunction instanceof Array)){
			pFunction = new Array(pFunction);
		}
		// On traite tous les handler définit
		for(var cur_i_pFunction in pFunction){
			if(typeof(pFunction[cur_i_pFunction]) == 'string' && pFunction[cur_i_pFunction] == benchmark.framework.net.ObjControleurAjax3.ECOUTEURPARDEFAUT){
				// Gestion des écouteurs par défaut.
				switch (pEventType) {
					case benchmark.framework.net.ObjControleurAjax3.EVENEMENT.COMPLET:
						cur_pFunction = benchmark.framework.net.ObjControleurAjax3.handlerEvtComplet;
						break;
					case benchmark.framework.net.ObjControleurAjax3.EVENEMENT.SUCCES:
						cur_pFunction = benchmark.framework.net.ObjControleurAjax3.handlerEvtSucces;
						break;
					case benchmark.framework.net.ObjControleurAjax3.EVENEMENT.ERREUR:
						cur_pFunction = benchmark.framework.net.ObjControleurAjax3.handlerEvtErreur;
						break;
					case benchmark.framework.net.ObjControleurAjax3.EVENEMENT.AVANT_ENVOI:
						cur_pFunction = benchmark.framework.net.ObjControleurAjax3.handlerEvtAvant_envoi;
						break;
				}
			}else if(typeof(pFunction[cur_i_pFunction]) == 'function'){
				cur_pFunction = pFunction[cur_i_pFunction];
			}else{
				//alert('écouteur invalide');
				return false;
			}
			// On associe effectivement l'écouteur à l'événement
			if(this._eventDispatcher.addEventListener(pEventType, cur_pFunction) == false){
				return false;
			}
		}
		return true;
	},
	
	/**
	 * permet de supprimer un ecouteur pour un evenement donnée au gestionnaire d'evenement
	 * @param pEventType string le type d'evenement ecouté
	 * @param pFunction function l'ecouteur
	 * @return boolean true si l'ecouteur a bien été supprimé
	 */
	removeEventListener: function(pEventType, pFunction){
		if ( pFunction instanceof Array ){
			for(var cur_pFunction in pFunction){
				return this._eventDispatcher.removeEventListener(pEventType, cur_pFunction);
			}
		}else{
			return this._eventDispatcher.removeEventListener(pEventType, pFunction);
		}
	},
	
	/**
	 * permet de diffuser un evenement
	 * @param pEvent Event l'objet Evenement a diffuser
	 */
	dispatchEvent: function(pEvent){
		this._eventDispatcher.dispatchEvent(pEvent);
	},
	
	/**
	 * permet de verifier la presence d'ecouteur pour un evenement donnée
	 * si pFunction est renseigné, on verifie si l'ecouteur pFunction ecoute l'evenement pEventType
	 * @param pEventType string le type d'evenement ecouté
	 * @param pFunction function (optionnel) l'ecouteur
	 * @return boolean true si il y a des ecouteurs ou si l'ecouteur ecoute effectivement sur l'evenement
	 */
	hasEventListener: function(pEventType, pFunction){
		return this._eventDispatcher.hasEventListener(pEventType, pFunction);
	}
	
};
