var AutoCompletePads = Class.create();

AutoCompletePads.prototype = {
	_out: '',
	_elm: '',
	_id: '',
	_hidden: '',
	_selItem: 0,
	_txt_tmr: '',
	_txt_tmout: '',
	_sug: [],
	_lastValue: '',
	_oninicialookup: '',
	_onchange: '',
	
	initialize: function ( id, hidden, oninicialookup, onchange ) {
		
		this._elm = $( id );
		if ( !this._elm )
		{
			throw( "AutoCompletePads requiere un ID de elemento valido para inicializarse." );
		}
		
		this._id = id;
		this._hidden = $( hidden );
		this._onchange = onchange;
		this._oninicialookup = oninicialookup;
		
		var instancia = this;
		
		Event.observe( this._elm, 'blur', function ( event ) {
			if ( instancia._selItem > 0 )
			{
				instancia.setText( instancia._selItem );
				instancia.removeItems( );
			}
			
			if ( instancia.trim( instancia._hidden.value ) == '0' )
			{
				instancia._elm.value = '';
			}
		} );
		
		this._elm.onkeypress = function ( event ) {
			
			if ( !event ) event = window.event;
			
			var key = event.keyCode || event.wich;
			
			if ( key == Event.KEY_RETURN )
			{
				if ( instancia._selItem > 0 )
				{
					instancia.setText( instancia._selItem );
					instancia.removeItems( );
				}
				
				Event.stop( event );
			}
			else if ( key == Event.KEY_TAB )
			{
				// console.log( 'TAB!' );
				if ( instancia._selItem > 0 )
				{
					instancia.setText( instancia._selItem );
					instancia.removeItems( );
				}
			}
			else if ( key == Event.KEY_ESC )
			{
				instancia.clearHighlight( );
				instancia.removeItems( );
				
				Event.stop( event );
			}
			return true;
		};
		
		Event.observe( this._elm, 'keyup', function ( event ) {
			var elm = Event.element( event );
			
			var key = event.keyCode || event.wich;
			
			if ( key == Event.KEY_UP || key == Event.KEY_DOWN )
			{
				instancia.changeSelection( key );
				
				Event.stop( event );
			}
			else if ( instancia.hasChanged( elm ) )
			{
				var newVal = instancia.trim( elm.value );
				instancia._hidden.value = '0';
				
				// console.log( instancia._id + ': hasChanged, set value 0' );
				
				instancia._lastValue = newVal;
				
				if ( typeof instancia._oninicialookup == 'function')
				{
					instancia._oninicialookup( elm );
				}
				
				if ( newVal && newVal.length > 0 )
				{
					elm.addClassName( 'autocomplete_txt_busy' );
					
					clearTimeout( instancia._txt_tmr );
					
					instancia._txt_tmr = setTimeout( function ( ) {
						new Ajax.Request( '/master/tools/padsLookup.aspx', {
								method: 'get',
								parameters: 'q=' + newVal,
								onSuccess: function ( transport ) {
									instancia.showResult( transport.responseText );
								},
								onFailure: function ( transport ) {
									instancia._elm.removeClassName( 'autocomplete_txt_busy' );
									alert( 'Error intentando obtener informacion de paradas.\nPor favor intente nuevamente.' );
								}
							}
						);
					},
					500 );
				}
			}
			return true;
		} );
		
		if ( this._elm && this._elm.value.length > 0 )
		{
			this._lastValue = this._elm.value;
		}
		
		/*
		if ( this._hidden && this._hidden.value.length > 0 && !isNaN( this._hidden.value ) && parseInt( this._hidden.value ) > 0 )
		{
			if ( typeof this._oninicialookup == 'function')
			{
				this._oninicialookup( this._elm );
			}
			
			new Ajax.Request( '/master/tools/padsLookup.aspx', {
								method: 'get',
								parameters: 'q=' + this._hidden.value,
								onSuccess: function ( transport ) {
									instancia.showOne( transport.responseText );
								},
								onFailure: function ( transport ) {
									instancia._elm.removeClassName( 'autocomplete_txt_busy' );
									alert( 'Error intentando obtener informacion de paradas.\nPor favor intente nuevamente.' );
								}
							}
						);
		}
		*/
	},
	
	showOne: function( response )
	{
		var sug = eval( response );
		
		if ( sug && sug.length > 0 )
		{
			var item = sug[ 0 ];
			
			this._lastValue = item.text;
			this._elm.value = item.text;
			this._hidden.value = item.id;
			
			// console.log( this._id + ': Set IdPad ' + item.id );
			
			if ( typeof this._onchange == 'function')
			{
				this._onchange( this._elm, item );
			}
		}
		else
		{
			this._hidden.value = '0';
			this._elm.value = '';

			// console.log( this._id + ': Set IdPad 0' );
		}
	},
	
	relocateOutPanel: function( )
	{
		this._out = $( 'out' );
		
		if ( this._out == undefined )
		{
			this._out = $( document.createElement( 'div' ) );
			this._out.id = 'out';
		}
		
		if ( this._out.parentNode != this._elm.parentNode )
		{
			if ( this._out.parentNode != undefined )
			{
				this._out.remove( );
			}
			this._elm.parentNode.appendChild( this._out );
		}
	},
	
	showResult: function ( response )
	{
		this._sug = eval( response );
		
		if ( this._sug && this._sug.length > 0 )
		{
			if ( document.activeElement != this._elm )
			{
				this.setText( 1 );
				this.removeItems( );
			}
			else
			{
				this.relocateOutPanel( );
				
				this.clearItems( this._out );
				
				var ul = document.createElement( 'ul' );
				ul.id = 'ac_ul';
				this._out.appendChild( ul );
				
				var instancia = this;
				
				for ( var i=0; i < this._sug.length; i++ )
				{
					var item = this._sug[ i ];
					
					var li = document.createElement( 'li' );
					li.name = i;
					li.innerHTML = item.text;
					ul.appendChild( li );
					
					Event.observe( li, 'mouseover', function ( event ) {
						var elm = Event.element( event );
						
						instancia.setHighlight( elm.name + 1 );
					} );
					
					Event.observe( li, 'click', function ( event ) {
						var elm = Event.element( event );
						
						instancia.setText( elm.name + 1 );
						instancia.removeItems( );
					} );
				}
				
				this._out.addClassName( 'visible' );
				
				/* POSICIONAMIENTO */
				var pos = this._elm.cumulativeOffset();
				this._out.style.left 	= pos[0] + "px";
				this._out.style.top 	= pos[1] + this._elm.offsetHeight + "px";
		
				var w = this._elm.offsetWidth;
			    
				this._out.style.width 	= w + "px";
				/* FIN POSICIONAMIENTO */
				
				this._selItem = 1;
				this.setHighlight( this._selItem );
				
				this._txt_tmout = setTimeout( function( ) {
						instancia.removeItems( );
					},
					2500 );
				
				Event.observe( this._out, 'mouseover', function ( event ) {
					instancia.clearTmout( );
				} );
				
				Event.observe( this._out, 'mouseout', function ( event ) {
					if ( instancia._txt_tmout != undefined )
					{
						instancia.resetTmout( instancia._out );
					}
				} );
			}
		}
		
		this._elm.removeClassName( 'autocomplete_txt_busy' );
		
	},
	
	clearTmout: function( )
	{
		if ( this._txt_tmout != undefined )
		{
			clearTimeout( this._txt_tmout );
		}
	},
	
	resetTmout: function( out )
	{
		this.clearTmout( );
		
		var instancia = this;
		
		this._txt_tmout = setTimeout( function( ) {
				instancia.removeItems( );
			},
			2500 );
	},
	
	removeItems: function( )
	{
		this.clearItems( this._out );

		if ( this._out.parentNode != undefined )
		{
			this._out.remove( );
		}
	},
	
	clearItems: function( out )
	{
		if ( out && out.hasChildNodes( ) )
		{
		    while ( out.childNodes.length >= 1 )
		    {
		        out.removeChild( out.firstChild );       
		    }
		}
	},
	
	hasChanged: function( elm )
	{
		return ( this._lastValue != this.trim( elm.value ) );
	},
	
	setText: function( n )
	{
		if ( this._sug != undefined && n > 0 && this._sug[ n - 1 ] )
		{
			var item = this._sug[ n - 1 ];
			this._lastValue = item.text;
			this._elm.value = item.text;
			this._hidden.value = item.id;
			
			// console.log( this._id + ': setText id ' + item.id );
			
			if (typeof this._onchange == 'function')
			{
				this._onchange( this._elm, item );
			}
		}
		else
		{
			this._hidden.value = '0';
			
			// console.log( this._id + ': setText id 00' );
		}
	},
	
	trim: function( text )
	{
		for ( i=0; i < text.length; )
		{
			if( text.charAt(i)==" " )
				text = text.substring( i + 1, text.length );
			else
				break;
		}
		
		for ( i = text.length-1; i >= 0; i = text.length - 1 )
		{
			if ( text.charAt( i ) == " " )
				text = text.substring( 0, i );
			else
				break;
		}
		
		return text;
	},
	
	changeSelection: function( key )
	{
		var list = $( 'ac_ul' );
		if ( !list )
		{
			return false;
		}
		
		var n;
		
		n = ( key == Event.KEY_DOWN || key == Event.KEY_TAB ) ? this._selItem + 1 : this._selItem - 1;
		
		n = ( n > list.childNodes.length ) ? list.childNodes.length : ( ( n < 1 ) ? 1 : n );
		
		this.setHighlight( n );
		
		this.scrollToItem( n );
		
		this.resetTmout( this._out );
	},
	
	setHighlight: function( n )
	{
		var list = $('ac_ul');
	  	
		if ( !list )
		{
			return false;
		}
		
		if ( this._selItem > 0 )
		{
			this.clearHighlight( );
		}
	  	
	  	this._selItem = Number( n );
		
		var listItem = $( list.childNodes[ this._selItem - 1 ] );
		listItem.addClassName( 'ac_highlight' );
		
		this.clearTmout( );
	},
	
	scrollToItem: function( n )
	{
		var list = $('ac_ul');
		var listItem = $( list.childNodes[ Number( n ) - 1 ] );
		
		// console.log( listItem.offsetTop + ', ' + list.scrollTop + ', ' + list.getHeight() );
		
		if ( listItem.offsetTop > list.scrollTop && listItem.offsetTop + listItem.getHeight() < list.scrollTop + list.getHeight() )
		{
			// do nothing
		}
		else if ( listItem.offsetTop < list.scrollTop )
		{
			list.scrollTop = listItem.offsetTop - 3;
		}
		else if ( ( listItem.offsetTop + listItem.getHeight( ) > list.offsetHeight ) )
		{
			list.scrollTop = listItem.offsetTop - ( list.getHeight( ) - listItem.getHeight( ) ) + 3;
		}
	},
	
	clearHighlight: function( )
	{
		var list = $('ac_ul');
	  	
		if( !list )
		{
			return false;
		}
	  	
		if( this._selItem > 0 )
		{
			$( list.childNodes[ this._selItem - 1 ] ).removeClassName( 'ac_highlight' );
			
			this._selItem = 0;
		}
	}
}
