var varContainer = new Class
( {
	
	Implements: [Options, Events],
	
	options:
	{
		'position':			0,
		'count':			0,
		'keys':				"",
		'parametrs':		0,
		'currentParametrs':	0
	},
	
	initialize: function( options )
	{
		this.setOptions( options );
	},
	
	setPosition: function( vars )
	{
		this.options.position = vars;
	},
	
	getPosition: function()
	{
		return this.options.position;
	},
	
	setCount: function( vars )
	{
		this.options.count = vars;
	},
	
	getCount: function()
	{
		return this.options.count;
	},
	
	setKeys: function( vars )
	{
		this.options.keys = vars;
	},
	
	getKeys: function()
	{
		return this.options.keys;
	},
	
	setParametrs: function( vars )
	{
		this.options.parametrs = vars;
	},
	
	getParametrs: function()
	{
		return this.options.parametrs;
	},
	
	setCurrentParametrs: function( vars )
	{
		this.options.currentParametrs = vars;
	},
	
	getCurrentParametrs: function()
	{
		return this.options.currentParametrs;
	},
	
	clear: function()
	{
		this.options.position = 0;
		this.options.count = 0;
		this.options.keys = "";
		this.options.parametrs = 0;
		this.options.currentParametrs = 0;
	}
} );

var jsonRequest = new Class
( {
	
	initialize: function( url, results, vars )
	{
		this.serverUrl = url;
		this.results = results;
		this.vars = vars;
	},
	
	getParametrs: function( keys )
	{
		var parametrsRequest = new Request.JSON( 
		{ 'url': this.serverUrl,
			'onSuccess': function( xmlResp, textResp )
			{
				var parametrsResponse = JSON.decode(textResp);
				this.vars.setParametrs( parametrsResponse );
				this.results.out( parametrsResponse );
			}.bind( this )
		} ).get( 
		{
			'keys'	: keys
		} );
	}
	
} );

var tableResults = new Class
( {
	
	initialize: function( input, output, vars )
	{
		this.input = input;
		this.output = output;
		this.vars = vars;
	},
	
	clear: function()
	{
		this.output.set( 'html', "" );
	},
	
	out: function( parametrs )
	{
		this.vars.setPosition( 0 );
		this.clear();
		this.hide();
		if ( parametrs.length > 0 )
		{		
			this.clear();
			this.show();
			parametrs.each( function( item, index ) 
			{
				var tableTR = new Element( 'tr',
				{
					'id': 'item-' + ( index + 1 ),
					'class': 'table-line'
				} );
				var tableTD = new Element( 'td',
				{
					'html': item
				} );
				var tempThis = this;
				tableTD.addEvent( 'mouseenter', function(e) 
				{
					this.getParent().setStyle( 'background-color', 'lightgray' );
					if ( tempThis.vars.getPosition() != 0 )
					{
						document.id( 'item-' + tempThis.vars.getPosition() ).setStyle( 'background-color', 'white' );
					}
					tempThis.vars.setPosition( this.getParent().get( 'id' ).substring( 5 ) );
				} );
				tableTD.addEvent( 'mouseleave', function(e) 
				{
					this.getParent().setStyle( 'background-color', 'white' );
				} );
				tableTD.addEvent( 'click', function(e) 
				{
					tempThis.setChoise( this.get( 'html' ) );
					tempThis.hide();
					tempThis.input.focus();
				} );
				tableTD.inject( tableTR );
				tableTR.inject( this.output );
			}.bind( this ) );
		}
	},
	
	getUp: function()
	{
		count = document.getElements( '.table-line' ).length;
		if ( count > 0 )
		{
			if ( this.vars.getPosition() != 0 )
			{
				document.id( 'item-' + this.vars.getPosition() ).setStyle( 'background-color', 'white' );
			}
			else
			{
				this.vars.setPosition( count + 1 );
			}
			if( this.vars.getPosition() == 1 )
			{
				this.vars.setPosition( count );
			}
			else
			{
				this.vars.setPosition( this.vars.getPosition().toInt() - 1 );
			}
			document.id( 'item-' + this.vars.getPosition() ).setStyle( 'background-color', 'lightgray' );
		}
	},
	
	getDown: function()
	{
		count = document.getElements( '.table-line' ).length;
		if ( count > 0 )
		{
			if ( this.vars.getPosition() != 0 )
			{
				document.id( 'item-' + this.vars.getPosition() ).setStyle( 'background-color', 'white' );
			}
			if( this.vars.getPosition() == count )
			{
				this.vars.setPosition( 1 );
			}
			else
			{
				this.vars.setPosition( this.vars.getPosition().toInt() + 1 );
			}
			document.id( 'item-' + this.vars.getPosition() ).setStyle( 'background-color', 'lightgray' );
		}
	},
	
	setChoise: function( word )
	{
		text = this.input.get( 'value' );
		if ( this.vars.getPosition() != 0 )
		{
			var outputText = "";
			temp = text.split( ',' );
			temp.each( function( item, index )
			{
				if ( index != ( temp.length - 1 ) )
				{
					outputText += item.trim() + ", ";
				}
				else
				{
					outputText += word;
				}
			} );
			this.input.set( 'value', outputText );
		}
	},
	
	show: function()
	{
		this.output.setStyle( 'display', 'block' );
	},
	
	hide: function()
	{
		this.output.setStyle( 'display', 'none' );
	}
	
} );

var stringProcessor = new Class
( {
	
	initialize: function( vars )
	{
		this.vars = vars;
	},
	
	getLast: function( text )
	{
		var last = "";
		str = text.split(',');
		tmpLast = str.getLast().trim();
		last = tmpLast;
		return last;
	},
	
	checkKeys: function( text )
	{
		needToRequest = false;
		if( ( text != "" ) && ( text.substring( 0, 1 ) != this.vars.getKeys() ) )
		{
			needToRequest = true;
		}
		return needToRequest;
	},
	
	updateCurrentParametrs: function( text )
	{
		var tmpCurrentParams = new Array();
		var tmpParams = this.vars.getParametrs();
		if ( text != "" )
		{
			tmpParams.each( function( item, index ) 
			{
				if ( text.toLowerCase() == item.substring( 0, text.length ).toLowerCase() )
				{
					tmpCurrentParams.push( item );
				}
			} );
			if ( this.vars.getCurrentParametrs() != tmpCurrentParams )
			{
				this.vars.setCurrentParametrs( tmpCurrentParams );
				return true;
			}
			else
			{
				return false;
			}
		}
		else
		{
			return false;
		}
	}
} );

var kernel = new Class
( {
	
	Implements: [Options, Events],
	
	options:
	{
		'qwe': 'qwe'
	},
	
	initialize: function( options, inputID, tableID, url )
	{
		this.setOptions( options );
		this.input = document.id( inputID );
		this.output = document.id( tableID );
		
		this.vars = new varContainer( null );
		this.results = new tableResults( this.input, this.output, this.vars );
		this.requests = new jsonRequest( url, this.results, this.vars );
		this.strOperations = new stringProcessor( this.vars );
				
		this.addEventsToElements();
		
	},
	
	addEventsToElements: function()
	{
		this.input.addEvent( 'blur', function(e) 
		{
			//this.results.hide();
		}.bind( this ) );
		
		this.input.addEvent( 'keydown', function(e) 
		{
			if ( e.code == 13 )
			{
				e.stop();
			}
		} );
		
		this.input.addEvent( 'keyup', function(e) 
		{
			if ( e.code == 38 )
			{
				this.pressedUp( e );
			}
			else if ( e.code == 40 )
			{
				this.pressedDown( e );
			}
			else if ( e.code == 13 )
			{
				this.pressedEnter( e );
			}
			else
			{
				this.pressedOtherKeys( e );
			}
		}.bind( this ) );
	},
	
	pressedUp: function( e )
	{
		this.results.getUp();
	},
	
	pressedDown: function( e )
	{
		this.results.getDown();
	},
	
	pressedEnter: function( e )
	{
		this.results.setChoise( document.id( 'item-' + this.vars.getPosition() ).getChildren().get( 'html' ) );
		last = this.strOperations.getLast( this.input.get( 'value' ) );
		if ( this.strOperations.updateCurrentParametrs( last ) )
		{
			this.results.out( this.vars.getCurrentParametrs() );
		}
	},
	
	pressedOtherKeys: function( e )
	{
		last = this.strOperations.getLast( this.input.get( 'value' ) );
		if ( last == "" )
		{
			this.results.hide();
			this.results.clear();
		}
		needToRequest = this.strOperations.checkKeys( last );
		if ( needToRequest )
		{
			this.vars.setKeys( last.substring( 0, 1 ) );
			this.requests.getParametrs( last.substring( 0, 1 ) );
		}
		if ( this.strOperations.updateCurrentParametrs( last ) )
		{
			this.results.out( this.vars.getCurrentParametrs() );
		}
	}
	
} );

