function Ajax(url,f,loading){

// FUNCIONAMIENTO GENERAL (XML) /////////////////////////////////////////////

	// VARIABLES LOCALES /////////////////////

	var intentos=0;
	var self;
	var indicemodal=0;
	var indicetooltip=0;


	// PROPIEDADES ///////////////////////////
	
	this.xmlDoc = null;
	this.url = url? url : null;
	this.f = f? f: null;
	this.loading = loading? loading : null;
	this.loaderror = null;
	this.running = false;
	this.post = null;
	this.id = Math.random();
	this.nocache = false;
	
	// MÉTODOS ///////////////////////////////
	
	// Iniciamos el objeto
	this.init = function(){	
		if (window.XMLHttpRequest) {
			this.xmlDoc = new XMLHttpRequest();
			this.xmlDoc.onreadystatechange = check;
		} 
		else if (window.ActiveXObject) {			
			this.xmlDoc = new ActiveXObject("Microsoft.XMLHTTP");
			if (this.xmlDoc)
				this.xmlDoc.onreadystatechange = check;
		} 
		else
			alert('Tu navegador no puede soportar el script');
	}
	
	// Ejecutamos
	this.run = function(run_url,run_f,run_loading){
		// Si nos llegan  parámetros los recogemos
		this.url = run_url? run_url : this.url;
		this.f = run_f? run_f: this.f;
		this.loading = run_loading? run_loading : this.loading;

		// Iniciamos objeto
		try{
			this.init();
		} catch(e){
			// ActiveX desactivado
			this.showModal('<h3 style="color: red">Aviso importante</h3>Hemos detectado que tu navegador tiene desactivado el uso de controles ActiveX en la configuraci&oacute;n de seguridad, lo que te impedir&aacute; navegar con normalidad por este sitio. Para activarlo, debes seguir los siguiente pasos:<br><br><div style="text-align:left">1- Accede al men&uacute; <strong>Herramientas -> Opciones de Internet</strong>.<br>2- Haz click en la pesta&ntilde;a <strong>Seguridad</strong>.<br>3- Haz click en el bot&oacute;n <strong>Nivel personalizado...</strong><br>4- Dentro del men&uacute; <strong>Controles y complementos de ActiveX</strong>, en la primera opción <strong>Activar la secuencia de comandos de los controles de ActiveX marcados como seguros</strong>, seleccionar la opci&oacute;n <strong>Activar</strong>.<br>5- Pincha en <strong>Aceptar</strong> en las dos ventanas.<br>6- Cuando hayas terminado, haz click en el bot&oacute;n <strong>Actualizar</strong> para volver a cargar la p&aacute;gina.</div><br><br><input type="button" value="Actualizar" onclick="location.reload();">');
			return false;
		}

		this.running = true;
		
		// Función cargando
		if (this.loading!=null)
			if(typeof(self.loading)=='function')
				self.loading();
			else
				eval(self.loading);

			eval(this.loading);
		
		// Prevenimos cacheo con IE
		if (this.nocache){
			if(this.url.indexOf('?')>0)
				this.url+='&ajax-random='+Math.random()
			else
				this.url+='?ajax-random='+Math.random()
		}
		
		// Cargamos la URL
//		try{
			this.xmlDoc.open((this.post==null?'GET':'POST'), this.url, true);
			if(this.post!=null)
				this.xmlDoc.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
			this.xmlDoc.send(this.post);
			this.post=null;
/*		}
		catch(e){checkerror();}*/
	}	
		
	
	// FUNCIONES PRIVATE ///////////////////////
	
	// Chequeamos el resultado
	function check() {
		if (self.xmlDoc.readyState==4)
			if (self.xmlDoc.status==200){
				self.running = false;
				if(typeof(self.f)=='function')
					self.f();
				else
					eval(self.f);
				intentos = 0;
			}
			else
				checkerror();	
	}


	function checkerror(){
		self.running = false;

		if(self.loaderror!=null)
			if(typeof(self.loaderror)=='function')
				self.loaderror();
			else
				eval(self.loaderror);
		else
			if(intentos < 3){
				if(confirm('Ocurrió un error de comunicación con el servidor. ¿Desea reintentar?')){
					intentos ++;
					self.run();
				}
				else{
					intentos = 0;
					self.errorLabel('ERROR: No se ha podido establecer comunicación con el servidor');
				}
			}
			else{
				intentos = 0;
				self.errorLabel('Error de comunicación con el servidor. Por favor, vuelva a intentarlo pasados unos minutos');
			}
		
		return;
	}

// EFECTOS Y MENSAJES ////////////////////////////////////////////////


	// VARIABLES LOCALES /////////////////////

	var label;
	var modal2Html = '';
	var tooltipTimeout;
	

	// PROPIEDADES ///////////////////////////
	
	this.hideTimeout = 2;
	this.errorTimeout = 5;


	// MÉTODOS ///////////////////////////////
	
	// Mostrar mensaje en etiqueta arriba a la derecha, tipo Google
	this.showLabel = function(msg){
		crearEtiqueta();
		label.style.color = '#000';
		label.style.background = '#FD6';
		label.innerHTML = msg;
		label.style.display = '';
	}


	// Ocultar etiqueta (si se pasa un texto como parámetro se muestra con fondo verde durante 2 segundos)
	this.hideLabel = function(msg){
		if(msg){
			crearEtiqueta();
			label.style.color = '#FFF';
			label.style.background = '#093';
			label.innerHTML = msg;
			setTimeout(function(){if(document.getElementById('_ajax_label')) document.body.removeChild(document.getElementById('_ajax_label'))},this.hideTimeout*1000);
		}
		else 
			if(document.getElementById("_ajax_label")) 
				document.body.removeChild(document.getElementById("_ajax_label"));
	}


	// Ocultar etiqueta mostrando un mensaje con fondo rojo durante 5 segundos
	this.errorLabel = function(msg){
		crearEtiqueta();
		label.style.color = '#FFF';
		label.style.background = '#C30';
		label.innerHTML = msg;
		setTimeout(function(){if(document.getElementById('_ajax_label')) document.body.removeChild(document.getElementById('_ajax_label'))},this.errorTimeout*1000);
	}


	this.showTooltip = function(msg){
		clearTimeout(tooltipTimeout);
		var tt;
		if(!document.getElementById('_ajax_tooltip_'+this.id)){
			tt = document.createElement('DIV');
			tt.id = '_ajax_tooltip_'+this.id;
			tt.style.position='absolute';
			tt.style.zIndex=1000*indicemodal+1;
			document.body.appendChild(tt);
			document.body.onmousemove=function(e){
				document.getElementById('_ajax_tooltip_'+self.id).style.top=((e?e:event).clientY+document.body.scrollTop+20)+'px';
				document.getElementById('_ajax_tooltip_'+self.id).style.left=((e?e:event).clientX+15)+'px';
			}
		}
		else
			tt = document.getElementById('_ajax_tooltip_'+this.id);
		
		tt.style.left='-2000px';
		tt.style.top='-2000px';
		tt.className='ajax_tooltip_on';
		tt.innerHTML=msg;
		tt.style.display='';
	}
	
	this.hideTooltip = function(msg){
		clearTimeout(tooltipTimeout);
		if(document.getElementById('_ajax_tooltip_'+this.id)){
			if(msg){
				document.getElementById('_ajax_tooltip_'+this.id).style.display='';
				document.getElementById('_ajax_tooltip_'+this.id).className='ajax_tooltip_off';
				document.getElementById('_ajax_tooltip_'+this.id).innerHTML = msg;
				tooltipTimeout=setTimeout(function(){document.getElementById('_ajax_tooltip_'+self.id).style.display='none';},this.hideTimeout*1000);
			}
			else{
				document.getElementById('_ajax_tooltip_'+this.id).style.display='none';
			}
		}
	}

	this.errorTooltip = function(msg){
		clearTimeout(tooltipTimeout);
		if(document.getElementById('_ajax_tooltip_'+this.id)){
			document.getElementById('_ajax_tooltip_'+this.id).style.display='';
			document.getElementById('_ajax_tooltip_'+this.id).className='ajax_tooltip_error';
			document.getElementById('_ajax_tooltip_'+this.id).innerHTML = msg;
			tooltipTimeout=setTimeout(function(){document.getElementById('_ajax_tooltip_'+self.id).style.display='none';},this.errorTimeout*1000);
		}
	}

	// Ventana modal centrada tamano personalizado
	this.showModal = function(html,ancho,alto){
		indicemodal++;
		bgTrans();
		var idventana = '_ajax_modalcontent_'+this.id+'_'+indicemodal;
		
		if(!document.getElementById(idventana))
		{
			
			var modalcontent = document.createElement('DIV');
			modalcontent.style.cssText = 'position:absolute; left: 0px; top: 0px; width: 100%; height: 100%; z-index:'+((1000*indicemodal)+1)+';';
			modalcontent.id = idventana;
			document.body.appendChild(modalcontent);
			if (indicemodal == 1)
			visionCombos('hidden');
		}
		
		document.getElementById(idventana).innerHTML = '<table border="0" width="100%" height="100%" align="center"><tr><td align="center"><div class="modalstyle" id="ajax_contenido" style="height:'+alto+'px; width:'+ancho+'px"><div style="float:right; width:20px; margin:0px;"><a href="#" class="botonClose" onClick="ajax.hideModal();return false;" style="color:white;">X</a></div>'+html+'</div></td></tr></table>';

		document.getElementById(idventana).style.top = document.body.scrollTop+"px";

	}
	
	
	// Ventana modal con efecto fadein
	this.showModalFade = function(html){
		this.showModal(html);
		fadeIn(document.getElementById('_ajax_modalcontent_'+this.id+'_'+indicemodal),10);
	}
	
	// Ventana modal centrada que carga un iframe con el contenido url con ancho y alto
	this.showModalURL = function(url,ancho,alto){
		this.showModal('<iframe name="frame_ajax" width="'+ancho+'" height="'+alto+'" scrolling="no" src="'+url+'" frameborder="no"></iframe>');
	}	
	

	this.showModalPopup = function(html){
		modal2Html = html;

//		this.hideModal();
		
		indicemodal++;
		bgTrans();

		if(!document.getElementById('_ajax_modal2_'+this.id+'_'+indicemodal)){
			var modal = document.createElement('DIV');
			modal.style.cssText = 'position: absolute; z-index:'+((1000*indicemodal)+1)+'; left: -45px; width: 15px; height: 15px; border: 1px solid #469dbe;';
			modal.style.top= getScrollY() + 15 + 'px'; 			
			modal.id = '_ajax_modal2_'+this.id+'_'+indicemodal;
			document.body.appendChild(modal);
		}

		/*if(document.all)
			document.body.style.overflow = 'hidden';
		else
			window.onscroll = function(){
				if(document.getElementById('_ajax_modal2_'+this.id+'_'+indicemodal)){
					document.getElementById('_ajax_modal2_'+this.id+'_'+indicemodal).style.top = getScrollY()+15;
				}
			}*/

		modal2mover();
	}
		

	// Ocultar ventanas modales
	this.hideModal = function(){
		if (indicemodal == 1)
		visionCombos('visible');
		
		if(document.getElementById('_ajax_modal2_'+this.id+'_'+indicemodal)){
			document.body.removeChild(document.getElementById('_ajax_modal2_'+this.id+'_'+indicemodal));
			document.body.removeChild(document.getElementById('_ajax_trans_'+this.id+'_'+indicemodal));
			indicemodal--;
		}else if(document.getElementById('_ajax_modalcontent_'+this.id+'_'+indicemodal)){
			document.body.removeChild(document.getElementById('_ajax_modalcontent_'+this.id+'_'+indicemodal));
			document.body.removeChild(document.getElementById('_ajax_trans_'+this.id+'_'+indicemodal));
			indicemodal--;
		}

		if(indicemodal>0 && document.getElementById('_ajax_modalcontent_'+this.id+'_'+indicemodal))
			document.getElementById('_ajax_modalcontent_'+this.id+'_'+indicemodal).style.top = getScrollY();
	}

	this.hideModalFade = function(){
		if(document.getElementById('_ajax_modal2_'+this.id+'_'+indicemodal))
			fadeOut(document.getElementById('_ajax_modal2_'+this.id+'_'+indicemodal),90);
		else if(document.getElementById('_ajax_modalcontent_'+this.id+'_'+indicemodal))
			fadeOut(document.getElementById('_ajax_modalcontent_'+this.id+'_'+indicemodal),90);		
	}

	this.cargaCapa = function(fichero,capa) {
		this.url = fichero;
		this.f = "self.cargaCapaAjax('"+capa+"')";
		this.run();
	}
	this.cargaCapaAjax = function(capa) {
		var resultado = this.xmlDoc.responseText;
		var textos = resultado.split('%%%');
		document.getElementById(capa).innerHTML = textos[0];
		if (textos[1])
			eval(textos[1]);
		this.hideLabel();
	}



	// FUNCIONES PRIVATE ///////////////////////

	function crearEtiqueta(){
		if(document.getElementById('_ajax_label'))
			label = document.getElementById('_ajax_label');
		else{
			label = document.createElement('SPAN');
			label.style.cssText = 'position: absolute; right:0px; padding: 2px 20px 2px 20px; font-family: arial; font-size: 13px; font-weight: bold; z-index: 99';
			
			label.id = '_ajax_label';
			if (document.body!=null)
				document.body.appendChild(label);
			else
				document.documentElement.appendChild(label);
		}

		label.style.top = getScrollY();
	}


	function modal2mover(){	
		var modal = document.getElementById('_ajax_modal2_'+self.id+'_'+indicemodal);
		
		if (modal.style.left!='30px'){
			modal.style.left = parseInt(modal.style.left.replace('px','')) + 5 + 'px';
			setTimeout(function(){modal2mover();},1);
		} 
		else {
			setTimeout('document.getElementById(\'_ajax_modal2_'+self.id+'_'+indicemodal+'\').style.background="#FF850D"',100);
			setTimeout('document.getElementById(\'_ajax_modal2_'+self.id+'_'+indicemodal+'\').style.background="#FFF"',200);
			setTimeout('document.getElementById(\'_ajax_modal2_'+self.id+'_'+indicemodal+'\').style.background="#FF850D"',300);
			setTimeout('document.getElementById(\'_ajax_modal2_'+self.id+'_'+indicemodal+'\').style.background="#FFF"',400);
			setTimeout('document.getElementById(\'_ajax_modal2_'+self.id+'_'+indicemodal+'\').style.background="#FF850D"',500);
			setTimeout('document.getElementById(\'_ajax_modal2_'+self.id+'_'+indicemodal+'\').style.background="#FFF"',600);
			setTimeout(function(){modal2resize();},700);
		}
	}

	function modal2resize(){
		var modal = document.getElementById('_ajax_modal2_'+self.id+'_'+indicemodal);

		if (modal.style.width!=415+'px'){
			modal.style.width = parseInt(modal.style.width.replace('px','')) + 40 + 'px';
			modal.style.height = parseInt(modal.style.height.replace('px','')) + 10 + 'px';
			setTimeout(function(){modal2resize();},20);
		}
		else{
			modal.style.background= 'url(http://www.mafepe.com/images/logomafepe.gif) no-repeat top center #FFF';
			modal.style.height = 'auto';
			modal.innerHTML = '<div style="margin: 50px 0 15px 0; text-align: center;">'+modal2Html+'</p>';
		}
	}


	function bgTrans(){
		if(!document.getElementById('_ajax_trans_'+self.id+'_'+indicemodal))
		{
			var modal = document.createElement('DIV');
			if(document.all)
				modal.style.filter = 'Alpha(Opacity=80)';
			else
				modal.style.MozOpacity='0.8';
			
				/*
				modal.style.backgroundColor = 'transparent'; 
				modal.style.backgroundImage = 'url(/images/px.gif)';
				modal.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader (src="/images/px.png", sizingMethod="scale")';
				*/

				/* modal.style.backgroundImage = 'url(/images/px.png)'; */
			
			//modal.style.backgroundColor = self.transBgColor;
			modal.style.position = 'absolute';
			if (window.ActiveXObject)
			modal.style.height = (document.body.scrollHeight?document.body.scrollHeight:document.documentElement.scrollHeight)+'px';
			else
			modal.style.height = document.documentElement.scrollHeight+"px";
			modal.style.top = '0px';
			modal.style.left = '0px';
			modal.style.zIndex = 1000*indicemodal;
			modal.style.width = '100%';
			modal.className = 'ajax_trans';
			modal.id = '_ajax_trans_'+self.id+'_'+indicemodal;

			document.body.appendChild(modal);
			visionCombos('hidden');
		}
	}

	function fadeIn(ventana,opacidad){
		if(document.all)
			ventana.style.filter='progid:DXImageTransform.Microsoft.Alpha(opacity='+opacidad+')';
		else{
			if(opacidad>=100)
				ventana.style.MozOpacity='1.00';
			else
				ventana.style.MozOpacity='.'+opacidad;
		}
		
		if(opacidad<100)
			if(document.all)
				setTimeout(function(){fadeIn(ventana,opacidad+10)},1);
			else
				setTimeout(function(){fadeIn(ventana,opacidad+25)},1);
	}
	
	function fadeOut(ventana,opacidad){
		if(document.all)
			ventana.style.filter='progid:DXImageTransform.Microsoft.Alpha(opacity='+opacidad+')';
		else
			ventana.style.MozOpacity='.'+opacidad;

		if(opacidad>0)
			if(document.all)
				setTimeout(function(){fadeOut(ventana,opacidad-10)},1);
			else
				setTimeout(function(){fadeOut(ventana,opacidad-25)},1);
		else
			self.hideModal();
	}

	function visionCombos(opcion){
		if(document.all){
			if(indicemodal<=1)
				var arr = document.getElementsByTagName('select');
			else
				if(document.getElementById('_ajax_modal2_'+self.id+'_'+(indicemodal-1)))
					var arr = document.getElementById('_ajax_modal2_'+self.id+'_'+(indicemodal-1)).getElementsByTagName('select');
				else
					if(document.getElementById('_ajax_modalcontent_'+self.id+'_'+(indicemodal-1)))
						var arr = document.getElementById('_ajax_modalcontent_'+self.id+'_'+(indicemodal-1)).getElementsByTagName('select');

			for(i = 0; i < arr.length; i++)
				arr[i].style.visibility = opcion;
		}
		// También para flash
		var arr = document.getElementsByTagName('object');
		for(i = 0; i < arr.length; i++)
			arr[i].style.visibility = opcion;

		var arr = document.getElementsByTagName('embed');
		for(i = 0; i < arr.length; i++)
			arr[i].style.visibility = opcion;
	}
	
	function getScrollY(){
		var scrollY = 0;
		
		if ( document.body && document.body.scrollTop ){
			scrollY = document.body.scrollTop;
		}else if ( document.documentElement && document.documentElement.scrollTop ){
			scrollY = document.documentElement.scrollTop;
		}else if ( window.pageYOffset ){
			scrollY = window.pageYOffset;
		}else if ( window.scrollY ){
			scrollY = window.scrollY;
		}
		
		return scrollY;
	}

	// Necesario para poder instanciar la clase en el onreadystatechange
	self = this;
}