
	// Funcion para realizar invocaciones asincronas XML
	function processRequest (url) {
		processRequest(url, true);
	}
	
	function processRequest (url, alerta) {
		var now = new Date();
		var ara = now.toUTCString();
		if(url.indexOf("?")<0) {
			url = url + "?";
		}
		url += "&ara=" + ara;

		if (window.XMLHttpRequest) {
			// IE7, Mozilla, Safari, ...
		    http_request = new XMLHttpRequest();
		} else if (window.ActiveXObject) {
			// MS Internet Explorer, IE5, IE6
		    http_request = new ActiveXObject("Microsoft.XMLHTTP");
		}
		
		// Llamamos al servidor en modo sincrono
		http_request.open('GET', url, false);
		http_request.send(null);
		
		// Interpretamos la respuesta del servidor
		if (http_request.status == 200) {
		    // Respuesta OK
		    return http_request;
		} else {
			if(alerta)
				alert('Error processing request: ' + http_request.statusText);
			return null;
		}			
	}
	
	// Busca un elemento con el tipo de tag e id indicados
	function findElement (elem, tagname, id) {
		var children = elem.childNodes;
		// Recorremos lista de hijos
		for (i=0; i<children.length; i++) {
			node = children[i];
			// Si es un elemento
			if (node.nodeType == 1) {
				if (node.nodeName == tagname && node.getAttribute('id') == id) {
					return node;
				}
			}
		}
		return null;
	}


	function ltrim(cadena) {
		while (cadena.charAt(0) == ' ') {
			cadena = cadena.substring(1);
		}
		return cadena;
	}


	// Funcion para aplicar estilos
	function aplicaEstilo (elem, style) {
		var index;
		var kvSep;
		var key;
		var val;
		while ((index = style.indexOf(';')) >= 0) {
		
			var prop = style.substring(0, index);
			var kvSep = prop.indexOf(':');
			
			key = prop.substring(0, kvSep);
			key = ltrim(key);
			key = key.replace('-', '');
			
			val = prop.substring(kvSep+1);
			val = ltrim(val);
			
			//alert('[' + key + '=' + val + ']');
			
			eval("elem." + key + "='" + val + "'");
			
			style = style.substring(index+1);
		}
	}


	// Funcion de copia recursiva de nodos
	function copyElements (source) {
	
		var i=0;	// indice para bucles
		
		//alert('Creating ' + source.nodeName + ' element');
		var target = document.createElement(source.nodeName);
		
		// Procesamos atributos
		var attrs = source.attributes;
		var attrsDesc = '';
		
		for (i=0; i<attrs.length; i++) {
		
			var node = attrs[i];
			attrsDesc = attrsDesc + '\n' + node.nodeName + '=' + node.nodeValue;
			
			// Es un atributo
			target.setAttribute(node.nodeName, node.nodeValue);
		}
		
		//alert('Attrs OK:' + attrsDesc);
		
		// Procesamos hijos: Elementos y texto
		var children = source.childNodes;
		
		for (i=0; i<children.length; i++) {
			var node = children[i];
			if (node.nodeType == 1) {
				//alert('Processing child element');
				// Es un elemento
				var newElem = copyElements(node);
				target.appendChild(newElem);
				
			} else if (node.nodeType == 3) {
				// Es texto
				//alert('Processing text: ' + node.nodeValue);
				var text = document.createTextNode(node.nodeValue);
				target.appendChild(text);
			} else {
				// Do nothing!
			}
		}
		
		//alert('Returning new node');
		return target;
	}

	
	function buildQuery(theFormName) {
	    theForm = document.forms[theFormName];
	    var qs = ''
	    for (e=0;e<theForm.elements.length;e++) {
	        if (theForm.elements[e].name!='') {
	            var name = theForm.elements[e].name;
	            qs+=(qs=='')?'':'&'
	            if (theForm.elements[e].type=='radio'){
	            	if (theForm.elements[e].checked==true){
			            qs+= name+'='+escape(theForm.elements[e].value);	            	
	            	}
	            }else{
		            qs+= name+'='+escape(theForm.elements[e].value);
	            }
	        }
	    }
	    qs+="\n";
	    return qs
	} 
	