//var prev_entered_strs = [] ;

var fields_to_complete = [] ;


var cur_complete_field = undefined ;

function CompleteField
	( 
			input_field_id
		,	url_to_post_to
		, 	params_to_send_request_with
		, 	request_field_name_entered_str
		, 	get_html_representation_func
		, 	get_str_representation_func
	)
{
	/** int     index of insntance of this object in fields_to_complete **/
	this.id ;
	/**  int    id of input-field to be completed     */
	this.input_field_id ;
	/**         input-field that this complete-field is assigned to  **/
	this.input_field         ;
	/**  string   previously entered str       */
	this.prev_entered_str    ;
	/**   minimum length  of str to be entered before sending request to server **/
	this.min_length = 3      ;
	/**    div where all available options for selecting are located **/
	this.cur_dropdown_list ;
	/** iframe to which is used by this field **/
	this.cur_iframe = undefined ;//@@hack: iframe to hide select in IE
	/**     url to post a request to **/
	this.url_to_post_to ;	
	/**  array of params to send to server with request **/
	this.params_to_send_request_with = undefined ;
	/**  name of field where entered str to put in fields that are sent to server **/
	this.request_field_name_entered_str ;
	/**  function that is used to convert given set of xml-tags to html-representation **/
	this.get_html_representation_func ;
	/**  function that is used to convert given set of xml-tags to str-representation **/
	this.get_str_representation_func ;
	/** array of DOM-node */
	this.xml_items ;
	this.subdivs ;
	/** index of currently selected item in this.xml_items **/
	this.cur_item_index = undefined ;
	
	
	

	this.__construct = function ( input_field_id, url_to_post_to, params_to_send_request_with, request_field_name_entered_str, get_html_representation_func, get_str_representation_func )
	{

		this.id = fields_to_complete.length ; 
		
	
		this.input_field_id = input_field_id ;					
		this.input_field = document.getElementById( this.input_field_id ) ;
		
		if ( !this.input_field )
			return false ;
		
		this.prev_entered_str = this.input_field.value ;
		
		this.url_to_post_to = url_to_post_to ;
		this.params_to_send_request_with = new Array( params_to_send_request_with.length + 1 ) ;
		this.params_to_send_request_with[ request_field_name_entered_str ] = '' ;
		this.request_field_name_entered_str = request_field_name_entered_str ;
		
		this.get_html_representation_func = get_html_representation_func ;
		this.get_str_representation_func = get_str_representation_func ;
		
		
		fields_to_complete[ this.id ] = this ;
		
		this.SetUpEventsHandlers() ;
		
		
	}
	
	/**
	 * function used for sending ajax-request to server to fill specified field
	 *
	 **/
	this.CompleteField = function()
	{
//alert( this.id);	
//alert( this.input_field ) ;
		//get length of entered string from specified input-field		
		var entered_string = this.input_field.value ;
		
		if ( this.prev_entered_str == entered_string )
		{//if prev. entered string is the same as current
			//do nothing
			return ;
		}
	//alert( input_field_name_id ) ;	
	//alert( '"' + prev_entered_strs[input_field_name_id] + '" vs "' + entered_string + '"') ;
		//remember new entered string
		this.prev_entered_str = entered_string ;	
		//check length of value 
		if ( entered_string.length < this.min_length )
		{
			//hide dropdown-list: so even if user simply deleted chars, the old drop-down-list will not be shown to him/her
			if ( undefined != this.cur_dropdown_list )
				this.HideDropdownList() ;
			return ;
		}
		
		//var fields = new Array(1) ;
		this.params_to_send_request_with[ request_field_name_entered_str ] = entered_string ;
	
		//create ajax handler
		var ajax_handler = new CAjaxHandler ;
		//make request
		ajax_handler.MakeRequest
			( 
					'GET'
				, 	this.url_to_post_to
				, 	this.params_to_send_request_with
				, 	eval
						(
							'r=function(str_result, xml_result) {'
								+ 'fields_to_complete["' + this.id + '"].CallBack(str_result, xml_result);'
							+ '}'
						)
				, true 
			) ;	
	}//CompleteField

	this.CallBack = function( str_result, xml_result ) 
	{
	//alert(  str_result ) ;		
	//alert(  cities.length ) ;
	
		//get cities-objects from xml-response
		this.xml_items = xml_result.getElementsByTagName( 'city' ) ;
		this.subdivs = new Array( this.xml_items.length ) ;


		
		//cur_input_field = input_field ;
		var cur_dropdown_list_id = 'city_field_dropdown_list' ;
		this.cur_dropdown_list =  document.getElementById( cur_dropdown_list_id );
		this.cur_iframe = document.getElementById( cur_dropdown_list_id + '_iframe' )	;
		//clear list	
		delete_all_childs( this.cur_dropdown_list ) ;	
		
		cur_complete_field = this ;
	
		is_enter_enabled = false ;
	//alert( navigator.appName ) ;	


		//bokasmart-hack
		topperdiv = document.createElement( 'div' ) ;
		topperdiv.className = 'topperdiv' ;
		this.cur_dropdown_list.appendChild( topperdiv ) ;
	
		this.cur_dropdown_list.className = 'drop-down-list' ;
		//move needed div
		show_under( this.input_field, this.cur_dropdown_list, 'body' ) ;	
		
		
		if ( 0 == this.xml_items.length )
		{//if we  found nothing
			if( navigator.appName == "Microsoft Internet Explorer" ) 
			{//show iframe under drop-down-list, so we close select-elements, IE6.0 bug
				show_under( this.input_field, this.cur_iframe, 'body' ) ;
				this.cur_iframe.style.height = this.cur_dropdown_list.offsetHeight + 'px' ;
			}
			//alert( 'Nothing' ) ;			
			topperdiv.innerHTML = str_no_cities_found ;			
			//this.HideDropdownList() ;
			return ;
		}		
		
		this.cur_item_index = 0 ;
		for ( var i = 0 ; i < this.xml_items.length ; i++ )
		{
			var html_representation = this.get_html_representation_func( this.xml_items[i] ) ;//.firstChild.data
//alert( str_items[i].firstChild.data ) ;
			var subdiv = document.createElement( 'div' ) ;
			subdiv.innerHTML = html_representation ;
			this.subdivs[i] = subdiv ;
//			txtNode = document.createTextNode( txtRepresentation ) ;
//			subdiv.appendChild( txtNode ) ;
			//subdiv.txtRepresentation = txtRepresentation ;
			if ( 0 == i )
			{//if it's first item
				//make first item selected
				subdiv.className =  'mouse-out' ;
			}
			else
			{
				subdiv.className   = 'mouse-over' ;
			}
			add_event_handler
				( 
					  subdiv
					, 'mouseout'
					, 
						 eval( 'f=function()'
						+ '{'
							+ 'fields_to_complete[ "' + this.id + '" ].SetCurItemNo( undefined ) ; '
							//+ 'this.className = "mouse-over" ;  '
						+ '} ' )
				) ;
			add_event_handler
				( 
					  subdiv
					, 'mouseover'
					, eval( 'f=function()'
						+ '{' 
							+ 'fields_to_complete[ "' + this.id + '" ].SetCurItemNo( ' + i + ' ); \n'
						+ '} \n' 
							)
				) ;
			
			add_event_handler( 
				  subdiv
				, 'click'
				, eval( 'f=function() '
					+ '{'
						+ 'fields_to_complete[ "' + this.id + '" ].SetValueFromItemNo( ' + i + ' ) ;'
						//+ ' cur_input_field.focus() ; '
						+ 'fields_to_complete[ "' + this.id + '" ].HideDropdownList() ;'
						+ 'fields_to_complete[ "' + this.id + '" ].input_field.focus() ;'
					+ '}')
				) ;
	//alert( subdiv.outerHTML ) ;		
			topperdiv.appendChild( subdiv ) ;					
		}
		
		if( navigator.appName == "Microsoft Internet Explorer" ) 
		{//show iframe under drop-down-list, so we close select-elements, IE6.0 bug
			show_under( this.input_field, this.cur_iframe, 'body' ) ;
			this.cur_iframe.style.height = this.cur_dropdown_list.offsetHeight + 'px' ;
		}
		

	}//function CallBack
	
	this.SetUpEventsHandlers = function()
	{
		add_event_handler
			(
					this.input_field
				, 	'keyup'
				, 	eval( 
							'r = function(){'
								+ 'fields_to_complete["' + this.id + '"].CompleteField();' 
							+'}'
						)
			)
			;
	
		add_event_handler
			(
					this.input_field
				, 	'keyup'
				, 	eval
						(
							' r = function(e){ '
								+'fields_to_complete["' + this.id + '"].KeyHandler(e);'
							+ '}'
						)
			) 
			;				
		
		add_event_handler
			(
				  this.input_field
				, 'blur'
				, 
					eval( 
					  'f=function()\n' 
						+ '{\n'
							+ 'if ( fields_to_complete[ "' + this.id + '" ].cur_dropdown_list != undefined )'
							+ '{'
								+ 'if ( undefined == fields_to_complete[ "' + this.id + '" ].cur_item_index )\n'
								+ '{//if no item selected\n'
									+ '//select first item\n'
									+ 'fields_to_complete[ "' + this.id + '" ].cur_item_index = 0 ;\n'
								+ '}\n'
								+ 'fields_to_complete[ "' + this.id + '" ].SetValueFromItemNo( fields_to_complete[ "' + this.id + '" ].cur_item_index ) ; \n'							
							+ '}\n'						
							+ 'fields_to_complete[ "' + this.id + '" ].HideDropdownList(); \n'
						+ '}\n'
					)
			) ;		
	}
	

	this.HideDropdownList = function()
	{
		if ( undefined == this.cur_dropdown_list )
			return;
		//delete_all_childs( document.getElementById( cur_dropdown_list_id ) ) ;
		this.cur_dropdown_list.className = 'drop-down-list-hidden' ;
		this.cur_iframe.style.visibility = 'hidden' ;
		
		this.cur_dropdown_list = undefined ;
		this.cur_iframe        = undefined ;
		
		is_enter_enabled = true ; 
	}//function HideDropdownList

	this.KeyHandler = function( event )
	{

		if ( !event )
			event = window.event ;
		if ( undefined == this.cur_dropdown_list || !event )
		{
			return true;
		}
//alert(this.id);			
//alert( event.keyCode ) ;	
		this.input_field.focus();
		
		switch ( event.keyCode )
		{
			case 34: //pgdn
	//		case 35://end-key
				this.SetCurItemNo( this.xml_items.length-1 ) ;
				break ;
			case 33: //pgup
	//		case 36://home-key
				this.SetCurItemNo( 0 ) ;
				break ;
			case 38://up-key
				var prev_item_no = this.cur_item_index - 1 ;
				if ( prev_item_no < 0 )
					prev_item_no = 0 ;
				this.SetCurItemNo( prev_item_no ) ;
				
				break ;				
			case 40://down-key
				var next_item_index = this.cur_item_index + 1 ;
				if ( next_item_index >= this.xml_items.length )
					next_item_index = this.xml_items.length - 1 ;
				this.SetCurItemNo( next_item_index ) ;				
				break ;
			case 27://esc
				this.HideDropdownList() ;
				break ;
			case 13://enter		
	//alert( cur_record ) ;		
				this.SetValueFromItemNo( this.cur_item_index ) ;
				this.HideDropdownList() ;
				
				
				break; 

			
		}
		
		//alert(1);
		return false ;
	}
	
	this.GetSubDivNo = function( no )
	{
		var subdiv = this.subdivs[no] ;

		return subdiv ;
	}

	this.SetCurItemNo = function( item_no )
	{
//alert( this.cur_item_index + '=>' + item_no ) ;	
		if ( undefined != this.cur_item_index )
		{//if we have some item selected
			//unselect it
			var subdiv = this.GetSubDivNo( this.cur_item_index ) ;
			if  ( undefined != subdiv )
			{
				subdiv.className = 'mouse-over' ;
			}
		}
		
		this.cur_item_index = item_no ;
		if ( undefined != item_no )
		{
			var cur_sub_div = this.GetSubDivNo( item_no ) ;
			if ( undefined != cur_sub_div )
			{
				cur_sub_div.className = 'mouse-out' ;		
			}
		}
	}//function SetCurItemNo

	this.SetValueFromItemNo = function( item_no )
	{
		if ( 
				( undefined != this.xml_items[ item_no ] )
			&& 	( undefined != this.input_field ) 
			)
		{	
			var str_representation = this.get_str_representation_func( this.xml_items[ item_no ] )
			this.input_field.value = str_representation ;
			this.prev_entered_str = str_representation ;
			//this.input_field.focus() ;
		}
	}
	
	this.__construct( input_field_id, url_to_post_to, params_to_send_request_with, request_field_name_entered_str, get_html_representation_func, get_str_representation_func ) ;
}//function CompleteField

function delete_all_childs( field )
{
//alert( 'deleting all childs: ' + field.id);
	field.innerHTML = '' ;
	return ;

	for ( i = 0 ; i < field.childNodes.length ; i++ )
		field.removeChild( field.childNodes[i] ) ;
}

function show_under( item_to_show_under, item_to_be_shown, final_field_id )
{
	var width = item_to_show_under.offsetWidth - 2 ;
	var left = find_offset( item_to_show_under, 'offsetLeft', final_field_id ) ;
	var top  = find_offset( item_to_show_under, 'offsetTop',  final_field_id ) + item_to_show_under.offsetHeight -1 ;
//alert( top ) ;
//alert('showing ' + dropdown_list.id);
//alert( dropdown_list.innerHTML ) ;
	
	item_to_be_shown.style.visibility = 'visible' ;
	item_to_be_shown.style.position = 'absolute' ;
	//dropdown_list.style.zindex='1000' ;
	
	item_to_be_shown.style.width = width + 'px' ;
	item_to_be_shown.style.left  = left + 'px' ;
	item_to_be_shown.style.top   = top  + 'px' ;
//alert( dropdown_list.className ) ;	
}

function find_offset( field, attr, final_field_id )
{
	//init global offset as 0
	var offset = 0 ;
	//while we can find parent-field
	while(
		    field
		&& ( field.id != final_field_id ) //and it's id is not final_id
		)
	{	
		//add it's offset to global-offset
		offset += field[attr] ;
		//make cur-element equalt to it's parent
		field = field.offsetParent ;
	}
	//return result
	return offset ;
}//find_offset


