// CLASE GENÉRICA PARA APLICACIONES AJAX (25/08/06)
//
// 22/09/06: showModalURL(url,ancho,alto) - Crea una ventana modal con un iframe para mostrar la url dentro con tamaño ancho y alto.
//
// 10/10/06: propiedad id  (identificador único para cada objeto). 
//			 propiedad loaderror (función a ejecutar cuando hay error de parseado).
//			 posibilidad de abrir ventanas modales unas sobre otras
//
// 20/10/06: showModalFade(html) - muestra ventana con efecto fade (fundido).
// 			 hideModalFade() - oculta ventana con efecto fade (fundido).
//
// 10/01/07: propiedad post - Si metemos un string en la propiedad post, se realizará una llamada POST enviando ese texto en lugar de GET.
//
//
//	PROPIEDADES:
//		Para XML:
//
//		- id :  			contiene un identificador único
//		- xmlDoc :  		objeto que contiene el documento xml
//		- url : 			url del documento xml
//		- loading : 		función a ejecutar mientras carga el xml
//		- loaderror : 		función a ejecutar cuando ocurre un error de parseado (si no se especifica, se ejecuta la rutina habitual de reintento)
//		- f : 				función a ejecutar una vez cargado el xml
//		- running : 		booleano. Nos dice si el objeto está en ejecución 
//							(desde que ejecutamos .run() hasta que ejecutamos la función f). Puede ser útil para concurrencia.
//		- post :			Si establecemos esta variable, enviaremos la cadena que asignemos por POST
//
//		Para mensajes y efectos:
//
//		- hideTimeout : 	tiempo que tarda en cerrarse la etiqueta cuando el mensaje no es de error (por defecto 2 sec.)
//		- errorTimeout : 	tiempo que tarda en cerrarse la etiqueta cuando el mensaje es de error (por defecto 5 sec.)
//
//
//	MÉTODOS:
//		Para XML:
//
//		- init() : 			Inicializa y resetea el objeto xmlDoc. Es llamado dentro de run(), por lo que no es necesario 
//							llamarlo previamente.
//		- run() : 			inicia la ejecución del xml. Cuando está cargado, chequea errores de parseado. Si los encuentra, 
//							detiene la ejecución y muestra un mensaje para volver a intentar (el error de parseado puede ser
//							temporal). Si tras 3 intentos no consigue cargar el xml detiene la ejecución mostrando un mensaje
//							de error.
//		
//		Para mensajes y efectos:
//
//		- showLabel(msg) :				Muestra una etiqueta tipo google con fondo amarillo y lo mantiene hasta que se oculta o se muestra 
//										otro mensaje.
//		- hideLabel(msg) :				Oculta el mensaje. Si se le pasa un texto lo oculta mostrando el texto durante 2 segundos (por defecto)
//		- errorLabel(msg) :				Oculta el mensaje mostrando un texto de error durante 5 segundos (por defecto)
//		- showModal(html) : 			Muestra una ventana modal centrada vertical y horizontalmente con fondo transparente con el
//										contenido del parámetro html
//		- showModalURL(url,ancho,alto): Crea una ventana modal con un iframe para mostrar la url dentro con tamaño ancho y alto.
//		- showModalPopup(html): 		Muestra una ventana modal que aparece desde el lado izquierdo con fondo transparente y con el
//										contenido del parámetro html
//		- hideModal() :					Oculta las ventanas modales que hubiera abiertas
//		- showModalFade(html)			Muestra ventana modal con efecto fade (fundido).
// 		- hideModalFade()				Oculta ventana con efecto fade (fundido).
//
//
//	WIKI:
//		var ajax = new Ajax();
//		ajax.url = 'prueba.xml';
//		ajax.loading = 'cargando()';
//		ajax.loaderror = 'procesarError()'; (Opcional)
//		ajax.f = 'procesar()';
//		ajax.run();	
//
//		Al instanciar el objeto se le pueden pasar opcionalmente 3 parámetros, correspondientes a las propiedades url, f y loading.  
//		Por ejemplo: 
//		var ajax = new Ajax('prueba.xml','procesar()','cargando()');
//		ajax.run();	
//
//		También se pueden pasar al ejecutar run.  
//		Por ejemplo: 
//		var ajax = new Ajax();
//		ajax.run('prueba.xml','procesar()','cargando()');	
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


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=ISO-8859-1');
			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('Ha ocurrido 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.\nPor 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($('_ajax_label')) document.body.removeChild($('_ajax_label'))},this.hideTimeout*1000);
		}
		else 
			if($("_ajax_label")) 
				document.body.removeChild($("_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($('_ajax_label')) document.body.removeChild($('_ajax_label'))},this.errorTimeout*1000);
	}


	this.showTooltip = function(msg){
		clearTimeout(tooltipTimeout);
		var tt;
		if(!$('_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){
				$('_ajax_tooltip_'+self.id).style.top=((e?e:event).clientY+document.body.scrollTop+20)+'px';
				$('_ajax_tooltip_'+self.id).style.left=((e?e:event).clientX+15)+'px';
			}
		}
		else
			tt = $('_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($('_ajax_tooltip_'+this.id)){
			if(msg){
				$('_ajax_tooltip_'+this.id).style.display='';
				$('_ajax_tooltip_'+this.id).className='ajax_tooltip_off';
				$('_ajax_tooltip_'+this.id).innerHTML = msg;
				tooltipTimeout=setTimeout(function(){$('_ajax_tooltip_'+self.id).style.display='none';},this.hideTimeout*1000);
			}
			else{
				$('_ajax_tooltip_'+this.id).style.display='none';
			}
		}
	}

	this.errorTooltip = function(msg){
		clearTimeout(tooltipTimeout);
		if($('_ajax_tooltip_'+this.id)){
			$('_ajax_tooltip_'+this.id).style.display='';
			$('_ajax_tooltip_'+this.id).className='ajax_tooltip_error';
			$('_ajax_tooltip_'+this.id).innerHTML = msg;
			tooltipTimeout=setTimeout(function(){$('_ajax_tooltip_'+self.id).style.display='none';},this.errorTimeout*1000);
		}
	}

	// Ventana modal centrada
	this.showModal = function(html){
		indicemodal++;
		bgTrans();
		var idventana = '_ajax_modalcontent_'+this.id+'_'+indicemodal;
		
		if(!$(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);
//			visionCombos('hidden');
		}
		
		$(idventana).innerHTML = '<table border="0" width="100%" height="100%" align="center"><tr><td align="center"><div class="modalstyle">'+html+'</div></td></tr></table>';

		$(idventana).style.top = getScrollY();

		/*if(document.all)
			document.body.style.overflow = 'hidden';
		else
			window.onscroll = function(){
				if($(idventana)){
					$(idventana).style.top = getScrollY();
				}
			}*/
	}
	
	// Ventana modal con efecto fadein
	this.showModalFade = function(html){
		this.showModal(html);
		fadeIn($('_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(!$('_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($('_ajax_modal2_'+this.id+'_'+indicemodal)){
					$('_ajax_modal2_'+this.id+'_'+indicemodal).style.top = getScrollY()+15;
				}
			}*/

		modal2mover();
	}
		

	// Ocultar ventanas modales
	this.hideModal = function(){
		visionCombos('visible');
		
		if($('_ajax_modal2_'+this.id+'_'+indicemodal)){
			document.body.removeChild($('_ajax_modal2_'+this.id+'_'+indicemodal));
			document.body.removeChild($('_ajax_trans_'+this.id+'_'+indicemodal));
			indicemodal--;
		}else if($('_ajax_modalcontent_'+this.id+'_'+indicemodal)){
			document.body.removeChild($('_ajax_modalcontent_'+this.id+'_'+indicemodal));
			document.body.removeChild($('_ajax_trans_'+this.id+'_'+indicemodal));
			indicemodal--;
		}

		if(indicemodal>0 && $('_ajax_modalcontent_'+this.id+'_'+indicemodal))
			$('_ajax_modalcontent_'+this.id+'_'+indicemodal).style.top = getScrollY();
	}

	this.hideModalFade = function(){
		if($('_ajax_modal2_'+this.id+'_'+indicemodal))
			fadeOut($('_ajax_modal2_'+this.id+'_'+indicemodal),90);
		else if($('_ajax_modalcontent_'+this.id+'_'+indicemodal))
			fadeOut($('_ajax_modalcontent_'+this.id+'_'+indicemodal),90);		
	}



	// FUNCIONES PRIVATE ///////////////////////

	function crearEtiqueta(){
		if($('_ajax_label'))
			label = $('_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';
			document.body.appendChild(label);
		}

		label.style.top = getScrollY();
	}


	function modal2mover(){	
		var modal = $('_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 = $('_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.facilisimo.com/mensajes/expocasa/images/logo.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(!$('_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';
			modal.style.height = (document.body.scrollHeight?document.body.scrollHeight: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($('_ajax_modal2_'+self.id+'_'+(indicemodal-1)))
					var arr = $('_ajax_modal2_'+self.id+'_'+(indicemodal-1)).getElementsByTagName('select');
				else
					if($('_ajax_modalcontent_'+self.id+'_'+(indicemodal-1)))
						var arr = $('_ajax_modalcontent_'+self.id+'_'+(indicemodal-1)).getElementsByTagName('select');

			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;
	}
	
	function $(id){return document.getElementById(id);}

	// Necesario para poder instanciar la clase en el onreadystatechange
	self = this;
}

