/*
############################
# creates AutoSuggestion
# needs:
#		input_id			:String
#		data_url			:String
#		key_delay			:int
#		start_key_count		:int
#		max_display_items	:int
#		max_list_items		:int
#		max_request_items	:int
#		request_type		:String (static,dynamic)
#		LangLC				:String
#		hidden_field_name	:String
#		search_case			:String (0=Events; 1=Teams; 2= Player)
#		do_return_action	:String (0=no action; 1= do choose_action)
############################
*/
var AutoSuggestion = Class.create();
	AutoSuggestion.prototype = {
		/*
		############################
		# initialize class
		############################
		*/
		initialize: function(input_id, data_url, key_delay, start_key_count, max_display_items, max_list_items, max_request_items, request_type, LangLC, hidden_field_id, hidden_field_name, search_case, choose_action, do_return_action)
		{
			debugOut('init: '+request_type);
			//varams
			this.input_id			= input_id;
			this.input_element		= $(this.input_id);
			this.class_name			= 'suggest-box';
			this.data_url			= data_url;
			this.key_delay			= key_delay;
			this.start_key_count	= start_key_count;
			this.max_display_items	= max_display_items;
			this.max_list_items		= max_list_items;
			this.max_request_items	= max_request_items;
			this.request_type		= request_type;
			this.LangLC				= LangLC;
			this.hidden_field_id	= hidden_field_id;
			this.hidden_field_name	= hidden_field_name;
			this.search_case		= search_case;
			this.choose_action		= 'window.'+choose_action;
			this.do_return_action	= do_return_action;
			this.do_return_action	= '0';
			
			//variable
			this.over_sugestion_box			= false;
			this.delay_timeout				= false;
			this.box_visibility_status		= true;
			this.last_request_result_count	= false;
			this.last_request_string_count	= false;
			this.last_request_string		= '';
			this.last_filter_result_count	= 0;
			this.search_var					= 'searchStr';
			this.act_scroll_height			= 0;
			this.item_height				= 20;
			this.marked_index				= false;
			this.ready						= false;
			this.marked_item				= false;
			this.sugestion_box				= null;
			this.sugestion_storage_array	= new Array();
			this.sugestion_array			= new Array();
			
			//preparing
			if (this.request_type == 'static')
			{
				//fill sugestion_array
				this.fill_sugestion_storage(this.data_url+'?searchStr=&searchCase='+this.search_case+'&maxRows='+this.max_request_items+'&LangLC='+this.LangLC);
			};
			
			// go on
			this.modify_input();
			this.prepare_sugestion_box();
		},
		
		/*
		############################
		# modifys the input properties
		############################
		*/
		modify_input: function()
		{
			// absolutize input_element
			//this.input_element.absolutize();
			
			//turn autocomplete off
			this.input_element.setAttribute('autocomplete', 'off');
			
			//add key handler
			this.input_element.observe	(
											'keyup',
											function(event)
											{
												if (this.input_element.value != '')
												{
													this.key_handler(event);
												}
											}.bind(this)
										);
			//add click handler
			this.input_element.observe	(
											'click',
											function(event)
											{
												this.process_input(this.input_element.value);
											}.bind(this)
										);
			
			//add blur handler
			this.input_element.observe	(
										 	'blur',
											function(event)
											{
												window.setTimeout	(
																		function()
																		{
																			if (!this.over_sugestion_box)
																			{
																				this.box_visibility('hide');
																			}
																			else
																			{
																				this.input_element.focus();
																			}
																		}.bind(this),
																		100
																	);
											}.bind(this)
										 );
			
		},
		
		/*
		############################
		# prepare_sugestion_box
		############################
		*/
		prepare_sugestion_box: function()
		{
			//create new div layer
			this.sugestion_box = document.createElement('div');
			Element.extend(this.sugestion_box);
			this.sugestion_box.addClassName(this.class_name);


			/*
			this.sugestion_box = new Element	(
													'div', 
													{
														'class'	: this.class_name
													}
												);
			*/
			this.sugestion_box.innerHTML = '';
			
			this.sugestion_box.observe	(
											'mouseover',
											function(event)
											{
												//set as marked
												this.over_sugestion_box = true;
																						
											}.bind(this)
										);
										
			this.sugestion_box.observe	(
											'mouseout',
											function(event)
											{
												//set as marked
												this.over_sugestion_box = false;
																						
											}.bind(this)
										);


			
			// insert suggestion box
			/*
			this.input_element.insert	(
										 	{
												after:this.sugestion_box
											}
										);
			*/
			
			this.input_element.parentNode.insertBefore(this.sugestion_box,this.input_element);
			
			//this.input_element.parentNode.appendChild(this.sugestion_box);
			
			this.input_element.makePositioned();
			
			// create new hidden field
			/*if(!$(this.hidden_field_id))
			{
				this.new_hidden_field = new Element	(
														'input',
														{
															'type'	: 'hidden',
															'id'	: this.hidden_field_id,
															'name'	: this.hidden_field_name
														}
													);
				
				// insert hidden field
				this.input_element.insert	(
											 	{
													after:this.new_hidden_field
												}
											);
			}
			else
			{
			*/
			this.new_hidden_field = $(this.hidden_field_id);
			/*};*/
			
										
			// absolutize suggestion box
			
			
			
			//this.sugestion_box.absolutize();
			this.sugestion_box.makePositioned();
			// positionize @ bottom of imput_element
			//this.sugestion_box.style.top 	= (this.input_element.cumulativeOffset().top + this.input_element.getDimensions().height)+'px';
			//this.sugestion_box.style.left 	= this.sugestion_box.cumulativeOffset().left +'px';
			// hide sugestion_box
			//this.sugestion_box.hide();
			this.box_visibility('hide');
		},
		
		/*
		############################
		# input_delay
		############################
		*/
		input_delay: function(value)
		{
			
			var tempValue = value;
			var ThisClass = this;
			
			window.clearTimeout(this.delay_timeout);
			
			this.delay_timeout = window.setTimeout	(
														function()
														{
															ThisClass.process_input.apply(ThisClass, [tempValue])
														},
														this.key_delay
													)
		},
		
		/*
		############################
		# process_input
		############################
		*/
		process_input: function(input_data)
		{
			
			this.marked_item = false;
			if (
					(input_data == '')
				)
			{
				if (this.marked_item)
				{
					this.marked_item = false;
					this.marked_index = false;
				}
				this.new_hidden_field.value = '';
				this.box_visibility('hide');
			}
			else
			{
				if (
						(this.ready)
						||
						(this.request_type = 'dynamic')
					)
				{
					this.new_hidden_field.value = '';
					
					//reset marked item
					if (this.marked_item)
					{
						this.un_mark_item(this.marked_item);
						this.marked_item = false;
						this.marked_index = false;
					}
					
					//process input
					if (
							(this.request_type == 'static')
							&&
							(input_data.length >= this.start_key_count)
						)
					{	
					// ############################################################################################################################################
					// # start client side filtering
					// ############################################################################################################################################
						this.sugestion_array = this.filter_data('static',input_data);
						this.fill_sugestioin_box();
						
					// ############################################################################################################################################
					// # end client side filtering
					// ############################################################################################################################################
					}
					else if (
								(this.request_type == 'dynamic')
								&&
							 	(input_data.length >= this.start_key_count)
							)
					{
					// ############################################################################################################################################
					// # start server side filtering
					// ############################################################################################################################################
						
						debugOut('last result count: '+this.last_request_result_count);
						if 	(
								(this.last_request_result_count == false)
								||
								(this.dyna_request_check(this.input_element.value))
							)
						{
							
							var tempFunc = function(temp_data)
								{
									this.last_request_result_count 	= temp_data.FibaSearch.length;
									this.last_request_string_length = this.input_element.value.length;
									this.last_request_string		= this.input_element.value;
									
									this.sugestion_storage_array = temp_data;
									this.sugestion_array = this.filter_data('dynamic',this.input_element.value);
									this.fill_sugestioin_box();
									
								}.bind(this);
							
							tempSearchUrl = this.data_url+'?searchStr='+input_data+'&searchCase='+this.search_case+'&maxRows='+this.max_request_items+'&LangLC='+this.LangLC;
							this.load_data(tempSearchUrl, tempFunc)
							
						}
						else
						{
							// just filter what is already in array
							this.sugestion_array = this.filter_data('dynamic',this.input_element.value);
							this.fill_sugestioin_box();
						}
					// ############################################################################################################################################
					// # stop server side filtering
					// ############################################################################################################################################
					}
					else
					{
						this.sugestion_array = new Array();
					};
					
					if (this.sugestion_array.length > 0)
					{
						this.box_visibility('show');
					}
					else
					{
						this.box_visibility('hide');
					};
				};
			};
		},
		
		/*
		############################
		# dyna_request_check
		############################
		*/
		dyna_request_check: function(new_request_str)
		{
			var return_value = false;
			
			
			if 	(
					(new_request_str.length > this.last_request_string.length)
					&&
					(new_request_str.indexOf(this.last_request_string) > -1)
				)
			{
				debugOut('Condition 1 & 2 erfüllt');
				debugOut('Condition 3 & 4');
				debugOut(this.last_request_result_count +' == '+this.max_request_items);
				debugOut(this.last_filter_result_count +' < '+this.max_list_items);

				
				if 	(
						(this.last_request_result_count == this.max_request_items)
						&&
						(this.last_filter_result_count < this.max_list_items)
					)
				{
					debugOut('Condition 3 & 4 erfüllt');
					return_value = true;
				}
				else
				{
					debugOut('Condition 3 & 4 nicht erfüllt');
					return_value = false;
				}
			}
			else
			{
				debugOut('Condition 1 & 2 nicht erfüllt');
				return_value = true;
			}
			
			return return_value;
		},
		
		/*
		############################
		# fill_sugestioin_box
		############################
		*/
		fill_sugestioin_box: function()
		{
			
			// empty sugestion box
			this.sugestion_box.innerHTML = '';
			
			//fill sugestioin box
			var temp_counter = 0;
			
			if (this.sugestion_array.length > 0)
			{
				this.sugestion_array.each	(
										  		function(item_)
												{
													
													if (temp_counter <= this.max_list_items)
													{
													
														// rendering items
														temp_list_item = this.build_display_item({
															'name': item_.official_name,
															'sID': item_.sID
														});
														if (temp_counter == 0) {
															temp_list_item.addClassName('first');
														};
														
														//insert in sugestion box
														this.sugestion_box.appendChild(temp_list_item);
														
														/*												
														this.sugestion_box.insert	(
																						{
																						bottom:temp_list_item
																						}
																					);
														*/
													}
																				
													temp_counter = temp_counter + 1;	
																			
												}.bind(this)
											)
			};
			
			this.change_suggestion_box_height();
		},
		
		/*
		############################
		# filter_data
		############################
		*/
		filter_data: function(type, input_data)
		{
			
			var temp_Array = new Array();
			
			this.sugestion_storage_array.FibaSearch.each	(
															 	function(item_, index)
																{
																	
																	if (
																			(item_.alias.toLowerCase().indexOf(input_data.toLowerCase()) != -1)
																			||
																			(item_.official_name.toLowerCase().indexOf(input_data.toLowerCase()) != -1)
																		)
																	{
																		temp_Array.push(item_);
																	}
																	
																}.bind(this)
															);
															
			//console.log(temp_Array.length);
			
			this.last_filter_result_count = temp_Array.length;
			
			if (this.last_filter_result_count == 0)
			{
				this.box_visibility('hide');
			};
			
			return  temp_Array;
			
		},
		
		/*
		############################
		# fill_sugestion_storage
		############################
		*/
		fill_sugestion_storage: function(data_url)
		{
			var tempFunc = function(temp_data)
			{
				this.sugestion_storage_array = temp_data;
			}.bind(this);
			this.load_data(data_url, tempFunc)
		},
		
		/*
		############################
		# load_data
		############################
		*/
		load_data: function(data_url, tempFunc)
		{

			new Ajax.Request	(
							 		data_url,
									{
										method		: 'get',
										onSuccess	: function(transport)
										{
											var json = transport.responseText.evalJSON(true);
											debugOut(json);
											tempFunc(json);
											this.ready = true;
										}.bind(this)
									}
								);
		},
		
		/*
		############################
		# highlight_match
		#	adds one string in front and one at the end of an match, used e.g.: to highlight a match by adding some HTML code in front (<span class="highlite">) and some (</span>) after the match
		############################
		*/
		highlight_match: function(str,strToHighlight,strHlCodePrefix,strHlCodeSuffix)
		{
			var tempRegExp = new RegExp(
										strToHighlight.replace(/([\^\$\\\.\+\*\?\{\}\(\)\|\[\]])/g,'\\$1')
										,'i');
			var tempMatch = tempRegExp.exec(str);
			if (tempMatch == null) {
				return str;
			} else {
				return str.substr(0,tempMatch.index) + strHlCodePrefix + str.substr(tempMatch.index,strToHighlight.length) + strHlCodeSuffix + str.substr(tempMatch.index+strToHighlight.length,str.length);
			};
		},

		/*
		############################
		# build_display_item
		############################
		*/
		build_display_item: function(config)
		{
			//create new div item
			var tempItem;
			
			tempItem = document.createElement('div');
			Element.extend(tempItem);
			tempItem.addClassName(this.input_id+'-list-item item');
			tempItem.setAttribute("sID", config.sID);
			tempItem.setAttribute("value", config.name);

			/*
			var tempItem =  new Element		(
												'div', 
												{
													'class'	: this.input_id+'-list-item item',
													'sID'	: config.sID,
													'value'	: config.name
												}
											);
			*/
			
			//tempItem.setOpacity(0.8);
			
			var tempStr = this.input_element.value;
			
			
			//globalStrReplace -> Fiba common functions needed
			//var tempText = globalStrReplace(config.name,tempStr,'<span class="highlite">'+tempStr+'</span>','i');
			var tempText = this.highlight_match(config.name,tempStr,'<span class="highlite">','</span>');
			
			tempItem.innerHTML = tempText;
			
			//highlite item
			tempItem.observe	(
									'mouseover',
									function(event)
									{
										//set as marked
										this.mark_item(tempItem);
																				
									}.bind(this)
								);
			//click
			tempItem.observe	(
									'click',
									function(event)
									{
										this.input_element.value = config.name;
										this.new_hidden_field.value = config.sID;
										this.box_visibility('hide');
										if (this.choose_action != '')
										{
											eval(this.choose_action);
										}
									}.bind(this)
								);
			
			
			return tempItem;
		},
		
		/*
		############################
		# box_visibility
		############################
		*/
		box_visibility: function(type)
		{
			//var curent_type = this.sugestion_box.getStyle('display');
			if	(
				 	(type == 'show' )
					&&
					(!this.box_visibility_status)
				)
			{
				this.sugestion_box.setStyle	(
												{
													display: 'block'
												}
											);
				this.box_visibility_status = true;
			}
			else if	(
					 	(type == 'hide')
						&&
						(this.box_visibility_status)
					)
			{
				this.sugestion_box.setStyle	(
												{ 
													display: 'none'
												}
											);
				this.box_visibility_status = false;
			};
		},

		/*
		############################
		# key_handler
		############################
		*/
		key_handler: function(e)
		{
			var element = Event.element(e);
			
			switch (e.keyCode)
			{
				case	Event.KEY_UP:
							this.move_selection('up');
							Event.stop(e);
						break;
 
				case 	Event.KEY_DOWN:
							this.move_selection('down');
							Event.stop(e);
						break;
						
				case	Event.KEY_RETURN:
							this.take_selection();
							Event.stop(e);
						break;
						
				case	Event.KEY_LEFT:
							Event.stop(e);
						break;
				
				case	Event.KEY_RIGHT:
							Event.stop(e);
						break;
				
				default:
						this.input_delay(this.input_element.value);
			}
			
		},
		
		/*
		############################
		# move_selection
		############################
		*/
		move_selection: function(type)
		{
			
			if (this.last_filter_result_count > 0) {
			
				var items_ = $$('div.' + this.input_id + '-list-item');
				
				if (type == 'up') {
					//debugOut('up');
					if (this.get_marked_item()) {
						if (this.get_marked_item().previous()) {
							var temp_un_mark = this.get_marked_item();
							var temp_mark = this.get_marked_item().previous();
							this.mark_item(temp_mark);
						//this.un_mark_item(temp_un_mark);
						}
					}
				}
				else 
					if (type == 'down') {
						//debugOut('down');
						if (this.get_marked_item()) {
							if (this.get_marked_item().next()) {
								var temp_un_mark = this.get_marked_item();
								var temp_mark = this.get_marked_item().next();
								this.mark_item(temp_mark);
							//this.un_mark_item(temp_un_mark);
							}
						}
						else {
						
							this.mark_item(this.get_first_item());
							
						};
				};
			};
		},

		/*
		############################
		# get_first_item
		############################
		*/
		get_first_item: function()
		{
			var item_ = $$('div.'+this.input_id+'-list-item')[0];
			if (item_ )
			{
				return item_;
			}
			else
			{
				return false;
			}
		},

		/*
		############################
		# get_marked_item
		############################
		*/
		get_marked_item: function()
		{
			var temp_selected_item = false;
			var items_ = $$('div.'+this.input_id+'-list-item');
						
			temp_selected_item = this.marked_item;
			
			if (temp_selected_item)
			{
				return temp_selected_item;
			}
			else
			{
				return false;
			}
			
		},
		
		/*
		############################
		# mark_item
		############################
		*/
		mark_item: function(item_)
		{
			var this_item = item_;
			
			if (this.marked_item)
			{
				this.un_mark_item(this.marked_item);
			}
			
			this_item.addClassName('selected');
			
			this.marked_item = this_item;
			
			//set marked_index
			
			this.marked_index = this.get_marked_index();
			
			var ThisClass = this;
			
			var correct_scroll = window.setTimeout	(
											function()
											{
												ThisClass.correct_scroll_position.apply(ThisClass)
											},
											50
										)

			
			
			//this.correct_scroll_position();
						
			return this_item;
		},
		
		/*
		############################
		# get_marked_index
		############################
		*/
		get_marked_index: function()
		{
			var items_ = $$('div.'+this.input_id+'-list-item');
			var index 	= false;
			
			if (items_.length > 0)
			{
				var counter = 0
				while (!index && items_.length > counter)
				{
					if (items_[counter].hasClassName('selected'))
					{
						index = counter;
					}
					counter++;
				}
			}
			
			return index;
			
		},

		/*
		############################
		# correct_scroll_position
		############################
		*/
		correct_scroll_position: function()
		{	
			var new_scroll_height = -1;
		
			//debugOut('act scroll top:'+this.new_scroll_height);
			//debugOut('new scroll top:'+((this.marked_index - this.max_display_items + 1) * this.item_height));
			//debugOut('limit hight:'+this.item_height * this.max_display_items);
			
			var item_pos_over_all = this.marked_index * this.item_height;
			var min_item_pos = this.act_scroll_height;
			var max_item_pos = this.act_scroll_height + (this.max_display_items * this.item_height) - this.item_height;

			if (item_pos_over_all > max_item_pos)
			{
				new_scroll_height = item_pos_over_all - (this.max_display_items * this.item_height) + this.item_height;
			};
			
			if (min_item_pos > item_pos_over_all)
			{
				new_scroll_height = item_pos_over_all;
			};
			
			if (new_scroll_height != -1)
			{
				this.act_scroll_height = new_scroll_height;
				
				this.sugestion_box.scrollTop = this.act_scroll_height;
			}
			
		},
			
		/*
		############################
		# un_mark_item
		############################
		*/
		un_mark_item: function(item_)
		{
			var this_item = item_;
			this_item.removeClassName('selected');
			return this_item;
		},
		
		/*
		############################
		# take_selection
		############################
		*/
		take_selection: function()
		{
			if (this.marked_item)
			{
				if(this.get_marked_item())
				{
					this.new_hidden_field.value	= this.get_marked_item().getAttribute('sid');
					this.input_element.value 	= this.get_marked_item().getAttribute('value').replace(/&amp;/g,'&');
					this.box_visibility('hide');
					
					if 	(
							(this.choose_action != '')
							&&
							(this.do_return_action == '1')
						)
					{
						eval(this.choose_action);
					}
					
				}
			}
		},
		
		/*
		############################
		# change_suggestion_box_height
		############################
		*/
		change_suggestion_box_height: function()
		{
			if (this.sugestion_array.length > 0)
			{
				// count items
				var items_ = $$('div.'+this.input_id+'-list-item');
				var Box_height = items_[0].getHeight();
				
				if (items_.length >= this.max_display_items)
				{
					Box_height = this.item_height*this.max_display_items;
				}
				else
				{
					Box_height = (items_.length)*this.item_height;
				}
				this.sugestion_box.setStyle	(
												{
													height: Box_height+'px'
												}
											);
				this.box_visibility('show');
				
			}
			else
			{
				this.box_visibility('hide');
			}
		},

		/*
		############################
		# enter
		############################
		*/
		enter: function()
		{
			
			if (this.input_element.value != '')
			{
				this.take_selection();
			}
		}
	};
//);
