﻿// Les méthodes d'envois
var GatewayMethods = {
	POST: "post",
	GET: "get"
}

// Les events
var GatewayEvent = {
	LOAD: "load",
	COMPLETE: "complete",
	ERROR: "error"
}

// L'objet Gateway
function Gateway (url, method, cakeMode)
{
	// Les variables
	var _this 		= this;
	var url 		= url == undefined ? "gateway/" : url;
	var queries 	= [];
	var sendMethod	= method == undefined ? "post" : method.toLowerCase();
	var cakeMode	= cakeMode == undefined ? false : cakeMode;
	
	// Créer un élément XHR
	function createXhttp (response)
	{
		// Le xhttp (ça c'est du commentaire utile à mort)
		var xhttp;
		
		// Essayer de créer l'objet xhttp sur MSXML2.XMLHTTP (ie)
		try
		{
			xhttp = new ActiveXObject('Msxml2.XMLHTTP');
		}
		catch (erreur1)
		{
			// Essayer de créer l'objet xhttp sur Microsoft.XMLHTTP
			try
			{
				xhttp = new ActiveXObject('Microsoft.XMLHTTP');
			}
			catch (erreur2)
			{
				// Essayer pour tous les autres navigateurs
				try
				{
					xhttp = new XMLHttpRequest();
				}
				catch (erreur3)
				{
					// Impossible de créer l'objet xhttp
					xhttp = false;
					
					// Signaler l'erreur
					_this.onError(1, "Impossible de créer l'objet XHTTP");
				}
			}
		}
		
		// Ecouter les changement d'état de l'objet xhttp
		xhttp.onreadystatechange = function ()
		{
			// Tout est prêt
			if (xhttp.readyState == 4)
			{
				// Vérifier l'état HTTP
				if (xhttp.status == 200)
				{
					// Parser l'objet
					var objet = eval("(" + xhttp.responseText + ")");
					
					// Vérifier si on a une erreur
					if (objet.error != null && objet.type != null)
					{
						// Faire passer le message d'erreur
						if (response.onError != null)
							response.onError(objet.type, objet.message);
						
						// Appeler aussi sur le gateway
						if (_this.onError != null)
							_this.onError(objet.type, objet.message);
					}
					else
					{
						// Les données ont bien été reçues
						if (response.onLoad != null)
							response.onLoad(objet);
						
						// Appeler aussi sur le gateway
						if (_this.onLoad != null)
							_this.onLoad(objet);
					}
				}
				else
				{
					// Formater le message d'erreur
					var messageErreur = "Erreur HTTP ("+xhttp.status+")";
					
					// Une erreur HTTP est intercéptée
					if (response.onError != null)
						response.onError(0, messageErreur);
					
					// Appeler aussi sur le gateway
					if (_this.onError != null)
						_this.onError(0, messageErreur);
				}
				
				// Recréer un tableau vierge
				var newTab = [];
				
				// Retirer la requête de la liste des requêtes
				for (var i in queries)
				{
					// Si on a trouvé notre requête
					if (queries[i] != response)
					{
						// Ajouter au nouveau tableau
						newTab.push(queries[i]);
					}
				}
				
				// Affecter le nouveau tableau
				queries = newTab;
				
				// S'il n'y a plus de requêtes, on envoie onComplete
				if (queries.length == 0 && _this.onComplete != null)
					_this.onComplete();
			}
		}
		
		// Retourner l'xhttp
		return xhttp;
	}
	
	// Appeler une méthode sur la passerelle
	this.call = function (service, handler)
	{
		// Initialiser l'objet de réponse
		var response = new Object();
		
		// Vérifier si on a un handler, si oui on le map sur le onLoad
		if (handler != null)
			response.onLoad = handler;
		
		// Décomposer le service en classe et méthode
		var query 	= service.split(".");
		var classe 	= query[0];
		var method 	= query[1];
		
		// Initialiser la string post des paramètres
		var paramsString = "";
		
		// Vérifier s'il y a des paramètres
		if (arguments.length > 2)
		{
			// Pour tous les paramètres
			for (var i = 2; i < arguments.length; i++)
			{
				// Encoder ce param
				paramsString += "&arg"+(i-2)+"="+escape(arguments[i]);
			}
		}
		
		// Appeler la méthode onCall si elle existe
		if (this.onCall != null)
			this.onCall(service);
		
		// Définir l'url
		var urlOpen = url
		
		// Ajout du controller et de l'action pour le cakeMode
		if (cakeMode)
			urlOpen += classe+"/"+method;
			
		// La classe et la méthode
		var serviceString = "class="+classe+"&method="+method;
		
		// Associer les paramètres s'il y en a
		if (paramsString != "")
			serviceString += paramsString;
		
		// Créer l'xhttp
		var xhttp = createXhttp(response);
		
		// Vérifier la méthode d'envoie
		if (sendMethod == "post")
		{
			// Ouvrir la connexion
			xhttp.open("POST", urlOpen+"?d="+new Date().getTime(), true); 
			
			// Si on est en POST, il faut ajouter ce header
			xhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		}
		else
		{
			// Ouvrir la connexion
			xhttp.open("GET", urlOpen+"?d="+new Date().getTime()+serviceString, true); 
		}
		
		// Envoyer la requête
		xhttp.send(serviceString);
		
		// Ajouter la requête
		queries.push(response);
		
		// Retourner l'objet de réponse
		return response;
	}
	
	// La fonction pour savoir si ça charge
	this.isLoading = function ()
	{
		return (queries.length != 0);
	}
	
	// La fonction pour retourner les requêtes
	this.getQueries = function ()
	{
		return queries;
	}
}
