/**
*    Json key/value autocomplete for jQuery 
*    Provides a transparent way to have key/value autocomplete
*    Copyright (C) 2008 Ziadin Givan www.CodeAssembly.com  
*
*    This program is free software: you can redistribute it and/or modify
*    it under the terms of the GNU Lesser General Public License as published by
*    the Free Software Foundation, either version 3 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU Lesser General Public License
*    along with this program.  If not, see http://www.gnu.org/licenses/
*     
*    Examples 
*	 $("input#example").autocomplete("autocomplete.php");//using default parameters
*	 $("input#example").autocomplete("autocomplete.php",{minChars:3,timeout:3000,validSelection:false,parameters:{'myparam':'myvalue'},before : function(input,text) {},after : function(input,text) {}});
*    minChars = Minimum characters the input must have for the ajax request to be made
*	 timeOut = Number of miliseconds passed after user entered text to make the ajax request   
*    validSelection = If set to true then will invalidate (set to empty) the value field if the text is not selected (or modified) from the list of items.
*    parameters = Custom parameters to be passed
*    after, before = a function that will be caled before/after the ajax request
*/
jQuery.fn.auto = function(url, settings ) 
{
	return this.each( function()//do it for each matched element
	{
		//this is the original input
		var textInput = $(this);
		
		

		settings = jQuery.extend(//provide default settings
		{
			minChars : 1,
			timeout: 1000,
			after : null,
			before : null,
			validSelection : true,
			parameters : {},
			street:'',
			acceptName:''
		} , settings);

		//create a new hidden input that will be used for holding the return value when posting the form, then swap names with the original input
		textInput.after('<input autocomplete="off" type="hidden" id="' + textInput.attr("name") + '_id" name="' + textInput.attr("name")  + '_text"/>');
		
		var valueInput = $(this).next();
		valueInput.after('<input autocomplete="off" type="hidden" value="0" id="' + settings.acceptName + '_id" name="' + settings.acceptName  + '"/>');
		var acceptInput = valueInput.next();
		
		textInput.bind('blur', function(){
//			if(acceptInput.val()==1){
//				$('#' + settings.acceptNo).hide();
//				$('#' + settings.acceptYes).show();
//                                $('#submit_button').show();
//
//			}else if(textInput.val()!=''){
//				$('#' + settings.acceptYes).hide();
//				$('#' + settings.acceptNo).show();
//                                $('#submit_button').hide();
//			}
		});
		//create the ul that will hold the text and values
		valueInput.after('<ul class="autocomplete"></ul>');

		var list = valueInput.next();
		var typingTimeout;
		var size = 0;
		var selected = -1;

                

		function getData(text)
		{
			window.clearInterval(typingTimeout);
			if ($('#request_street').val()!='' && (settings.minChars != null && text.length >= settings.minChars)){
				
				clear();
				if (settings.before) {
					settings.before(textInput,text);
				}
				settings.parameters.text = text;
				var streetId = '&street=';
				streetId += $('#' + settings.street).val();
				$.getJSON(url + streetId,settings.parameters,function(data)
				{
					var items = '';
					if (data && data.length>0){
						textInput.removeClass('fail');
						size = data.length;
						for (i = 0; i < data.length; i++)//iterate over all options
						{
							var acceptKey = '';
						  for ( key in data[i] )//get key => value
						  {	
							  if(key!='accept'){
								  acceptKey = key;
							  }else{
								  items += '<li accept="' + data[i][key] + '" value="' + acceptKey + '">' + data[i][acceptKey].replace(new RegExp("(" + text + ")","i"),"<strong>$1</strong>") + '</li>';
							  }
						  }
						  if(items){
							  list.html(items);
							  //on mouse hover over elements set selected class and on click set the selected value and close list
							  list.show().children().
							  hover(function() { 
								  $(this).addClass("selected").siblings().removeClass("selected");
							  }, function() { 
								  $(this).removeClass("selected") 
							  }).
							  click(function () {
								valueInput.val( $(this).attr('value') );
								acceptInput.val( $(this).attr('accept') );
								textInput.val($(this).text());
								clear();
//								checkHouse();
							  });
						  }
						}
						
					}else{
						textInput.addClass('fail');
					}
					if (settings.after){
						settings.after(textInput,text);
					}
				});
				
				oldText = text;
			}
		}
		
		function clear(){
			list.hide();
			size = 0;
			selected = -1;
		}	
		
		textInput.keydown(function(e) 
		{
			window.clearInterval(typingTimeout);
			if(e.which == 27)//escape
			{
				clear();
			} else if (e.which == 46 || e.which == 8)//delete and backspace
			{
				clear();
				//invalidate previous selection
				if (settings.validSelection) valueInput.val('');
			}
			else if(e.which == 13)//enter 
			{ 
				if ( list.css("display") == "none")//if the list is not visible then make a new request, otherwise hide the list
				{ 
					getData(textInput.val());
				} else
				{
					clear();
				}
				textInput.select();
				
				e.preventDefault();
				return false;
			}
			else if(e.which == 40  || e.which == 38)//move up, down 
			{
				size = list.children('li').length;
				
			  switch(e.which) 
			  {
				case 40: 
				  selected = selected >= size - 1 ? 0 : selected + 1; break;
				case 38:
				  selected = selected <= 0 ? size - 1 : selected - 1; break;
				default: break;
			  }
			  //set selected item and input values
			  textInput.val( list.children().removeClass('selected').eq(selected).addClass('selected').text() );	        
			  valueInput.val( list.children().eq(selected).attr('value') );
			  if(selected<0)
				  acceptInput.val(0);
			  else
				  acceptInput.val(list.children().eq(selected).attr('accept'));
			}else if(e.which == 9){
				//list.hide();
			}else{ 
				//invalidate previous selection
				if (settings.validSelection) valueInput.val('');
				typingTimeout = window.setTimeout(function() {
					acceptInput.val(0);
					getData(textInput.val()) 
				},settings.timeout);
			}
		});
	});
};

