
	// $URBANO_VERSION = "2.490"
	function uAgent(id) {
		if(id == "") { alert("ID en uAgent llego vacia"); }
		this.Conexiones = new Array();
		this.Targets = Array();
		this.Actions = Array();		// Accciones de cada conexion (eval, get, etc)
		// this.evtHandlers = Array();
		this.onLoad = '';
		this.ID = id;
		this.IndicatorID	= '';
		this.Indicator		= false;
		
		// Opciones del uagent:
		this.Options = {
			"set_preblanking"	:false,		// aGetSet y sGetSet blanquean los elementos antes de pedir datos ?
			"indicator_id"		:null		// ID del elemento que indica que el uagent esta trabajando
		}
		
		return this;
	}
	
	
	uAgent.prototype.setIndicatorId = function(id) {
		// Fija el ID del identificador (trabajando)
		
		this.Options.indicator_id = id;
		
		if(document.getElementById(this.Options.indicator_id)) {
			this.Indicator = document.getElementById(this.Options.indicator_id);
		}
	}
	
	uAgent.prototype.setOption = function(option_name, valor) {
		this.Options[option_name] = valor;
	}
	
	uAgent.prototype.getOption = function(option_name) {
		return this.Options[option_name];
	}
	
	
	uAgent.prototype.createStateHandler = function(agent, cnx_id) {
		// #uDOC:TITLE createStateHandler
		// #uDOC:DESCR Crea una closure para manejar los eventos de la conexion
		
		return (function(e) {
			// alert(agent);
			agent['recvTransfer'](e, cnx_id);
		});
	}
	
	uAgent.prototype.scheduleTransfer = function(url, reqmethod) {
		
		// Metodo default para transacciones es GET:
		if(reqmethod == undefined) { reqmethod = "GET"; }
		
		// Genera la conexion
		var cnx_id = this.getAgent();
		
		// Checa el tipo de datos porque a veces recibimos 0:
		if((! cnx_id) && (typeof cnx_id == "boolean")) { return false; }
		
		// Genera el manejador de estados, que es un closure:
		var f = this.createStateHandler(this, cnx_id);
		
		// Asigna al event handler de la conexion:
		if(this.Conexiones[cnx_id].addEventListener) { this.Conexiones[cnx_id].addEventListener("readystatechange", f, false); }
		
		// Este deberia ser asi en IE: Pero no sirve:
		// else if(this.Conexiones[cnx_id].attachEvent) { this.Conexiones[cnx_id].attachEvent("onreadystatechange", f); }
		else { this.Conexiones[cnx_id].onreadystatechange = f; }
		
		
		/*  codigo pre-clousre:
			// Asigna el resultado al recibidir
			eval("this.Conexiones['" + cnx_id + "'].onreadystatechange = function() { "+this.ID+".recvTransfer("+cnx_id+"); }");
		*/
		this.Conexiones[cnx_id].open(reqmethod, url, true);
		return cnx_id;
	}
	
	uAgent.prototype.doTransfer = function(cnx_id, post_data) {
		
		// Cruz cruz que no truene esto:
		if(post_data == undefined) { post_data = null; }
		
		// Manda la conexion:
		this.Conexiones[cnx_id].send(post_data);
	}
	
	uAgent.prototype.aGetSet = function(url, target) {
		
		if(this.Indicator) { this.Indicator.style.display = "block"; }
		
		if(this.Options.set_preblanking) { target.innerHTML = ''; }
		
		var cnx_id = this.scheduleTransfer(url);
		
		this.Actions[cnx_id] = "set";
		this.Targets[cnx_id] = target;				
		
		this.doTransfer(cnx_id);
		
		return true;
	}
	
	uAgent.prototype.aPostSet = function(url, target, data) {
		var cnx_id = this.scheduleTransfer(url, "POST");
		
		this.Actions[cnx_id] = "set";
		this.Targets[cnx_id] = target;				
		this.Conexiones[cnx_id].setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		this.doTransfer(cnx_id, data);
		
		return true;
	}
	
	uAgent.prototype.aGetEval = function(url) {
		
		// Saca el indicator:
		if(this.Indicator) { this.Indicator.style.display = "block"; }
		
		// Programa la conexion:
		var cnx_id = this.scheduleTransfer(url);
		
		// Fija la accion de eval:
		this.Actions[cnx_id] = "eval";
		
		this.doTransfer(cnx_id);
		
		return true;
	}
	
	uAgent.prototype.aPostEval = function(url, data) {
		
		// Saca el indicador si hay:
		if(this.Indicator) { this.Indicator.style.display = "block"; }
		
		// Programa el post:
		var cnx_id = this.scheduleTransfer(url, "POST");
		
		this.Actions[cnx_id] = "eval";
		this.Conexiones[cnx_id].setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		this.doTransfer(cnx_id, data);
		
		return true;
	}
	
	uAgent.prototype.aPostFunction = function(url, target, data) {
		
		// Saca el indicador si hay:
		if(this.Indicator) { this.Indicator.style.display = "block"; }
		
		var cnx_id = this.scheduleTransfer(url, "POST");
		this.Actions[cnx_id] = "func";
		this.Targets[cnx_id] = target;
		
		// Pon el header de urlencoded para que se mande bien:
		this.Conexiones[cnx_id].setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		this.doTransfer(cnx_id, data);
		return true;
	}
	
	uAgent.prototype.aGetFunction = function(url, target) {
		
		// Saca el indicador si hay:
		if(this.Indicator) { this.Indicator.style.display = "block"; }
		
		var cnx_id = this.scheduleTransfer(url);
		this.Actions[cnx_id] = "func";
		this.Targets[cnx_id] = target;
		this.doTransfer(cnx_id);
		return true;
	}
	
	uAgent.prototype.recvTransfer = function(e, cnx_id) {
		
		/* RECIBE LOS DATOS DE LA CONEXION:
		//
		// Por ahora solo manejamos el status de complete
		// en el objeto de response. Si quieres agregar
		// mas cosas los demas estados que reporta son:
		//  0:uninitialized 1:loading 2:loaded 3:interactive) 4:complete
		*/
		
		if(this.Conexiones[cnx_id].readyState != 4) { return; }
		
		// FIXME: Esto es un error porque respuestas en blanco o que
		// evaluen a falso (0 string blanca, etc) se quedan pegadas para siempre:
		if(! this.Conexiones[cnx_id].responseText) { return; }
		
		if(this.Actions[cnx_id] == "set") {
			// FIXME: No usar innerHTML, pero si no que ?!
			this.Targets[cnx_id].innerHTML = this.Conexiones[cnx_id].responseText;
			
		} else if(this.Actions[cnx_id] == "eval") {
			eval(this.Conexiones[cnx_id].responseText);
			
		} else if(this.Actions[cnx_id] == "func") {
			
			// Si el target es una string, entonces es el nombre de una func:
			if(this.Targets[cnx_id].substr) {
				var fun = eval(this.Targets[cnx_id]); // (this.Conexiones[cnx_id].responseText);
				if(fun) { fun(this.Conexiones[cnx_id].responseText); }
				
			// Si es un array entonces asumimos que es un metodo de un obj:
			} else if(this.Targets[cnx_id].splice) {
				// FIXME:Aqui hay que checar si existe el metodo:
				this.Targets[cnx_id][0][this.Targets[cnx_id][1]](this.Conexiones[cnx_id].responseText);
			
			// Si no, asusmimos que es la funcion en si
			} else {
				this.Targets[cnx_id].call(undefined, this.Conexiones[cnx_id].responseText);
			}
			
		}
		
		// Checa si hay un indicador y si si, cortalo
		if(this.Indicator) { this.Indicator.style.display = "none"; }
		
		// checa si hay un event handler de onload
		if(this.onLoad != "") {
			this.onLoad.call();
		}
		
		// alert(this.Conexiones.length);
		// Regresa lo que resulte de limpiar la conexion:
		return this.cleanTransfer(cnx_id);
		
	}
	
	uAgent.prototype.cleanTransfer = function(cnx_id) {
		// #uDOC:TITLE cleanTransfer
		// #uDOC:DESCR Limpia de la memoria los datos de la conexion que ya paso:
		
		if(this.Conexiones[cnx_id])		{ this.Conexiones[cnx_id]	= undefined; }
		if(this.Actions[cnx_id])		{ this.Actions[cnx_id]		= null; }
		if(this.Targets[cnx_id])		{ this.Targets[cnx_id]		= null; }
		
		return true;
	}
	
	uAgent.prototype.addEvtHandler = function(evt, hdlr) {
		if(evt == "load") {
			if(hdlr) {
				this.onLoad = hdlr;
			}
		}
	}
	
	uAgent.prototype.getAgent = function() {
		// #uDOC:TITLE getAgent
		// #uDOC:DESCR Crea un conector y asignalo en el array regresendao el ID
		
		var connector;
		// var cnx_id = parseInt(Math.random() * 1000);
		
		// Saca el objeto de request
		if (window.XMLHttpRequest)		{ connector = new XMLHttpRequest(); }
		else if (window.ActiveXObject)	{ connector = new ActiveXObject("Microsoft.XMLHTTP"); }
		
		// Si salio entonces metelo donde va.
		if(connector) {
			
			// Mete el conctor en el array y ese es ahora el ID de conexion:
			var l = this.Conexiones.push(connector);
			
			// ... bueno, menos uno :)
			return l - 1;
			
			
		} else {
			return false;
		}
	}
	
	uAgent.prototype.JSONP = function(url) {
		// #uDOC:TITLE JSONP
		// #uDOC:DESCR Jala un paquete de jsonp al document, puede ser crossdomain 
		
		var head = document.getElementsByTagName("head")[0] || document.documentElement;
		var scriptNode = document.createElement("script");
		scriptNode.src = url;
		if(head.firstChild) { head.insertBefore(scriptNode, head.firstChild); }
		else { head.appendChild(scriptNode); }
		
		// Succes, creo
		return true;
	}

