
// Colin JACQUELIN, le 06/03/06

var Ajax = {
  Version: '0.1'
};



Ajax.Requete = function(_variable1, _variable2, _variable3){

	// Constructeur	
	// Initialise l'objet XMLHttpRequest "requete" par la fonction "_initRequete"
	// et les deux listes d'écouteurs d'evenements.
	this._initRequete();
	this.listenersOnSuccess = new Array();
	this.listenersOnFailure = new Array();
	this.variable1 = _variable1;
	this.variable2 = _variable2;
	this.variable3 = _variable3;
};

Ajax.Requete.prototype = {
	// Objet XMLHttpRequest central
	requete: null,
	// Booléen indiquant si une requete a déjà été envoyée par cet objet
	requeteEnvoye: false,
	
	// Fonction qui est appellée pour afficher le panneau d'attente.
	// Par défaut, est vide.
	// Si l'utilisateur spécifie un panneau d'attente
	// alors la fonction "setAffichageAttenteChargement" construira cette fonction
	afficherAttenteChargement: function() {},
	// Fonction qui est appellée pour masquer le panneau d'attente.
	// Par défaut, est vide.
	// Si l'utilisateur spécifie un panneau d'attente
	// alors la fonction "setAffichageAttenteChargement" construira cette fonction
	masquerAttenteChargement: function() {},
	
	// Tableau contenant les écouteurs des succès et des échecs
	listenersOnSuccess: null,
	listenersOnFailure: null,
	

	// Initialisation de l'objet requete
	_initRequete: function() {
		try {
			// Pour IE
			this.requete = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try {
				// Pour IE
				this.requete = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (E) {
				this.requete = false;
			}
		}
		if (!this.requete && typeof XMLHttpRequest != 'undefined'){
			try {
				// Pour Mozilla / Firefox / ...
				this.requete = new XMLHttpRequest();
			}catch (e) {
				this.requete = false;
			}
		}
		
		// Force le masquage du panneau d'attente
		this.masquerAttenteChargement();
	},
	
	
	// Construction et envoi d'un formulaire
	// Délègue le patie "envoi" à la fonction "envoyerRequete"
	envoyerFormulaire: function(methode, action, idForm) {
		// Vérifie que le formulaire existe bien
		if(idForm == null)
			throw "Le formulaire n'a pas ete specifie";
		
		// Construit les paramètres de la requete en foncvtion du contenu des
		// champs du formulaire.
		// Si un champ n'a pas de valeur, alors il ne sera pas ajouter en paramètre de requete.
		var form = document.getElementById(idForm);
		var param = "";
		for(var i = 0; i < form.length; i++) {
			var champ = form[i];
			var valeur = champ.value;
			var nom = champ.name;
			
			if(valeur != "") {
				param += nom + "=" + escape(valeur) + "&";
			}
		}
		
		// Supprime le "&" final en trop
		if(param.length > 0) {
			param = param.substring(0, param.length - 1);
		}
		
		// Délègue l'envoi à la fonction "envoyerRequete"
		this.envoyerRequete(methode, action, param);
	},
	
	
	// Construction et envoi de la requete
	// exemples d'utilisation :
	//  * envoyerRequete("GET", "test.wadis?toto=titi", null, function(xml){...})
	//  * envoyerRequete("POST", "test.wadis" , "toto=titi", function(xml) {...})
	envoyerRequete: function(methode, action, param) {
		if(this.requete && !this.requeteEnvoye) {

			// On affiche la panneau d'attente
			this.afficherAttenteChargement();
			
			// Définit la fonction a éxecuter pour traiter la réponse
			this.requete.onreadystatechange = this.recevoirReponse();
			
			// Configure l'ouverture de la requete
			//1er argument : précise la méthode d'envoi : GET, POST ou bien HEAD
			//2ème argument : précise l'url où envoyer la requete. Pour un GET, il faut placer ici les paramètres
			//3ème argument : précise que c'est un flux asynchrone, non bloquant
			this.requete.open(methode, action, true);
		
			// Doit se faire obligatoirement après l'instruction "open"
			if(methode == "POST") {
				this.requete.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			}
		
			// envoi de la requete
			// Lors d'une requete POST, il faut placer ici le contenu de la requete
			// Lors d'une requete GET, ca ne sert à rien, mais c'est pourtant nécessaire pour
			// le bon fonctionnement sur certains browsers
			this.requete.send(param);
			
			this.requeteEnvoye = true;
			
		} else {
			// Cas qui ne devrait pas se produire car un objet requete ne peut servir qu'une seule fois
			// ou qu'il y'a eu un problème à l'initialisationde l'objet XMLHttprequest "requete".
			throw("Un objet requete ne peut servir qu'une seule fois.");
		}
	},
	
	
	// Gestionnaire de réponse de la requete
	// Est appellé à chaque changement d'état de l'objet XMLHttpRequest "requete"
	recevoirReponse: function() {
		var cetAjax = this;
		return function() {
		//	try {
				// On vérifie que la réponse est chargée et accessible
				if (cetAjax.requete.readyState == 4 || cetAjax.requete.readyState=="complete") {
					if (cetAjax.requete.status == 200) { // Code HTTP pour "page ok"
						//La réponse a bien été reçue	
						//alert(cetAjax.requete.responseText);
						var xmldoc = cetAjax.requete.responseXML;
												
						// On notifie du succès de la requete et on masque le panneau d'attente
						cetAjax.masquerAttenteChargement();
						cetAjax._fireSuccess(xmldoc);
					} else {
						// Il y'a eu un problème sur la requete
						var erreur = [];
						erreur[erreur.length] = cetAjax.requete.status;
						erreur[erreur.length] = "Problème survenu lors de la requete.";
						// On masque le panneau d'attente et on notifie les écouteurs de l'échec
						cetAjax.masquerAttenteChargement();
						cetAjax._fireFailure(erreur);
					}
				}
		//	} catch (e) {
		//		// Il y'a eu une exception, on notifie de l'échec et on masque le panneau d'attente
		//		var erreur = [];
		//		erreur[erreur.length] = cetAjax.requete.status;
		//		erreur[erreur.length] = "Problème survenu lors de la requete.";
		//		cetAjax.masquerAttenteChargement();
		//		cetAjax._fireFailure(erreur);
		//	}
		}
	},
	
	// Fonction privée qui notifie un succès aux écouteurs appropriés
	_fireSuccess: function(reponses) {
		for (var i = 0; i < this.listenersOnSuccess.length; i++) {
			this.listenersOnSuccess[i].apply(this, [reponses]);
		}
	},
	
	// Fonction privée qui notifie une erreur aux écouteurs appropriés
	_fireFailure: function(message) {
		for (var i = 0; i < this.listenersOnFailure.length; i++) {
			this.listenersOnFailure[i].apply(this, [message]);
		}
	},
	
	// Fonction qui permet de s'inscrire comme écouteur de succès
	registerOnSuccess: function(listener) {
		this.listenersOnSuccess.push(listener);
	},
	
	// Fonction qui permet de s'inscrire comme écouteur des erreurs
	registerOnFailure: function(listener) {
		this.listenersOnFailure.push(listener);
	},
	
	// Fonction qui permet de se désinscrire des écouteurs de succès
	unregisterOnSuccess: function(listener) {
		var i = 0;
		var n = 0;
		for( i = 0, n = 0; i < this.listenersOnSuccess.length; i++ ) {
			if( this.listenersOnSuccess[i] != listener ) {
				this.listenersOnSuccess[n++]=this.listenersOnSuccess[i];
			}
		}
		this.listenersOnSuccess.length -= (i-n);	
	},
	
	// Fonction qui permet de se désinscrire des écouteurs d'erreurs
	unregisterOnFailure: function(listener) {
		var i = 0;
		var n = 0;
		for( i = 0, n = 0; i < this.listenersOnFailure.length; i++ ) {
			if( this.listenersOnFailure[i] != listener ) {
				this.listenersOnFailure[n++]=this.listenersOnFailure[i];
			}
		}
		this.listenersOnFailure.length -= (i-n);	
	},
	
	// Fonction qui prend en charge l'affichage et le masquage de l'invitation à l'attente
	setAffichageAttenteChargement: function(tagId, tagIdCacheArray, temps) {
		// ID de la fonction d'attente qui affiche le panneau "WAIT" qu'à partir d'un temps donné
		var ID = null;
		
		// S'il n'y a pas de panneau d'attente alors on ne fait rien
		if(tagId == null || tagId == "")
			return;
		
		// Si le tag n'est pas bon
		var tag = document.getElementById(tagId);
		if (tag == null || tag == undefined)
			throw ("Le tag du panneau d'attente n'est pas valide");

		// Fonction appellée pour afficher l'attente, une fois la temporisation finie
		this.afficher = function() {
			alert("tag");
			tag.style.display = "block";
		}
		
		// fonction qui déclenche la temporisation avant l'affichage de l'attente
		this.afficherAttenteChargement = function() {
			if(tagIdCacheArray != null){
				for(var i=0; i<tagIdCacheArray.length; i++){
					document.getElementById(tagIdCacheArray[i]).style.display = 'none';
				}				
			}
			ID = setTimeout("document.getElementById('" + tagId + "').style.display = 'block';",temps);
		}
		
		// fonction qui cache l'attente, et qui tue la temporisation s'il y'en avait
		this.masquerAttenteChargement = function() {
			tag.style.display = "none";
			if(tagIdCacheArray != null){
				for(var i=0; i<tagIdCacheArray.length; i++){
					document.getElementById(tagIdCacheArray[i]).style.display = 'block';
				}				
			}
			if(ID != null) {
				clearTimeout(ID);
				ID = null;
			}
		}
		
		// Pour forcer l'initalisation du masquage du panneau d'attente
		this.masquerAttenteChargement();
	}
};
