/*
Copyright (c) 2007, PMP Concept
version: 1
*/

/*****************************************************************************
 *
 * 								Classe pmpAjax
 *
 *	Fonction : 	gestion de la communication client/server via AJAX
 *
 *  Paramètres
 *  	- url		: (string) fichier du script appelé
 *		- mode		: (string) method d'envoi POST ou GET
 *		- autosend  : (boolean) envoi automatiquement la requete au serveur 
 					  lors de l'ajout / modification des données
 *
*****************************************************************************/

PMP.util.pmpAjax = function(url, mode, autosend) 
{
	this.xhr = false;
	this.url = PMP.common.isString(url) ? url : new String() ;
	this.data = new Array();
	this.autoReset = false;
	this.autoSend = PMP.common.isBoolean(autosend) ? autosend : false;
	this.sendMethod = PMP.common.isString(mode) && (mode.toUpperCase() == "POST" || mode.toUpperCase() == "GET") ? mode : "POST";
	this.reponse = new PMP.util.pmpAjaxReponse(this.xhr);

	if (window.XMLHttpRequest) 
	{
		try 
		{ 
			this.xhr = new window.XMLHttpRequest(); 
		}
		catch (e) { return false; }
	} 
	else if (window.ActiveXObject)
	{
		var msXML = new Array(	"Msxml2.XMLHTTP.5.0",
								"Msxml2.XMLHTTP.4.0",
								"Msxml2.XMLHTTP.3.0",
								"Msxml2.XMLHTTP",
								"Microsoft.XMLHTTP");
		var nbMsXML = msXML.length;
		for (var i = 0; i < nbMsXML; i++) 
		{
			try 
			{
				this.xhr = new ActiveXObject(msXML[i]);
				break;
			}
			catch (e) { }
		}
		if (!this.xhr) { return false; }
	}

	this.xhr.onreadystatechange = (function () 
	{
		switch (this.xhr.readyState) {
			case 0 : this.uninitialized(this.xhr);
				break;

			case 1 : this.loading(this.xhr);
				break;

			case 2 : this.loaded(this.xhr);
				break;

			case 3 : this.interactive(this.xhr);
				break;

			case 4: this.complete(this.xhr);
				break;
		}
	}).bind(this);
}



PMP.util.pmpAjax.prototype.uninitialized	= new Function;
PMP.util.pmpAjax.prototype.loading		= new Function;
PMP.util.pmpAjax.prototype.loaded		= new Function;
PMP.util.pmpAjax.prototype.interactive	= new Function;
PMP.util.pmpAjax.prototype.complete		= new Function;

PMP.util.pmpAjax.prototype.autoResetOff = function ()	{ this.autoReset = false; }
PMP.util.pmpAjax.prototype.autoResetOn  = function ()	{ this.autoReset = true;  }
PMP.util.pmpAjax.prototype.autoSendOff  = function ()	{ this.autoSend  = false; }
PMP.util.pmpAjax.prototype.autoSendOn   = function ()	{ this.autoSend  = true;  }

PMP.util.pmpAjax.prototype.setSendMethod = function (method) 
{
	method = method.toUpperCase();
	switch(method)
	{
		case "GET": this.sendMethod = "GET";
		break;

		case "POST": this.sendMethod = "POST";
		break;

		default: this.sendMethod = "POST";
	}
}

PMP.util.pmpAjax.prototype.switchSendMethod = function() 
{
	if (this.sendMethod == "POST") 
		this.sendMethod = "GET";
	else 
		this.sendMethod = "POST";
}

PMP.util.pmpAjax.prototype.appendData = function (field, value)
{
	// si la variables est une valeur undefined, on ne fair rien
	if(PMP.common.isUndefined(value))
		return;

	// vérification de l'existence de la variable
	for (var i = 0; i < this.data.length; i++)
	{
		if (this.data[i]["field"] == field) 
		{
			this.data[i]["value"] = value.toString();
			return (this.autoSend) ? this.send() : true;
		}
	}
	// si la variable n'a pas été trouvé, on l'insère à la fin
	this.data.push(new Array());
	this.data[this.data.length - 1]["field"] = field;
	this.data[this.data.length - 1]["value"] = value.toString();
	return (this.autoSend) ? this.send() : true;
}

PMP.util.pmpAjax.prototype.resetData = function () 
{
	delete this.data;
	this.data = new Array();
	return true;
}

PMP.util.pmpAjax.prototype.prepareData = function () 
{
	var prepared = new String();
	for (var i = 0; i < this.data.length; i++) 
	{
		prepared += (i == 0 ? "" : "&") + encodeURIComponent(this.data[i]["field"]);
		prepared += "=" + encodeURIComponent(this.data[i]["value"]);
	}
	return prepared;
}

PMP.util.pmpAjax.prototype.setField = function (field, newField)
{
	for (var i = 0; i < this.data.length; i++)
	{
		if (this.data[i]["field"] == field) 
		{
			this.data[i]["field"] = newField;
			return (this.autoSend) ? this.send() : true;
		}
	}
	return false;
}

PMP.util.pmpAjax.prototype.deleteField = function (field) 
{
	var newData = new Array();
	var newIndex = 0;
	var deleted = false;
	for (var i = 0; i < this.data.length; i++) 
	{
		if (this.data[i]["field"] != field) 
		{
			newData.push(new Array());
			newData[newIndex]["field"] = this.data[i]["field"];
			newData[newIndex]["value"] = this.data[i]["value"];
			newIndex ++;
		} 
		else 
		{ 
			deleted = true;
		}
	}
	this.data = newData;
	return (deleted) ? ((this.autoSend) ? this.send() : true) : false;
}

PMP.util.pmpAjax.prototype.setValue = function (field, value) 
{
	for (var i = 0; i < this.data.length; i++) 
	{
		if (this.data[i]["field"] == field) 
		{
			this.data[i]["value"] = value;
			return (this.autoSend) ? this.send() : true;
		}
	}
	return false;
}

PMP.util.pmpAjax.prototype.deleteValue = function (field)
{
	for (var i = 0; i < this.data.length; i++)
	{
		if (this.data[i]["field"] == field) 
		{
			this.data[i]["value"] = new String;
			return (this.autoSend) ? this.send() : true;
		}
	}
	return false;
}

PMP.util.pmpAjax.prototype.send = function (parameters) 
{
	var url = PMP.common.isString(parameters) ? parameters : this.url;
	
	if(PMP.common.isObject(parameters) && parameters.context)
	{
		if(PMP.context.ajax)
			this.appendData("ajax", 1);

		if(PMP.context.parentModule)
			this.appendData("parentModule", PMP.context.parentModule);

		if(PMP.context.currentModule)
			this.appendData("currentModule", PMP.context.currentModule);
	}

	if( !PMP.common.isString(url) || url.length == 0 )
		return false;

	var preparedData = this.prepareData();

	switch(this.sendMethod)
	{
		case "GET":
			//try 
			//{
				if (preparedData.length > 0) 
					url = url + "?" + preparedData;
				this.xhr.open("GET", url, false);
				this.xhr.send(null);
			//} 
			//catch (e) { return false; }
			break;

		case "POST":
			//try 
			//{
				this.xhr.open("POST", url, false);
				this.xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				this.xhr.send(preparedData);
			//} 
			//catch (e) { return false; }
			break;
	}


	if(this.xhr.readyState == 4) 
	{
		if(this.xhr.status == 200)
		{
			this.reponse = new PMP.util.pmpAjaxReponse(this.xhr);
			return(this.xhr);
		}
	}
	
	if(this.autoReset) 
		this.resetData();

	return false;
}




PMP.util.pmpAjaxReponse = function(xhr) 
{
	this.etat = null;				// etat de la requête
	this.valeur = null;			// valeur retournée par le serveur
	this.champs = new Array();		// champs erronés retournés par le serveur
	this.messages = new Array();	// messages retournés par le serveur
	this.message = "";				// message formaté par défaut pour affichage à l'utilisateur

	if(!PMP.common.isUndefined(xhr))
	{
		this.load(xhr);
	}
}

PMP.util.pmpAjaxReponse.prototype.load = function (xhr) 
{
	if(PMP.common.isUndefined(xhr) || !xhr || !xhr.responseText)
	{
		this.etat = 0;
		this.message = "Impossible de récupérer la réponse du serveur";
		return;
	}

	//alert(PMP.common.isUndefined(xhr.responseXML));
	//alert(!xhr.responseXML);
	if(PMP.common.isUndefined(xhr.responseXML) || !xhr.responseXML || !xhr.responseXML.documentElement)
	{
		this.etat = xhr.responseText.search('<?xml version="1.0" encoding="UTF-8"?><reponse>') >=0 ? 0 : 1;
		this.message = xhr.responseText;
		return;
	}


	responseXML = xhr.responseXML;
	
	// récuparation de l'état de la requête (ex: 0 => échec, 1 => réussite, ...)
	var etats = responseXML.getElementsByTagName('etat');
	if(etats.length>0)
	{
		this.etat = etats.item(0).firstChild ? etats.item(0).firstChild.data : false;
	}
	else
	{
		this.etat = true;				// !!! etat = true pour opera => responseXML défini même si le contenu n'est pas du xml
		this.message = xhr.responseText;
	}

	// récuparation de la valeur renvoyée par le serveur
	var valeurs = responseXML.getElementsByTagName('valeur');
	if(valeurs.length>0 && valeurs.item(0).firstChild)
		this.valeur = valeurs.item(0).firstChild.data;
	else
		this.valeur = "";

	// récuparation des champs erronés
	var champs = responseXML.getElementsByTagName('champs');
	if(champs.length>0)
	{
		if(champs.item(0).firstChild)
			this.champs = champs.item(0).firstChild.data.split("|");
	}
	
	// récuparation des messages
	/*
	var messages = responseXML.getElementsByTagName('messages');
	if(messages.length>0)
	{
		if(messages.item(0).firstChild)
			this.messages = messages.item(0).firstChild.data.split("|");
	}
	*/


	// récupération du message
	var message = responseXML.getElementsByTagName('message');
	if(message.length>0 && message.item(0).firstChild)
		this.message = message.item(0).firstChild.data;


	//this.formateMessage();
}


PMP.util.pmpAjaxReponse.prototype.formateMessage = function () 
{
	if(this.message.length>0)
		return;

	// formatage du message
	this.message = "";
	
	if(this.champs.length>0)
	{
		// mise en forme du message : saut de ligne, -, espaces...
		this.message = "<br />- " + this.champs.join("<br />- ");

		this.message = "Veuillez renseigner les informations suivantes : " + this.message;
	}
	
	if(this.messages.length>0)
	{
		this.message += (this.message.length > 0 ? "<br /><br />" : "") + this.messages.join("<br />");
	}

	// si le message est vide on affecte le message par défaut
	if(this.message.length==0)
	{
		this.message = this.etat ? "Les modifications ont bien été prises en compte." : "Une erreur s'est produite";
			
	}
}