/**
* Libreria que construye una suggestion box asociada a una caja de texto.
* Los valores mostrados saldran de una peticion AJAX.
*
* Para utilizarlo es necesario llamar a la funcion IJ_AU_addAutocomplete(text),
* pasandole la caja de texto a la que asociarse. Esta caja de texto debe tener
* una serie de atributos especificos para configurar el componente.
*
* Los atributos obligatorios son los siguientes :
* - acURL : Indica la URL a la que realizar la peticion AJAX. A esta se
*						concatenará direcamente el valor de la caja de texto, por lo
*						que la URL ya deberá llevar el nombre del parametro.
*						Ejemplo : acURL="datos.cfm?txt="
*						El formato en que se deben devolver los datos es en una lista de JSON,
*						es decir : ["valor1","valor2","valor3",etc]
*
*
* Los atributos NO obligatorios son los siguientes :
* - acMaxList 	:	Indica el nº máximo de elementos que se quiere mostrar.
* - acMaxHeight : Indica el tamaño máximo en pixeles que tendrá la caja.
* - acWidth 		:	Indica el ancho que tendrá la caja.
* 								Valores posibles : - 'auto' (por defecto) La caja adaptará el ancho para que
*																						  quepa todo el contenido.
*																		 - 'box' La caja tomará el mismo ancho que la caja de texto.
*																		 - Cualquier numero, se tomará como ancho fijo.
* - acPosition 	: Indica si la caja debe aparecer por encima o por de bajo de la caja de texto.
*								 	Valores posibles : - 'top' La caja se muestra por encima.
*								 										 - 'bottom' (por defecto) La caja se muestra por debajo.
**/


var IJ_AU_isExplorer = window.ActiveXObject;
var IJ_AU_isOpera = navigator.userAgent.toLowerCase().indexOf("opera")>-1;

/**
 * FUNCIONES DE UTILIDAD
 */

//Funcion para añadir eventos
function IJ_AU_addEvent( obj, type, fn ) {
 if ( obj.attachEvent ) {
   obj['e'+type+fn] = fn;
   obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
   obj.attachEvent( 'on'+type, obj[type+fn] );
 } else
   obj.addEventListener( type, fn, false );
}

//Funcion para conseguir la posicion absoluta
function IJ_AU_findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}

//Funcion para conseguir la tecla pulsada en un evento.
function IJ_AU_getKey(e){
  if( !e ) {
    //if the browser did not pass the event information to the
    //function, we will have to obtain it from the event register
    if( window.event ) {
      //Internet Explorer
      e = window.event;
    } else {
      //total failure, we have no way of referencing the event
      return;
    }
  }
  if( typeof( e.keyCode ) == 'number'  ) {
    //DOM
    e = e.keyCode;
  } else if( typeof( e.which ) == 'number' ) {
    //NS 4 compatible
    e = e.which;
  } else if( typeof( e.charCode ) == 'number'  ) {
    //also NS 6+, Mozilla 0.9+
    e = e.charCode;
  } else {
    //total failure, we have no way of obtaining the key code
    return;
  }
  return e;
}	

/**
 *  FIN DE FUNCIONES DE UTILIDAD
 */
 
 
//Funcion que añade el autocomplete a una caja de texto.
//Se le pasa el input text.
function IJ_AU_addAutocomplete(text){
	var container = text.parentNode;
	var div = document.createElement("div");
	div.id="IJ_autocomplete_" + text.id;
	if( text.getAttribute("acmaxlist") ){
		div.maxList = text.getAttribute("acmaxlist");
	}
	else{
		div.maxList = 999999999;
	}
	if( text.getAttribute("acmaxheight") ){
		div.maxHeight = text.getAttribute("acmaxheight");
		div.style.height = div.maxHeight;
	}
	if( text.getAttribute("acurl") ){
		div.acURL= text.getAttribute("acurl");
	}
	if( text.getAttribute("acPosition") ){
		div.position = text.getAttribute("acPosition");
	}
	else{
		div.position = "bottom";
	}
	if( text.getAttribute("acWidth") ){
		var width = text.getAttribute("acWidth");
		div.acWidth = width;
		if( width == 'box' ){
			div.style.width = text.offsetWidth + "px";
		}
		else{
			width = parseInt(width);
			if( width > 0 ){
				div.style.width = width;
			}else{
				div.acWidth = 'auto';
			}
		}
	}else{
		div.acWidth = 'auto';
	}
	
	var pos = IJ_AU_findPos(text);
	var topText = pos[1];
	var leftText = pos[0];
	div.style.top = topText + text.offsetHeight;
	div.style.left = leftText;
	
	div.style.display="none";	
	div.style.overflow= "auto";
	div.className = "IJ_AU_caja";
	div.textBox = text;	
	div.posicion = -1;
	document.body.appendChild(div);
	
	IJ_AU_addEvent(text , 'keyup' , function(event){IJ_AU_autocompleteHandler(event , text);});
	IJ_AU_addEvent(window , 'resize' , function(event){redimension(div);});
	IJ_AU_addEvent(text , 'dblclick' , function(event){IJ_AU_autocompleteHandler(event , text);});
	if( IJ_AU_isOpera ){
		IJ_AU_addEvent(text , 'keypress' , function(event){IJ_AU_moverCursor(event , text );});
	}
	else{
		IJ_AU_addEvent(text , 'keydown' , function(event){IJ_AU_moverCursor(event , text );});
	}
	if( ( !IJ_AU_isExplorer && !IJ_AU_isOpera ) || div.maxList != 999999999 ){
		IJ_AU_addEvent(text , 'blur' , function(event){IJ_AU_cerrarCaja(event , text );});
	}
}

function redimension(text){
	var div = document.getElementById("IJ_autocomplete_" + text.id);
	for( var i = 0; i < document.body.childNodes.length ; i++){
		var node = document.body.childNodes[i];
		if( node.id ){
			if( node.id.indexOf("IJ_autocomplete_") == 0 ){
				if( node.style.display == "" ){
					var pos = IJ_AU_findPos(node.textBox);
					var topText = pos[1];
					var leftText = pos[0];
					node.style.top = topText + node.textBox.offsetHeight + "px";
					node.style.left = leftText + "px";			
				}
			}
		}
	} 
}

//Oculta la caja tras esperar un intervalo de tiempo. Esto es así porque cuando
//se clicka con el raton en una de las opciones, se pierde el foco de la caja y se
//llama a esta funcion antes de procesar el evento click. Entonces, si la caja se
//oculta directamente, el evento click no llega a producirse.
function IJ_AU_cerrarCaja(event , text , timeout ){
	if(!timeout){
		timeout = 200;
	}
	setTimeout("document.getElementById(\"IJ_autocomplete_" + text.id+"\").style.display = 'none'" , timeout);
}

//Evalua las teclas pulsadas y realiza acciones segun la tecla que sea.
//Las posibilidades son las siguientes:
// - Flecha arriba(40) : Mueve el cursor en el listado hacia arriba.
// - Flecha abajo(38) : Mueve el cursor en el listado hacia abajo.
// - Intro(13) : Selecciona el valor marcado.
// - Esc(27) : Cierra la caja.
function IJ_AU_moverCursor(event, text){
	var div = document.getElementById("IJ_autocomplete_" + text.id);
	var key = IJ_AU_getKey(event);				
	if( key == 38 ){
		if( div.style.display == '' && div.posicion > 0 ){
			IJ_AU_marcar(div.childNodes[0] , div.posicion - 1);
		}
	}
	else if( key == 40 ){
		if( div.style.display == '' && div.posicion < div.childNodes.length - 1 ){
			IJ_AU_marcar(div.childNodes[0] , div.posicion + 1);
		}
	}				
	else if( key == 13 ){
		if( div.style.display == '' && div.posicion >= 0 ){
			IJ_AU_seleccionarValor(div.childNodes[div.posicion]);
		}
		else{
			IJ_AU_cerrarCaja(null,text,0);
		}
	}				
	else if( key == 27 ){
		IJ_AU_cerrarCaja(null,text,0);
		//Necesario para explorer, ya que sino, 'esc' vuelve a poner el valor anterior de la caja.
		text.value = text.value;
	}
}

//Analiza que no se haya pusado una tecla de 'IJ_AU_moverCursor' y,
//en caso de que la caja de texto no este vacia, realiza la busqueda.
function IJ_AU_autocompleteHandler(event , text , llamar){
	var div = document.getElementById("IJ_autocomplete_" + text.id);
	var key = IJ_AU_getKey(event);
	if( key != 38 && key != 40 && key != 27 && key != 13 ){
		if( text.value == "" ){
			div.style.display = "none";
		}
		else{
			IJ_AU_hacerBusqueda(text , div);
		}
	}
}

//Realiza la peticion por AJAX para conseguir los valores a mostrar.
function IJ_AU_hacerBusqueda(text , div){
	var the_object;
	var http_request;
	if (window.XMLHttpRequest) { // Mozilla, Safari, ...
		http_request = new XMLHttpRequest();
	} else if (window.ActiveXObject) { // IE
		http_request = new ActiveXObject("Microsoft.XMLHTTP");
	}
	http_request.open( "GET", div.acURL+escape(text.value), true );
	http_request.onreadystatechange = function () {
		if ( http_request.readyState == 4 ) {
			if ( http_request.status == 200 ) {
				entradas = eval("("+http_request.responseText+")");
				var coleccion = entradas;
				//Esto lo tengo que quitar. Es por culpa de cache
				if( !coleccion.length && entradas.resultados ){
					coleccion = entradas.resultados;
				}					
				if( coleccion.length > 0 ){
					var html = "";		
					if( div.position == "top" ){
						coleccion.reverse();
					}
					for(var i=0;i<coleccion.length && i < div.maxList;i++){
						html += "<div onmouseover=\"IJ_AU_marcar(this , "+i+
							");\" onclick=\"IJ_AU_seleccionarValor(this)\" class=\"IJ_AU_item\">"+
							coleccion[i]+"</div>";
					}					         			
					if( ( IJ_AU_isExplorer || IJ_AU_isOpera ) && div.acWidth == 'auto' ){
						div.style.width = "";
					}
					div.innerHTML=html;
					div.style.display="";

					var pos = IJ_AU_findPos(text);
					var topText = pos[1];
					var leftText = pos[0];
					div.style.top = topText + text.offsetHeight + "px";
					div.style.left = leftText + "px";
	
					var altura = div.childNodes[0].offsetHeight * ( coleccion.length );
					if( parseInt(div.maxHeight) > 0 ){
						div.style.height = div.maxHeight;
						var altCaja = parseInt(div.style.height);
						if( altCaja > 0 && altCaja > altura ){
							if( IJ_AU_isExplorer ){
								div.style.height = altura+2;
							}
							else{
								div.style.height = altura;					
							}
						}
					}
					if( div.position == "top" ){												
						var pos = IJ_AU_findPos(div.textBox);
						div.style.top = pos[1] - div.offsetHeight;
						
						if( altura  > div.offsetHeight ){
							div.scrollTop = altura - div.offsetHeight;
						}
						div.posicion = coleccion.length;
						//IJ_AU_marcar( div.childNodes[0] , coleccion.length - 1 );
					}
					else{
						div.scrollTop = 0;
						div.posicion = -1;
						//IJ_AU_marcar( div.childNodes[0] , 0 );
					}
					altura += div.childNodes[0].offsetHeight;
					if( ( IJ_AU_isExplorer || IJ_AU_isOpera ) && div.acWidth == 'auto' ){
						if( altura > div.offsetHeight ){
							div.style.width = div.offsetWidth + 20;
						}
					}
				}
				else{
					div.style.display="none";
				}
			} else {
				alert( "There was a problem with the URL." );
			}
			http_request = null;
		}
	};
	http_request.send(null);
}

//Desmarca la opcion que estubiera marcada antes, en caso de haberla,
//y marca la opcion de la posicion 'pos'.
function IJ_AU_marcar(div , pos){
	var padre = div.parentNode;
	if( padre.posicion >= 0 && padre.childNodes[padre.posicion] ){
		padre.childNodes[padre.posicion].className = "IJ_AU_item";
	}
	padre.posicion=pos;				
	padre.childNodes[padre.posicion].className = "IJ_AU_itemSeleccionado";
	var altura = padre.childNodes[padre.posicion].offsetHeight * ( pos + 1 );
	if( altura > padre.offsetHeight + padre.scrollTop ){
		padre.scrollTop = altura - padre.offsetHeight;
	}
	else{
		altura = padre.childNodes[padre.posicion].offsetHeight * pos;
		if( altura < padre.scrollTop ){
			padre.scrollTop = altura;
		}						
	}
}

//Selecciona el valor del div que se le pasa y se coloca en la caja
//de texto. A continuacion se cierra la caja.
function IJ_AU_seleccionarValor(div){
	var padre = div.parentNode;
	padre.textBox.value = div.innerHTML;
	padre.childNodes[padre.posicion].className = "IJ_AU_item";
	padre.style.display = "none";
	padre.textBox.focus();				
}
