/*****************************************************************************
** cAjax - Interfaz XMLHTTP - mjfosela@gmail.com - 04-05-2006        	 	**
**																																					**
**									copyleft -2006																					**
******************************************************************************/

//VARIABLES GLOBALES
// Se colocan fuera de la clase, para que sean comunes a todas las instancias de
// los objetos que se creen, incluso comunes a cualquier parte del codigo js.
// Si cada llamada ajax es asignada con un identificador, todos los estados de cada
// llamadas son accesibles entre ellos y desde fuera.
// El identificador no se asigna automaticamente para evitar un crecimiento desmedido
// de los arrays de estado.

//ESTADOS
var bLoading			= new Array();
var bLoaded 			= new Array();
var bInteractive 	= new Array();
var bComplete 		= new Array();
var bCodRespuesta = new Array();
var tLoading 			= new Array();

//DATOS DE LAS LLAMADAS
var __sURL   	= new Array();
var __sVars 	= new Array();
var __fnDone	= new Array();
var __sMethod	= new Array();

var timestampInicio;
var timestampInicioProceso;

var maxIdAjaxPosible = 50;
for (var i=1;i<maxIdAjaxPosible;i++) { tLoading[i] = 0; }

function XHConn()
{

////////////////////////////////////////////////////////

	//PROPIEDADES PUBLICAS
	var oDate;
			this.oDate = new Date().getTime()/1000.0 + (2 * 60); //TIEMPO MAX 2 min

	var reconectarSi;
			this.reconectarSi = new Array();
	var countReconexiones;
			this.countReconexiones = new Array();
	var reconectarAlternativo;
			this.reconectarAlternativo = new Array();
			this.reconectarAlternativo['URL'] = new Array();
			this.reconectarAlternativo['sMethod'] = new Array();
			this.reconectarAlternativo['sVars'] = new Array();
			this.reconectarAlternativo['fnDone'] = new Array();
	var asincrono;
			this.asincrono = true;

	var tiempoCaducidadIdAjax
			this.tiempoCaducidadIdAjax = 120.0;

	//404
	this.reconectarSi['404'] = 2;
	this.countReconexiones['404'] = 0;

	//Timeout
	var tiempoTimeout;
			this.tiempoTimeout = 60; //segundos
	this.reconectarSi['timeout'] = 2;
	this.countReconexiones['timeout'] = 0;

////////////////////////////////////////////////////////

	//PROPIEDADES PRIVADAS
	var xmlhttp;

  var nCount=0;
  var idTimeout = new Array();
  var paso = new Array();
		  paso[0] = "No iniciado";		//uninitiated
		  paso[1] = "Cargando...";		//loading
		  paso[2] = "...Cargado";			//loaded
		  paso[3] = "Interactuando";	//interactive
		  paso[4] = "Completado";			//complete

  var me = this;
  var nproc = 0;
	var capaSalidaErrores = "";
////////////////////////////////////////////////////////

	//CONSTRUCTOR
  try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
  catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
  catch (e) { try { xmlhttp = new XMLHttpRequest(); }
  catch (e) { xmlhttp = false; }}}

  if (!xmlhttp) { fLog("NO HA SIDO POSIBLE CREAR EL OBJETO","error"); return null; }

	timestampInicioProceso = new Date().getTime()/1000.0;

////////////////////////////////////////////////////////

	// METODOS PUBLICOS
	this.abortar = function()
	{
		if (!bComplete[nproc])
		{
			xmlhttp.abort();
			fLog("ABORTADO PROCESO " + nproc,"titulo");
			bComplete[nproc] = true;
		} else {
			fLog("INTENTO DE ABORTAR PROCESO " + nproc + " FALLIDO PORQUE YA ESTÁ FINALIZADO","warning");
		}
	}

	// METODOS PUBLICOS
	this.abortarPorTimeout = function()
	{
		if (!bComplete[nproc])
		{
			fLog("PROCESO " + nproc +": TIMEOUT CUMPLIDO ("+me.tiempoTimeout+" seg.)","titulo");
			if (me.countReconexiones['timeout'] < me.reconectarSi['timeout'])
			{
				me.abortar();
				me.countReconexiones['timeout']++;
				fLog("Recargando AJAX_"+nproc+"... Intento "+me.countReconexiones['timeout']+" de "+me.reconectarSi['timeout'],"warning",nproc);

  			//RECONSTRUIMOS EL OBJ xmlhttp
  			try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
  			catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
  			catch (e) { try { xmlhttp = new XMLHttpRequest(); }
  			catch (e) { xmlhttp = false; }}}

				me.connect(__sURL[nproc], __sMethod[nproc], __sVars[nproc], __fnDone[nproc], nproc);
			} else {
				me.abortar();
				fLog("FIN RECARGAS PROCESO "+nproc+" POR Timeout","error");
			}
		}
	}

  this.connect = function(sURL, sMethod, sVars, fnDone)
  {
		//OBTENER ID
		var iCount=1;
		var idObjAjax=0;

		var t = (new Date().getTime()/1000.0);
		while (tLoading[iCount] > t  &&  iCount < maxIdAjaxPosible)
		{
			iCount++;
		}
		idObjAjax = iCount;
		tLoading[iCount] = t + this.tiempoCaducidadIdAjax;

		if (idObjAjax > maxIdAjaxPosible || idObjAjax == 0)
		{
			//ERROR. TODOS LOS IDS OCUPADOS

  		//IMPOSIBLE SEGUIR PARA EVITAR CONFLICTO.
  		//MARCO EL ERROR EN EL LOG
  		fLog("Todos los Ids de Ajax ocupados y sin caducar","error");
			try {
				Cargando(false);
			} catch(z) {  }
			//var msjError = "<center><p style='background:#FFF; color:#000; margin:50px; padding:10px; border:1px solid red;'>Ha ocurrido un error en la aplicación.<br/>Pulse el botón si desea enviar el error a soporte para correjir el error.</p><form name='formdekkdeenvio' action='/reshcdome/enviarmailerror.php' method='post'><textarea style='display:none;' name='logstring' id='idLogstring'></textarea><input type='submit' name='enviar' value='Enviar Error'/></form></center>";
			var msjError = "<form name='formdekkdeenvio' action='/reshcdome/enviarmailerror.php' method='post'><textarea style='display:none;' name='logstring' id='idLogstring'></textarea></form>";
			var b = document.getElementsByTagName("BODY");
			b[0].innerHTML = msjError;
			document.forms.formdekkdeenvio.logstring.value = sLog;
			document.forms.formdekkdeenvio.submit();
  		return false;
  	}

  	//ASIGNACION A VBLES GLOBALES
  	__sURL[idObjAjax] 		= sURL;
  	__sVars[idObjAjax] 		= sVars;
  	__fnDone[idObjAjax] 	= fnDone;
  	__sMethod[idObjAjax] 	= sMethod;

  	fLog("EJECUTANDO METODO connect["+idObjAjax+"]","titulo");
		fLog("LLamada por "+sMethod+": "+sURL+"?"+sVars,"notice");
  	nproc = idObjAjax;

    bLoaded[idObjAjax] 			= false;
    bInteractive[idObjAjax] = false;
    bComplete[idObjAjax] 		= false;
    bCodRespuesta[idObjAjax]= false;

    idTimeout[idObjAjax] = setTimeout(me.abortarPorTimeout, this.tiempoTimeout * 1000);

    sMethod = sMethod.toUpperCase();

    try {
    	switch (sMethod)
    	{
    		case "GET":
        	xmlhttp.open(sMethod, sURL+"?"+sVars, this.asincrono);
        	sVars = "";
        	break;
      	case "POST":
	        xmlhttp.open(sMethod, sURL, this.asincrono);
  	      xmlhttp.setRequestHeader("Method", "POST "+sURL+" HTTP/1.1");
    	    xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    	    break;
      }
			xmlhttp.onreadystatechange = function()	{	__onreadystatechange(xmlhttp,fnDone,idObjAjax,idTimeout,me);	};
      xmlhttp.send(sVars);
      if (!this.asincrono) { clearTimeout(idTimeout[idObjAjax]); fnDone(xmlhttp,idObjAjax); fLog("SALIDA true DE METODO connect["+idObjAjax+"] SINCRONO","titulo"); }
    }
    catch(z) { return false; fLog("SALIDA false DE METODO connect["+idObjAjax+"]","titulo"); }
    return true;
  };

////////////////////////////////////////////////////////

	//METODOS PRIVADOS
	__onreadystatechange = function(xmlhttp,fnDone,idObjAjax,idTimeout,obj)
  {
  	//if (xmlhttp.readyState == 1) { alert('POST: enviando');	}
    switch(xmlhttp.readyState)
    {
    	case 1:
    		if (!bLoading[idObjAjax])
    		{
    			bLoading[idObjAjax] = true;
    			fLog("Proceso "+idObjAjax+": Cargando ","notice");
    		}
    		break;
    	case 2:
    		if (!bLoaded[idObjAjax])
    		{
    			bLoaded[idObjAjax] = true;
    			fLog("Proceso "+idObjAjax+": Cargado ","notice");
    			clearTimeout(idTimeout[idObjAjax]);
    		}
    		break;
    	case 3:
    		if (!bInteractive[idObjAjax])
    		{
    			bInteractive[idObjAjax] = true;
    			fLog("Proceso "+idObjAjax+": Interactuando ","notice");
    			clearTimeout(idTimeout[idObjAjax]);
    		}
    		break;
    	case 4:
    		var bExecFnDone = 1;
    		clearTimeout(idTimeout[idObjAjax]);
      	if (!bComplete[idObjAjax])
    		{
    			try {
    				kk1 = xmlhttp.status;
    				kk2 = xmlhttp.readyState;
    			} catch(z) { bExecFnDone = 0; }
			  	try {
  					document.getElementById("info"+idObjAjax).innerHTML += "Proceso "+idObjAjax+" "+paso[xmlhttp.readyState]+"<br/>"+xmlhttp.status+": "+xmlhttp.statusText+"<br>";
  				} catch(z) {  }
      		bComplete[idObjAjax] = true;
      		if (bExecFnDone)
      		{
      			fnDone(xmlhttp,idObjAjax);
      		}
      		fLog("Proceso "+idObjAjax+": Completado ","notice");
      		fLog("SALIDA true DE METODO connect["+idObjAjax+"]","titulo");
    		}

    		//if (typeof(xmlhttp.statusText) == "string" && xmlhttp.statusText != "OK")
    		if (bExecFnDone && ( (bLoaded[idObjAjax] && !bInteractive[idObjAjax]) || (xmlhttp.responseText == "" && document.all) ) )
    		{
    			//document.getElementById("mensaje"+idObjAjax).innerHTML = "PAGINA NO ENCONTRADA";
   				fLog("Proceso "+idObjAjax+" ERROR: "+xmlhttp.status+": "+xmlhttp.statusText,"error");
    			bComplete[idObjAjax] = true;
   				bCodRespuesta[idObjAjax] = xmlhttp.status;

					try {
						if (me.countReconexiones[xmlhttp.status] < me.reconectarSi[xmlhttp.status] && typeof(obj)=="object")
						{
							me.countReconexiones[xmlhttp.status]++;
							fLog("Recargando AJAX_"+idObjAjax+"... Intento "+me.countReconexiones[xmlhttp.status]+" de "+me.reconectarSi[xmlhttp.status],"warning");
							obj.connect(__sURL[idObjAjax], __sMethod[idObjAjax], __sVars[idObjAjax], __fnDone[idObjAjax], idObjAjax);
						}
					} catch(z) {	}
			    bLoading[idObjAjax]			= false;
			    bLoaded[idObjAjax] 			= false;
			    bInteractive[idObjAjax] = false;
	   		}
    		break;
    	default: //NADA
    }
  };

  return this;
} // FIN DE LA CLASE


// PARTE DE LOGs
			var fecha = new Date();
			var printLog = true;	//para sacar en una capa los logs
			var sLog =  "<html><head><title>Log de ajaxConn</title>";
					sLog += "<style type='text/css'>";
					sLog += ".padre { font-family:verdana,arial,serif; font-size:9px; }";
					sLog += ".titulo { font-weight:bold; text-decoration:underline; }";
					sLog += ".error { color:red; }";
					sLog += ".warning { color:blue; }";
					sLog += ".notice { color:green; }";
					sLog += ".tiempo { font-weight:bold; font-family:serif; margin-right:10px; }";
					sLog += "</style>";
				  sLog += "</head><body><div class='padre'>";
					sLog += "<h5>LOG INICIADO A LAS " + fecha.getHours()+":"+fecha.getMinutes()+":"+fecha.getSeconds()+"</h5>\n";
					sLog += "<strong>*********************************</strong><br>\n";

			var bOpenLog = 1;
			var bPrimeravez = 0;

			function fLog(s,modo)
			{
				tNow = Math.round(((new Date().getTime()/1000.0) - timestampInicio)*100)/100;
				tNowProc = Math.round(((new Date().getTime()/1000.0) - timestampInicioProceso)*100)/100;
				if (tNow>60) { sMin=parseInt(tNow/60); sSeg=Math.round(tNow%60*100)/100; sTNow = "["+addZero(sMin)+":"+addZero(sSeg)+"]"; } else { sTNow = "["+addZero(tNow)+"]"; }
				sTNowProc = "["+addZero(tNowProc)+"]";
				if (bPrimeravez==0)
				{
					bPrimeravez = 1;
					try {
						document.getElementById("txtLog").innerHTML = sLog;
					} catch(z) { }
				}
				if (typeof(s)=="undefined") return -1;
				if (typeof(modo)=="undefined") modo = "";
				sLog += "<div class='"+modo+"'>";
				sLog += "<span class='tiempo'>"+sTNow+" "+sTNowProc+"</span>";
				sLog += s+"</div>\n";
				if (printLog)
				{
					try {
						document.getElementById("capaLog").style.display = "block";
						document.getElementById("txtLog").innerHTML += "<div class='"+modo+"'><span class='tiempo'>"+sTNow+" "+sTNowProc+"</span>"+s+"</div>\n";
					} catch(z) {  }
				} else {
					try {
						document.getElementById("capaLog").style.display = "none";
					} catch(z) {  }
				}
			}

			function explaya()
			{
				try {
					if (bOpenLog)
					{
						document.getElementById("capaLog").style.height="20px";
						document.getElementById("txtLog").style.height="0px";
					} else {
						document.getElementById("capaLog").style.height="400px";
						document.getElementById("txtLog").style.height="375px";
					}
				} catch(z) {  }
				bOpenLog = !bOpenLog;
			}

			function chapa() { printLog = 0; try{ document.getElementById("capaLog").style.display = "none"; } catch(z) {  }	}

			function addZero(input)
			{
				var tmp = input.toString().split(".");
				if (parseInt(input) < 10 && tmp[0].toString().length==1) input = "0"+input;
				return input;
			}


////////////////    COMPATIBILIDAD HACIA ATRAS      /////////////////////////////

			function validaCerrojo(){
				if (linksAbiertos==0){
					return false;
				}
				linksAbiertos=0;
				return true;
			}
			function offCerrojo(){
				setTimeout("linksAbiertos=1;",300);
				}
			function onCerrojo(){
				linksAbiertos=0;
			}

/*
		**** PARA MOSTRAR CAPA DE LOG ****

		JUSTO DESPUES DE <body>
		<script type="text/javascript" src="scripts/wz_dragdrop.js"></script>
  	<!--PARA MOSTRAR LOGS-->
  	<div id="capaLog" style="font-size:8px; font-family:verdana,arial,serif; border:0; background:#FF0; position:absolute; top:5px; left:750px; z-index:1000; width:260px; height:400px; cursor:move;">
  		<div style="width:258px; height:16px; text-align:right; border:1px outset #999; background:#AAA; padding-top:4px; cursor:move; ">
  			<span style="margin-right:20px; font-weight:bold; color:#FFF; cursor:move;">SALIDA DE LOGs EN CLIENTE</span>
  			<a href='#' onclick="explaya()" style="border:1px solid black; background:#EEE; color:#444; padding:1px; text-decoration:none;">\/</a>&nbsp;
  			<a href='#' onclick="chapa()" style="border:1px solid black;background:#EEE; color:#444; padding:1px; text-decoration:none;">X</a>&nbsp;
  		</div>
  		<div id="txtLog" style="overflow:auto; width:250px; height:375px; padding:0 4px; "></div>
  	</div>

		JUSTO ANTES DE </body>
		<script type="text/javascript">
				SET_DHTML("capaLog");
		</script>


*/