jQuery.autocomplete = function(id, value_name, data_source, minlength) {
		
		var text_field = $('#'+id);
		var results_box = false;
		var value_field = false;
		
		var value_name = value_name;
		
		var data_source = data_source;
		var data_cache = new Array();
		
		var delay = 600;
		var timeout = null;
		var disapear = null;
		var minlength = (!minlength) ? 2 : minlength;
				
		text_field.attr('autocomplete', 'off');
		
		text_field.keyup(function(e) {
		
			// On ignore MAJ, enter, delete
			if(e.keyCode > 8 && e.keyCode <= 32) { 				
				return false;
			}
			
			clearTimeout(timeout);
			timeout = setTimeout(loadData, delay);
		});				
		
		function loadData() {
			
			var keywords = text_field.val().length > minlength ? encodeURIComponent(text_field.val()) : false;
			var query_url = data_source+keywords;
				
			var cache_exists = typeof data_cache[keywords] == 'object';
		
			if(keywords && !cache_exists) {
			
				$.ajax({
					type: "GET",
   					url: query_url, 
					dataType: 'json',
					beforeSend: function(){
						//debug('Chargement en cours');
     					data_cache[keywords] = {};
						text_field.addClass('loading');
   					},
   					success: function(data){
						data_cache[keywords] = data;      				
						displayResults(data);
						text_field.removeClass('loading');
      					//debug('Terminé');
      				}
        		});
        	}
     			
			else if(cache_exists) {
				displayResults(data_cache[keywords]);
				//debug('Résultats en cache');			
			}
			
			else {
				displayResults(false);
				//debug('Keywords trop court');		
			}	
		}
		
		function displayResults(data) {
	
			if(results_box) results_box.remove();
			
			if(value_field) value_field.remove();
			
			if(!data) return false;
			
			var d = new Date();
			var t = d.getTime();
			
			// On créé le ul pour accueillir les resultats
			$('body').append('<ul class="ac_results" id="ac_results_'+t+'"></ul>');	
			results_box = $('#ac_results_'+t);
			
			// Si IE
			if(!!(window.attachEvent && navigator.userAgent.indexOf('Opera') === -1)) {
				$('.select').css({visibility: 'hidden'});
			}
			
			var position = text_field.offset();		
			results_box.css({'position':'absolute', 'top':position.top+text_field.outerHeight()+'px', 'left': position.left+'px', 'width':text_field.outerWidth()-2});
					
			// On verifie le nombre d'éléments trouvés
			if(data.length == 0) {
				$("<li/>").attr("id", 'city_0').text('Pas de résultats').appendTo(results_box);
				
				clearTimeout(disapear);
				disapear = setTimeout(function() { 
					results_box.remove(); 
					value_field.remove();
				}, 1200);
				
			}
			else if(data.length >= 1) {
				// On ajoute les resulats à l'interieur
				$.each(data, function(i,item) {
				
					var item_value = item.id;
					var item_text = item.text;
					$("<li/>").attr("id", (item_value ? 'city_'+item_value : '')).attr("class", (i%2==0 ? 'zebra1' : 'zebra2')).attr("title", item_text).text(item_text).appendTo(results_box);
				});	
				
				// On ajoute les dernier élément "N'est pas dans la liste"
				$("<li/>").text('N\'existe pas dans la liste').addClass('quit').appendTo(results_box);
				
				results_box.children().mouseover(function(){$(this).addClass('hover');});
				results_box.children().mouseout(function(){$(this).removeClass('hover');});
				results_box.children().click(selectItem);
			}	
		}
		
		function selectItem() {
			// On crée le champ caché pour y stocké l'id
			if(this.id) {
				var item_id = this.id.split('_')[1];
				var item_lib = $(this).text();
				text_field.next('.ac_value').remove();
				text_field.after('<input class="ac_value" type="hidden" name="'+value_name+'" value="'+item_id+'" />');
				value_field = text_field.next('.ac_value');
				text_field.val(item_lib);
			}
			results_box.remove();
			
			
			try {
				selectItemCallback(item_id);
			}
			catch(e) {}
		} 
	}
