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'ObjControleurAjax permet de gerer les appels ajax et eviter les appels multiple d'une meme ajax
 *
*	 function _ecouteurComplet(pEvent){}
*	function _ecouteurErreur(pEvent){}
*	function _ecouteurAvantEnvoi(pEvent){}
*	function _ecouteurSucces(pEvent){$(pEvent.currentTarget).after(pEvent.json.message_retour)}	
*		
*	jQuery(function($){ 
*
*		   	$("a.envoyer[@f_ajax]").bind("click",function(){
*				benchmark.framework.net.ObjControleurAjax.appelScriptAction(
*					this,
*					$(this).attr('f_ajax'),
*					{
*						COMPLET: _ecouteurComplet,
*						SUCCES: _ecouteurSucces,
*						AVANT_ENVOI: _ecouteurAvantEnvoi,
*						ERREUR: _ecouteurErreur
*					}
*				);
*				return false;
*			});
*
*	});
* @author Pierre Chabiland
* @since 17/10/2008
 */

 /**
  * Le constructeur de la classe. Chaque Url d'action a sont propre objet dédié a sa gestion
  * @param String pUrlAction l'url d'appl ajax
  */
benchmark.framework.net.ObjControleurAjax = function(pUrlAction) {
	this._urlAction = pUrlAction;
	this._urlActionDejaLance = false;
	this._ajaxEnCours = new Array();
	this._eventDispatcher = new benchmark.framework.util.EventDispatcher();
};

/**
 * les constantes definissant les evenements lié à l'ObjGestionAjax
 */
/**
 * COMPLET 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.ObjControleurAjax.COMPLET = "COMPLET";

/**
 * COMPLET 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.json => le retour json de la requete
 * evt.target => la cible d'envoi (le dispatcher)
 * evt.currentTarget => l'element DOM appelant
 */
benchmark.framework.net.ObjControleurAjax.SUCCES = "SUCCES";

/**
 * ERREUR 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 ERREUR)
 * evt.xhr => l'objet XmlHttpRequest associe
 * evt.msg => le message de retour
 * evt.exception => l'exception relevé
 * evt.target => la cible d'envoi (le dispatcher)
 * evt.currentTarget => l'element DOM appelant
 */
benchmark.framework.net.ObjControleurAjax.ERREUR = "ERREUR";

/**
 * 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 AVANT_ENVOI)
 * evt.xhr => l'objet XmlHttpRequest associe
 * evt.target => la cible d'envoi (le dispatcher)
 * evt.currentTarget => l'element DOM appelant
 */
benchmark.framework.net.ObjControleurAjax.AVANT_ENVOI = "AVANT_ENVOI";


/**
 * attribut statique contenant la referance au objet creer via la methode get
 */
benchmark.framework.net.ObjControleurAjax.listeInstance = {};


/**
 * Methode statique permettant de recuperer une instance d'ObjControleurAjax en fonction d'une url d'action
 */
benchmark.framework.net.ObjControleurAjax.get = function(pUrlAction,pEvt){
	var id_requete;
	// calcul de l'ID de la requête Ajax
	id_requete = pUrlAction.replace(
		/[^a-zA-Z0-9]/g,
		function(match){
			return '';
		}
	);
	
	if(!benchmark.framework.net.ObjControleurAjax.listeInstance[id_requete]){
		var instance = new benchmark.framework.net.ObjControleurAjax(pUrlAction);
		for(var type in pEvt){
			instance.removeEventListener(type);
			instance.addEventListener(type,pEvt[type]);
		}
		benchmark.framework.net.ObjControleurAjax.listeInstance[id_requete] = instance;
	}
	
	return benchmark.framework.net.ObjControleurAjax.listeInstance[id_requete];
};

/**
 * Methode static permettant de deferencer un objet ObjControleurAjax
 */
benchmark.framework.net.ObjControleurAjax.supprime = function(pUrlAction){
	var id_requete;
	// calcul de l'ID de la requête Ajax
	id_requete = pUrlAction.replace(
		/[^a-zA-Z0-9]/g,
		function(match){
			return '';
		}
	);
	if(benchmark.framework.net.ObjControleurAjax.listeInstance[id_requete]){
		delete benchmark.framework.net.ObjControleurAjax.listeInstance[id_requete];
	}
};

/**
 * Methode statique permettant de recuperer une instance d'ObjControleurAjax en fonction d'une url d'action
 */
benchmark.framework.net.ObjControleurAjax.appelScriptAction = function(pCurElem,pUrl,pEvt){
	return benchmark.framework.net.ObjControleurAjax.get(pUrl,pEvt).appelScript(pCurElem);
};
	

benchmark.framework.net.ObjControleurAjax.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'element dom appelant l'action ajax
	 */
	appelScript: function (pCurElem) {
		if(!this._urlActionDejaLance){
			this._urlActionDejaLance = true;
	
			var separation = this._urlAction.indexOf("?");
			var url = null;
			var donnee = null;
			if(separation != -1){
				url = this._urlAction.substring(0, separation);
				donnee = this._urlAction.substring(separation+1, this._urlAction.length)
			}else{
				url = this._urlAction;
			}
			$.ajax({
				type: "POST",
	
				dataType: "json",
				
				url: url,
				
				data: donnee,
	
				beforeSend: benchmark.framework.util.delegate(this,function(xhr){
						var evt = new benchmark.framework.util.Event(benchmark.framework.net.ObjControleurAjax.AVANT_ENVOI);
						evt.xhr = xhr;
						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.ObjControleurAjax.COMPLET);
						evt.xhr = xhr;
						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.ObjControleurAjax.SUCCES);
						evt.json = json;
						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.ObjControleurAjax.ERREUR);
						evt.xhr = xhr;
						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 pFunction function l'ecouteur
	 * @return boolean true si l'ecouteur n'est pas déja present et est bien ajouté, false sinon
	 */
	addEventListener: function(pEventType,pFunction){
		return this._eventDispatcher.addEventListener(pEventType,pFunction);
	},
	
	/**
	 * 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){
		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);
	}
	
}
