// ********************************************************
// * 		CLASE: ajaxDataHandler	V 2.1				  * 
// * Correciones										  *
// * 15/12/2007 -> Error de noCaching					  *
// * 20/02/2008 -> Error en Firefox. No ejecuta consultas *
// ********************************************************

function ajaxDataHandler()	{

	// *************
	// * Atributos *
	// *************
		// Ajax Request properties
		this.method					= "GET";	// GET [Default] | POST 	--> Método por el cual se envían los datos al servidor
		this.async					= true;		// TRUE [Default] | FALSE 	--> Indica si la comunicación es asíncrona o no 
		this.noCaching				= true;		// TRUE | FALSE [Default] 	--> Evita el problema de cacheo de paginas en el servidor
		this.dataSourceType			= "xml";	// xml [Default] | text 	--> Tipo de datos del archivo de datos
		this.processRequest			= "";		// Función que procesará los datos devueltos por el objeto ajax
		this.dataSource				= "";		// Archivo de datos
		
		// Loading properties
		this.showLoading			= false;	// TRUE | FALSE [Default] --> Indica si se muestra o no el cartel de cargando datos
		this.loadingImage			= "";		// Archivo de imagen de carga de datos (ej: 'imageAjaxLoading.gif')
		this.loadingText			= "";		// Texto de carga de datos (ej: 'Cargando datos...')
		this.loadingContainer		= "";		// Id del contenedor donde colocar el mensaje de cargando datos

	// **********************
	// * Variables privadas *
	// **********************
		var obj 					= this; // Referencia al objeto principal
		var loadingStatus 			= "";	// Variable interna usada por las funciones de setLoading y unsetLoading
		var pos						= ""; 
		var	ajaxHttpRequestObj 		= new Array(); 	// Array de objetos ajax (Permite utilizar multiples conexiones)


	
	// ***********
	// * Métodos *
	// ***********	
		// getData: Inicia una petición http obtiene el archivo y devuelve un array multidimensional con los datos (Si es un texto devuelve un array común)
		this.sendRequest = function sendRequest(newDataSource, newProcessRequest, newAditionalParam,newDataSourceType, newMethod, postValues, newAsync, newNoCaching)
			{
			// Valores por defecto
			if (!newDataSource)		{ newDataSource 		= this.dataSource; }
			if (!newProcessRequest)	{ newProcessRequest 	= this.processRequest; }
			if (!newDataSourceType)	{ newDataSourceType 	= this.dataSourceType; }
			if (!newMethod)			{ newMethod 			= this.method; }
			if (typeof(newAsync) == 'undefined') { newAsync 				= this.async; }
			if (typeof(newNoCaching) == 'undefined'){ newNoCaching 			= this.noCaching; }
			
			if (newDataSource && newProcessRequest)
				{
				// Creo el objeto ajaxHttpRequestObj para está operación
				try {
					pos = ajaxHttpRequestObj.push(new XMLHttpRequest());
					} 
				catch(err1) 
					{
					try { 
						pos = ajaxHttpRequestObj.push(new ActiveXObject("Msxml2.XMLHTTP"));
						} 
					catch (err2) 
						{
						try {
							pos = ajaxHttpRequestObj.push(new ActiveXObject("Microsoft.XMLHTTP"));
							} 
						catch (err3) 
							{
							ajaxHttpRequestObj = false;
							}
						}
					}
				
				
				// Pos contiene el id de la posicion siguiente del array por eso descuento 1 asi obtengo la referencia al objeto recien creado
				pos--;
				
				// noCahing habilitado
				if (newNoCaching) 	
					{ 
					
					// dataSource con parámetros adicionales
					if (newDataSource.indexOf("?") != -1 )
						{
						ajaxHttpRequestObj[pos].open(newMethod, newDataSource, newAsync); 
						}
					//dataSource sin parámetros adicionales
					else
						{
						ajaxHttpRequestObj[pos].open(newMethod, newDataSource+"?rand=" + parseInt(Math.random()*99999999), newAsync); 
						}
					
					
					}
				// noCaching deshabilitado
				else 
					{
					ajaxHttpRequestObj[pos].open(newMethod, newDataSource, newAsync);
					}
				
				// POST
				if (newMethod == "POST" && postValues != "") 
					{ 
					ajaxHttpRequestObj[pos].setRequestHeader('Content-Type','application/x-www-form-urlencoded');
					ajaxHttpRequestObj[pos].send(postValues); 
					}
				// GET
				else 
					{ 
					ajaxHttpRequestObj[pos].send(null); 
					}
					
				if (newAsync) {
					ajaxHttpRequestObj[pos].onreadystatechange = processRequestFunction(pos,newDataSource,newProcessRequest,newAditionalParam,newDataSourceType);
				}
				// Corrije el bug del Firefox que no ejecuta la funcion onreadystatechange cuando la consulta es sincrónica
				else {
					var funcSync = processRequestFunction(pos,newDataSource,newProcessRequest,newAditionalParam,newDataSourceType);
					funcSync();
				}
					
				} //Fin if newDataSource y newProcessRequest
			else
				{
				if (newDataSource == "" ) 		alert("Error: No se especificó un dataSource");
				if (newProcessRequest == "" ) 	alert("Error: No se especificó una función para procesar la petición http");
				}
			}
	
	
	// **********************
	// * Funciones privadas *
	// **********************
	
		// processRequestFunction: funcion especial que devuelve otra función custmizada para cada objeto ajaxHttpRequestObj
		function processRequestFunction(pos,newDataSource,newProcessRequest,newAditionalParam,newDataSourceType) 
			{
			// /*DEBUG*/ alert('ejecuta la funcion ajax');
			return function() {
				// /*DEBUG*/ alert("ReadyState: "+ajaxHttpRequestObj[pos].readyState);
				
				if (ajaxHttpRequestObj[pos].readyState == 4 || ajaxHttpRequestObj[pos].readyState == "complete")  
					{
					// La operación terminó hay que ver si el archivo cargado es el correcto o no se pudo encontrar
					// /*DEBUG*/ alert('Request Status:'+ajaxHttpRequestObj[pos].status);
					if (ajaxHttpRequestObj[pos].status == 200 && ajaxHttpRequestObj[pos].status != null) 
							{ 
							obj.unsetLoading();
							
							// Archivo xml
							// Obtengo el DOM del xml usando el objeto request
							if (newDataSourceType == 'xml' || newDataSourceType == 'XML') { var xmlDom = ajaxHttpRequestObj[pos].responseXML; newProcessRequest(xmlDom,newAditionalParam); }
							
							// Archivo de texto
							if (newDataSourceType == 'text' || newDataSourceType == 'TEXT') { var text = ajaxHttpRequestObj[pos].responseText; newProcessRequest(text,newAditionalParam); }
							} 
						else
							{
							alert("Error loading Document"+ newDataSource);
							}
					}
				else
					{
					obj.setLoading();
					}
				}
			}
	
		// setLoading = Método que setea el control en modo loading mostrando los gráficos correspondientes
		this.setLoading = function setLoading() {
			if (this.showLoading)
				{
				if (loadingStatus != 1 ) 
					{ 
					// Imagen y texto
					if (this.loadingImage != "" && this.loadingText != "") { document.getElementById(this.loadingContainer).innerHTML = '<img src="'+ this.loadingImage +'" />'+this.loadingText; }
					
					// Loading con imagen
					if (this.loadingImage != "" && this.loadingText == "") { document.getElementById(this.loadingContainer).innerHTML = '<img src="'+ this.loadingImage +'" />'; }
					
					// Loading con texto
					if (this.loadingImage == "" && this.loadingText != "")  { document.getElementById(this.loadingContainer).innerHTML = this.loadingText; }
					loadingStatus = 1;
					}
				}
			}
		
		// unsetLoading = quita el estado loading
		this.unsetLoading = function unsetLoading()
			{
			if (this.showLoading)
				{
				if (loadingStatus != 0 ) 
					{
					document.getElementById(this.loadingContainer).innerHTML = "&nbsp;";
					loadingStatus = 0;
					}
				}
			}
	
	
	
	}













