/**
* Ce fichier fait parti d'un package, toute modification doit entrainer la génération
* d'un nouveau package pour être pris en compte.
* voir l'objet ObjFichierPackage pour connaitre la marche à suivre pour regénérer un package
* @since 20/05/2009 Olivier REYT <reyt@benchmark.fr> 
*/

/**
 * Interface Elements for jQuery
 * Autocompleter
 * 
 * http://interface.eyecon.ro
 * 
 * Copyright (c) 2006 Stefan Petre
 * Dual licensed under the MIT (MIT-LICENSE.txt) 
 * and GPL (GPL-LICENSE.txt) licenses.
 *  
 */
/**
 * Attach AJAX driven autocomplete/sugestion box to text input fields.
 *
 * 
 * 
 * @name Autocomplete
 * @description Attach AJAX driven autocomplete/sugestion box to text input fields.
 * @param Hash hash A hash of parameters
 * @option String source the URL to request
 * @option Integer delay (optional) the delayed time to start the AJAX request
 * @option Boolean autofill (optional) when true the first sugested value fills the input
 * @option Boolean autoriseNouveau (optional) permet de retirer le comportement qui force le dernier element trouvé 
 * @option String helperClass (optional) the CSS class applied to sugestion box
 * @option String selectClass (optional) the CSS class applied to selected/hovered item
 * @option Integer minchars (optional) the number of characters needed before starting AJAX request
 * @option Hash fx (optional) {type:[slide|blind|fade]; duration: integer} the fx type to apply to sugestion box and duration for that fx
 * @option Function onSelect (optional) A function to be executed whenever an item it is selected
 * @option Function onShow (optional) A function to be executed whenever the suggection box is displayed
 * @option Function onHide (optional) A function to be executed whenever the suggection box is hidden
 * @option Function onHighlight (optional) A function to be executed whenever an item it is highlighted
 *
 * @type jQuery
 * @cat Plugins/Interface
 * @author Stefan Petre
 * 
 * Modification benchmark:
 *
 * @since 11/05/2009 Ajout option boolean autoScroll désactivé par défaut, permettant de réactiver l'option qui est donc désactivée désormais
 * permettant de centrer la vue automatiquement sur l'item selectionné. Le comportement est plus naturel ainsi.Une solution plus complete nécéssiterait des dépendances.
 * @since 2008 Damien BENOIT <benoit@benchmark.fr> ajout 
 * @since 1.00 Pierre Chabiland <chabiland@benchmark.fr> modification pour gerer 
 * la selection automatique dans le cas d'un seul resultat renvoye
 * correction de bug, desactivation du cache de base de l'autocompleter qui faisais des resultats byzarres
 * ajout d'un evenement onNoSelect appeler lorsque la saisie en cours ne correspond pas rien.
 * @since 1.00 07/01/2008 Pierre Chabiland <chabiland@benchmark.fr> ajout d'une methode updateNow qui permet de faire 
 * un appel ajax directement afin de bien remplir le champ.
 * @since 1.00 08/01/2008 - A.Nadler <nadler@benchmark.fr> - ajout du parametre autoriseNouveau qui permet de rentrer
 * des element non trouvés en base. Il supprime le comportement qui force le champ lorsque qu'un seul éléement
 * en base correspondait à l'insertion. Exemple je veux rentrer le film "terminator" , on a "terminator II" en base, le 
 * champ était alors systématiquement forcé à "terminator II" empechant l'ajout de "terminator"
 * @since 1.00 11/01/2008 - A.Nadler <nadler@benchmark.fr> - modification de la fonction applyOn elle ajoute
 * l'objet courant en second parametre lorsque qu'elle appelle une fonction. Cela permet à la fonction
 * de connaitre l'élément qui est à l'origine. On peut ainsi avoir des listes de champs utilisant autocomplete
 * qui utilisent la même fonction
 * @since 1.00 08/01/2008 - A.Nadler <nadler@benchmark.fr> - ajout du parametre paramSup qui permet de rajouter
 * un champ dans l'appel ajax 
 */
function is_array( mixed_var ) {
    return ( mixed_var instanceof Array );
}

function afficheProprieteElement(elm){
	var texte = '';
	for (p in elm) {
		texte+= p + " = " + elm[p] + "**";
	}
	alert(texte);
}

jQuery.iAuto = {
	helper : null,
	content : null,
	iframe: null,
	timer : null,
	lastValue: null,
	currentValue: null,
	subject: null,
	selectedItem : null,
	items: null,
	
	empty : function()
	{
		jQuery.iAuto.content.empty();
		if (jQuery.iAuto.iframe) {
			jQuery.iAuto.iframe.hide();
		}
	},

	clear : function()
	{
		jQuery.iAuto.items = null;
		jQuery.iAuto.selectedItem = null;
		jQuery.iAuto.lastValue = jQuery.iAuto.subject.value;
		if(jQuery.iAuto.helper.css('display') == 'block') {
			if (jQuery.iAuto.subject.autoCFG.fx) {
				switch(jQuery.iAuto.subject.autoCFG.fx.type) {
					case 'fade':
						jQuery.iAuto.helper.fadeOut(jQuery.iAuto.subject.autoCFG.fx.duration, jQuery.iAuto.empty);
						break;
					case 'slide':
						jQuery.iAuto.helper.SlideOutUp(jQuery.iAuto.subject.autoCFG.fx.duration, jQuery.iAuto.empty);
						break;
					case 'blind':
						jQuery.iAuto.helper.BlindUp(jQuery.iAuto.subject.autoCFG.fx.duration, jQuery.iAuto.empty);
						break;
				}
			} else {
				jQuery.iAuto.helper.hide();
			}
			if (jQuery.iAuto.subject.autoCFG.onHide)
				jQuery.iAuto.subject.autoCFG.onHide.apply(jQuery.iAuto.subject, [jQuery.iAuto.helper, jQuery.iAuto.iframe]);
		} else {
			jQuery.iAuto.empty();
		}
		
		window.clearTimeout(jQuery.iAuto.timer);
	},

	/**
	 * @param p1: cette methode a l'origine est appelé via un setTimeOut
	 * le premiere parametre renvoie un nombre encore indeterminé
	 * @param asynchrone si mis a faux: passe en asynchrone l'appel ajax
	 *
	 * @since 1.00 07/01/2008 Pierre Chabiland <chabiland@benchmark.fr> ajout des parametres
	 */
	update : function (p1, asynchrone) {
		if (asynchrone==null) asynchrone = true;
		var subject = jQuery.iAuto.subject;
		var subjectValue = jQuery.iAuto.getFieldValues(subject);
		//var selectionStart = jQuery.iAuto.getSelectionStart(subject);

		if (subject && typeof(subject.autoCFG)!='undefined' && typeof(subjectValue.item)!='undefined' && subjectValue.item != jQuery.iAuto.lastValue && subjectValue.item.length >= subject.autoCFG.minchars) {
			jQuery.iAuto.lastValue = subjectValue.item;
			jQuery.iAuto.currentValue = subjectValue.item;
			
			data = { field: jQuery(subject).attr('name')||'field', value: subjectValue.item };
			
			var valuesup = false;
			if (subject.autoCFG.paramSup) {
				
				parametre_sup = subject.autoCFG.paramSup;

				//afficheProprieteElement(parametre_sup);
				
				if (is_array(parametre_sup)) {
					
					for (un_element in parametre_sup) 
					{	
						/**
						* @since 31/10/08 Damien BENOIT <benoit@benchmark.fr> sinon on se prend parfois les fonctions ajoutées par prototype.js et tout plante :
						*/
						if( ! parametre_sup.hasOwnProperty(un_element) ) { continue; }
						
						un_libelle = un_element;
						
						element_jquery = parametre_sup[un_element];
					
						//alert(element_jquery);
						// Elément multiple :  on lie le tout avec un séparateur -
						if (typeof(element_jquery[0])!='undefined') {
							if ((element_jquery[0].tagName=='SELECT') && (element_jquery.attr('multiple')=='multiple')) {
								var liste = '';
			          			   	$("#" + un_element + " option[@selected]").each(
									function() {
										valeur = $(this).val();
										if(liste=='') liste  += valeur;
										else  liste  += ',' + valeur;
									}
								);
								eval('data.' + un_libelle + '= \'' + liste + '\';');
							} else if (typeof(element_jquery)=='object') {
								// Elément simple
								//console.log(un_element + '**' + typeof(element_jquery));
								valeur = element_jquery.val();
								eval('data.' + un_libelle + '= ' + valeur + ';');
							} else {
								eval('data.' + un_libelle + '= ' + element_jquery + ';');
							}
						}
						
						else {
							
							eval('data.' + un_libelle + '= \'' + element_jquery + '\';');
						}
					}
					
				} else  {
					data = {
						field: jQuery(subject).attr('name')||'field',
						value: subjectValue.item ,
						paramsup : parametre_sup.val()
					};
				}
				
			}

			//afficheProprieteElement(data);
			
			jQuery.ajax(
				{
					type: 'POST',
					data: jQuery.param(data),
					async: asynchrone,
					success: function(xml)
					{
						jQuery.iAuto.subject.xml = xml;
						
						subject.autoCFG.lastSuggestion = jQuery('item',xml);
						size = subject.autoCFG.lastSuggestion.size();
						if (size > 0) {
							var toWrite = '';
							subject.autoCFG.lastSuggestion.each(
								function(nr)
								{
									// controle la taille du libelle (50 caracteres maxi)
									var libelle = jQuery('text', this).text();
									if(libelle.length > 50){
										libelle = libelle.substring(0,50) + '...';
									}
									toWrite += '<li rel="' + jQuery('value', this).text() + '" dir="' + nr + '" style="cursor: default;">' + libelle + '</li>';
								}
							);
							if (subject.autoCFG.autofill) {
								var valueToAdd = jQuery('value', subject.autoCFG.lastSuggestion.get(0)).text();
								subject.value = subjectValue.pre + valueToAdd + subject.autoCFG.multipleSeparator + subjectValue.post;
								if(size != 1){
									jQuery.iAuto.selection(
										subject, 
										subjectValue.item.length != valueToAdd.length ? (subjectValue.pre.length + subjectValue.item.length) : valueToAdd.length,
										subjectValue.item.length != valueToAdd.length ? (subjectValue.pre.length + valueToAdd.length) : valueToAdd.length
									);
								}
							}
							else{
								if(size == 1 && !subject.autoCFG.autoriseNouveau){
									var valueToAdd = jQuery('value', subject.autoCFG.lastSuggestion.get(0)).text();
									subject.value = subjectValue.pre + valueToAdd + subject.autoCFG.multipleSeparator + subjectValue.post;
								}
							}
							
							if (size > 0){
								if(size == 1 && !subject.autoCFG.autoriseNouveau){
									// supprime la liste et affiche les donne
									jQuery.iAuto.clear();
									jQuery.iAuto.applyOn(jQuery.iAuto.subject,subject.autoCFG.lastSuggestion.get(0), 'onSelect');
								}
								else{
									// affiche la liste
									jQuery.iAuto.writeItems(subject, toWrite);
								}
							}
							else{
								jQuery.iAuto.applyOn(jQuery.iAuto.subject,null, 'onNoSelect');
								jQuery.iAuto.clear();
							}
						} else {
							jQuery.iAuto.applyOn(jQuery.iAuto.subject,null, 'onNoSelect');
							jQuery.iAuto.clear();
						}
					},
					url : subject.autoCFG.source
				}
			);
		}
	},
	
	writeItems : function(subject, toWrite)
	{
		jQuery.iAuto.content.html(toWrite);
		jQuery.iAuto.items = jQuery('li', jQuery.iAuto.content.get(0));
		jQuery.iAuto.items
			.mouseover(jQuery.iAuto.hoverItem)
			.bind('click', jQuery.iAuto.clickItem);
		var position = jQuery.iUtil.getPosition(subject);
		var size = jQuery.iUtil.getSize(subject);
		jQuery.iAuto.helper
			.css('top', position.y + size.hb + 'px')
			.css('left', position.x +  'px')
			.addClass(subject.autoCFG.helperClass);
		if (jQuery.iAuto.iframe) {
			jQuery.iAuto.iframe
				.css('display', 'block')
				.css('top', position.y + size.hb + 'px')
				.css('left', position.x +  'px')
				.css('width', jQuery.iAuto.helper.css('width'))
				.css('height', jQuery.iAuto.helper.css('height'));
		}
		jQuery.iAuto.selectedItem = 0;
		jQuery.iAuto.items.get(0).className = subject.autoCFG.selectClass;
		jQuery.iAuto.applyOn(subject,subject.autoCFG.lastSuggestion.get(0), 'onHighlight');
		
		if (jQuery.iAuto.helper.css('display') == 'none') {
			if (subject.autoCFG.inputWidth) {
				var borders = jQuery.iUtil.getPadding(subject, true);
				var paddings = jQuery.iUtil.getBorder(subject, true);
				jQuery.iAuto.helper.css('width', subject.offsetWidth - (jQuery.boxModel ? (borders.l + borders.r + paddings.l + paddings.r) : 0 ) + 'px');
			}
			if (subject.autoCFG.fx) {
				switch(subject.autoCFG.fx.type) {
					case 'fade':
						jQuery.iAuto.helper.fadeIn(subject.autoCFG.fx.duration);
						break;
				 	case 'slide':
						jQuery.iAuto.helper.SlideInUp(subject.autoCFG.fx.duration);
						break;
					case 'blind':
						jQuery.iAuto.helper.BlindDown(subject.autoCFG.fx.duration);
						break;
				}
			} else {
				jQuery.iAuto.helper.show();
			}
			
			if (jQuery.iAuto.subject.autoCFG.onShow)
				jQuery.iAuto.subject.autoCFG.onShow.apply(jQuery.iAuto.subject, [jQuery.iAuto.helper, jQuery.iAuto.iframe]);
		}
	},
	
	checkCache : function()
	{
		var subject = this;
		if (subject.autoCFG.lastSuggestion) {
						
			jQuery.iAuto.lastValue = subject.value;
			jQuery.iAuto.currentValue = subject.value;
			
			var toWrite = '';
			subject.autoCFG.lastSuggestion.each(
				function(nr)
				{
					value = jQuery('value', this).text().toLowerCase();
					inputValue = subject.value.toLowerCase();
					if (value.indexOf(inputValue) == 0) {
						toWrite += '<li rel="' + jQuery('value', this).text() + '" dir="' + nr + '" style="cursor: default;">' + jQuery('text', this).text() + '</li>';
					}
				}
			);
			
			if (toWrite != '') {
				jQuery.iAuto.writeItems(subject, toWrite);
				
				this.autoCFG.inCache = true;
				return;
			}
		}
		subject.autoCFG.lastSuggestion = null;
		this.autoCFG.inCache = false;
	},

	selection : function(field, start, end)
	{
		if (field.createTextRange) {
			var selRange = field.createTextRange();
			selRange.collapse(true);
			selRange.moveStart("character", start);
			selRange.moveEnd("character", - end + start);
			selRange.select();
		} else if (field.setSelectionRange) {
			field.setSelectionRange(start, end);
		} else {
			if (field.selectionStart) {
				field.selectionStart = start;
				field.selectionEnd = end;
			}
		}
		field.focus();
	},
	
	getSelectionStart : function(field)
	{
		if (field.selectionStart)
			return field.selectionStart;
		else if(field.createTextRange) {
			var selRange = document.selection.createRange();
			var selRange2 = selRange.duplicate();
			return 0 - selRange2.moveStart('character', -100000);
		}
	},
	
	getFieldValues : function(field)
	{
		if(typeof(field) != 'undefined' && field.value!='') {
			var fieldData = {
				value: field.value,
				pre: '',
				post: '',
				item: ''
			};
			
			if(typeof(field.autoCFG) != 'undefined' && field.autoCFG.multiple) {
				var finishedPre = false;
				var selectionStart = jQuery.iAuto.getSelectionStart(field)||0;
				var chunks = fieldData.value.split(field.autoCFG.multipleSeparator);
				for (var i=0; i<chunks.length; i++) {
					if(
						(fieldData.pre.length + chunks[i].length >= selectionStart
						 || 
						selectionStart == 0)
						 && 
						!finishedPre 
					) {
						if (fieldData.pre.length <= selectionStart)
							fieldData.item = chunks[i];
						else 
							fieldData.post += chunks[i] + (chunks[i] != '' ? field.autoCFG.multipleSeparator : '');
						finishedPre = true;
					} else if (finishedPre){
						fieldData.post += chunks[i] + (chunks[i] != '' ? field.autoCFG.multipleSeparator : '');
					}
					if(!finishedPre) {
						fieldData.pre += chunks[i] + (chunks.length > 1 ? field.autoCFG.multipleSeparator : '');
					}
				}
			} else {
				fieldData.item = fieldData.value;
			}
			return fieldData;
		}
		else {
			return false;
		}
	},
	
	autocomplete : function(e)
	{
		window.clearTimeout(jQuery.iAuto.timer);
		var subject = jQuery.iAuto.getFieldValues(this);
		var pressedKey = e.charCode || e.keyCode || -1;
		if (/13|27|35|36|38|40|^9|09/.test(pressedKey) && jQuery.iAuto.items) {
			if (window.event) {
				window.event.cancelBubble = true;
				window.event.returnValue = false;
			} else {
				e.preventDefault();
				e.stopPropagation();
			}
			if (jQuery.iAuto.selectedItem != null) 
				jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).className = '';
			else
				jQuery.iAuto.selectedItem = -1;
			switch(pressedKey) {
				//enter
				case 9:
				case 13:
					if (jQuery.iAuto.selectedItem == -1)
						jQuery.iAuto.selectedItem = 0;
					var selectedItem = jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0);
					var valueToAdd = selectedItem.getAttribute('rel');
					this.value = subject.pre + valueToAdd + this.autoCFG.multipleSeparator + subject.post;
					jQuery.iAuto.lastValue = subject.item;
					jQuery.iAuto.selection(
						this, 
						subject.pre.length + valueToAdd.length + this.autoCFG.multipleSeparator.length, 
						subject.pre.length + valueToAdd.length + this.autoCFG.multipleSeparator.length
					);
					jQuery.iAuto.clear();
					if (this.autoCFG.onSelect) {
						iteration = parseInt(selectedItem.getAttribute('dir'))||0;
						jQuery.iAuto.applyOn(this,this.autoCFG.lastSuggestion.get(iteration), 'onSelect');
					}
					if(this.autoCFG.autoScroll)
					{
						if (this.scrollIntoView)
						{	
							this.scrollIntoView(false);
						}
					}
					return pressedKey != 13;
					break;
				//escape
				case 27:
					this.value = subject.pre + jQuery.iAuto.lastValue + this.autoCFG.multipleSeparator + subject.post;
					this.autoCFG.lastSuggestion = null;
					jQuery.iAuto.clear();
					if(this.autoCFG.autoScroll)
					{
						if (this.scrollIntoView)
						{
							this.scrollIntoView(false);
						}
					}
					return false;
					break;
				//end
				case 35:
					jQuery.iAuto.selectedItem = jQuery.iAuto.items.size() - 1;
					break;
				//home
				case 36:
					jQuery.iAuto.selectedItem = 0;
					break;
				//up
				case 38:
					jQuery.iAuto.selectedItem --;
					if (jQuery.iAuto.selectedItem < 0)
						jQuery.iAuto.selectedItem = jQuery.iAuto.items.size() - 1;
					break;
				case 40:
					jQuery.iAuto.selectedItem ++;
					if (jQuery.iAuto.selectedItem == jQuery.iAuto.items.size())
						jQuery.iAuto.selectedItem = 0;
					break;
			}
			jQuery.iAuto.applyOn(this,this.autoCFG.lastSuggestion.get(jQuery.iAuto.selectedItem||0), 'onHighlight');
			jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).className = this.autoCFG.selectClass;

			if(this.autoCFG.autoScroll)
			{
				if (jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).scrollIntoView)
				{
					jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).scrollIntoView(true);
				}
			}

			if(this.autoCFG.autofill) {
				var valToAdd = jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).getAttribute('rel');
				this.value = subject.pre + valToAdd + this.autoCFG.multipleSeparator + subject.post;
				if(jQuery.iAuto.lastValue.length != valToAdd.length)
					jQuery.iAuto.selection(
						this, 
						subject.pre.length + jQuery.iAuto.lastValue.length, 
						subject.pre.length + valToAdd.length
					);
			}
			return false;
		}
		
		var force_execution_update = true;
		if(((pressedKey >= 65) && (pressedKey <= 90)) || ((pressedKey >= 97) && (pressedKey <= 122)) || ((pressedKey >= 48) && (pressedKey <= 57)) || (pressedKey == 32) || (pressedKey == 52) || (pressedKey == 54)){
			// si le catactère tapé est un chiffre, une lettre minuscule ou majuscule ou un des catactères suivants :
			// apostrophe (asc.52)
			// espace (asc.32)
			// tiret (asc.54)
			force_execution_update = false;

			// Les touches Control ou Alt sont-elles enfoncées ?
			if(window.event){
				// IE
				if((event.ctrlKey) || (event.altKey)){
					var force_execution_update = true;
				}
			}else{
				// FF
				if((e.ctrlKey) || (e.altKey)){
					var force_execution_update = true;
				}
			}

			
			// La derniere touche enfoncée est-elle la derniere lettre du mot en cours ?
			// (pour éviter un bug quand on fait Ctrl+C (le C est interprété alors qu'en fait, non)
			if(subject.item){
				chaine_en_cours = subject.item;
				longueur = chaine_en_cours.length;
				dernier_caractere = chaine_en_cours.charAt(longueur - 1);
				dernier_caractere_ascii = dernier_caractere.charCodeAt(0);
				
				if(dernier_caractere_ascii != pressedKey){
					// dernier caractere != touche enfoncée
					force_execution_update = true;
				}
			}
		}
		
		// console.log(pressedKey + ' > ' + force_execution_update);
		
		if(typeof(subject.item) != 'undefined' && subject.item.length == 0){
			jQuery.iAuto.lastValue = '';			
		}else{
		}
		
		if ((typeof(subject.item) != 'undefined' && subject.item != jQuery.iAuto.lastValue && subject.item.length >= this.autoCFG.minchars) || (force_execution_update)) {
			jQuery.iAuto.timer = window.setTimeout(jQuery.iAuto.update, this.autoCFG.delay);
		} else {
			jQuery.iAuto.applyOn(this,null, 'onNoSelect');
			if (jQuery.iAuto.items) {
				jQuery.iAuto.clear();	
			}
		}
			
		return true;
	},

	applyOn: function(field, item, type)
	{
		
		if (field.autoCFG[type]) {
			var data = {};
			if(item){
				childs = item.getElementsByTagName('*');
				for(i=0; i<childs.length; i++){
					data[childs[i].tagName] = childs[i].firstChild.nodeValue;
				}
			}
			field.autoCFG[type].apply(field,[data, field]);
		}
	},
	
	hoverItem : function(e)
	{
		if (jQuery.iAuto.items) {
			if (jQuery.iAuto.selectedItem != null) 
				jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).className = '';
			jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).className = '';
			jQuery.iAuto.selectedItem = parseInt(this.getAttribute('dir'))||0;
			jQuery.iAuto.items.get(jQuery.iAuto.selectedItem||0).className = jQuery.iAuto.subject.autoCFG.selectClass;
		}
	},

	clickItem : function(event)
	{	
		window.clearTimeout(jQuery.iAuto.timer);
		
		event = event || jQuery.event.fix( window.event );
		event.preventDefault();
		event.stopPropagation();
		var subject = jQuery.iAuto.getFieldValues(jQuery.iAuto.subject);
		var valueToAdd = this.getAttribute('rel');
		jQuery.iAuto.subject.value = subject.pre + valueToAdd + jQuery.iAuto.subject.autoCFG.multipleSeparator + subject.post;
		jQuery.iAuto.lastValue = this.getAttribute('rel');
		jQuery.iAuto.selection(
			jQuery.iAuto.subject, 
			subject.pre.length + valueToAdd.length + jQuery.iAuto.subject.autoCFG.multipleSeparator.length, 
			subject.pre.length + valueToAdd.length + jQuery.iAuto.subject.autoCFG.multipleSeparator.length
		);
		jQuery.iAuto.clear();
		if (jQuery.iAuto.subject.autoCFG.onSelect) {
			iteration = parseInt(this.getAttribute('dir'))||0;
			jQuery.iAuto.applyOn(jQuery.iAuto.subject,jQuery.iAuto.subject.autoCFG.lastSuggestion.get(iteration), 'onSelect');
		}

		return false;
	},

	protect : function(e)
	{
		pressedKey = e.charCode || e.keyCode || -1;
		if (/^13|27|35|36|38|40/.test(pressedKey) && jQuery.iAuto.items) { // ajout du ^ car lettre "q" vos 113 et ne fonctionnait pas
			if (window.event) {
				window.event.cancelBubble = true;
				window.event.returnValue = false;
			} else {
				e.preventDefault();
				e.stopPropagation();
			}
			return false;
		}
	},

	build : function(options)
	{
		if (!options.source || !jQuery.iUtil) {
			return;
		}

		if (!jQuery.iAuto.helper) {
			if (jQuery.browser.msie) {
				//jQuery('body', document).append('<iframe style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" id="autocompleteIframe" src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
				//jQuery.iAuto.iframe = jQuery('#autocompleteIframe');
			}
			
			/**
			* @since 29/04/09 Damien BENOIT <benoit@benchmark.fr> ie est incapable de faire un append sur un body non prêt :
			* on effectue donc l'ajout du helper au dom ready pour pouvoir faire malgré tout les déclarations d'Autocomplete
			* au plus tôt (module ready)
			*/
			if($.browser.msie)
			{
				$(document).ready(function()
				{
					jQuery('body', document).append('<div id="autocompleteHelper" style="position: absolute; top: 0; left: 0; z-index: 30001; display: none;"><ul style="margin: 0;padding: 0; list-style: none; z-index: 30002;">&nbsp;</ul></div>');
					jQuery.iAuto.helper = jQuery('#autocompleteHelper');
					jQuery.iAuto.content = jQuery('ul', jQuery.iAuto.helper);
				});
			}
			else 
			{
					jQuery('body', document).append('<div id="autocompleteHelper" style="position: absolute; top: 0; left: 0; z-index: 30001; display: none;"><ul style="margin: 0;padding: 0; list-style: none; z-index: 30002;">&nbsp;</ul></div>');
					jQuery.iAuto.helper = jQuery('#autocompleteHelper');
					jQuery.iAuto.content = jQuery('ul', jQuery.iAuto.helper);				
			}
			
		}

		return this.each(
			function()
			{
				
				if (this.tagName != 'INPUT' && this.getAttribute('type') != 'text' )
					return;
				this.autoCFG = {};
				this.autoCFG.source = options.source;
				this.autoCFG.minchars = Math.abs(parseInt(options.minchars)||1);
				this.autoCFG.helperClass = options.helperClass ? options.helperClass : '';
				this.autoCFG.selectClass = options.selectClass ? options.selectClass : '';
				this.autoCFG.onSelect = options.onSelect && options.onSelect.constructor == Function ? options.onSelect : null;
				this.autoCFG.onNoSelect = options.onNoSelect && options.onNoSelect.constructor == Function ? options.onNoSelect : null;
				this.autoCFG.onShow = options.onShow && options.onShow.constructor == Function ? options.onShow : null;
				this.autoCFG.onHide = options.onHide && options.onHide.constructor == Function ? options.onHide : null;
				this.autoCFG.onHighlight = options.onHighlight && options.onHighlight.constructor == Function ? options.onHighlight : null;
				this.autoCFG.inputWidth = options.inputWidth||false;
				this.autoCFG.multiple = options.multiple||false;
				this.autoCFG.multipleSeparator = this.autoCFG.multiple ? (options.multipleSeparator||', '):'';
				this.autoCFG.autofill = options.autofill ? true : false;
				this.autoCFG.autoriseNouveau = options.autoriseNouveau ? true : false;
				this.autoCFG.paramSup = options.paramSup;
				this.autoCFG.autoScroll = options.autoScroll ? true : false;
				
				this.autoCFG.delay = Math.abs(parseInt(options.delay)||1000);
				if (options.fx && options.fx.constructor == Object) {
					if (!options.fx.type || !/fade|slide|blind/.test(options.fx.type)) {
						options.fx.type = 'slide';
					}
					if (options.fx.type == 'slide' && !jQuery.fx.slide)
						return;
					if (options.fx.type == 'blind' && !jQuery.fx.BlindDirection)
						return;

					options.fx.duration = Math.abs(parseInt(options.fx.duration)||400);
					if (options.fx.duration > this.autoCFG.delay) {
						options.fx.duration = this.autoCFG.delay - 100;
					}
					this.autoCFG.fx = options.fx;
				}
				this.autoCFG.lastSuggestion = null;
				this.autoCFG.inCache = false;

				jQuery(this)
					.attr('autocomplete', 'off')
					.focus(
						function()
						{
							jQuery.iAuto.subject = this;
							jQuery.iAuto.lastValue = this.value;
						}
					)
					.keypress(jQuery.iAuto.protect)
					.keyup(jQuery.iAuto.autocomplete)
					.blur(
						function()
						{
							jQuery.iAuto.timer = window.setTimeout(jQuery.iAuto.clear, 200);
						}
					);
			}
		);
	},
	/**
	 * Cette methode permet de faire une mise a jour du champs directement
	 * C'est a dire qu'un appel ajax est realisé selon le contenu du champs texte 
	 * pour mettre a jour le champs. Cette methode est utilise pour faire une derniere verification 
	 * avant l'envois du formulaire. 
	 * @since 1.00 07/01/2008 Pierre Chabiland <chabiland@benchmark.fr>
	 */
	updateNow: function(){
		return this.each(
			function()
			{
				jQuery.iAuto.subject = this;
				jQuery.iAuto.lastValue = null;
				jQuery.iAuto.update(0,false);
			}
		);
	}
	
};
jQuery.fn.Autocomplete = jQuery.iAuto.build;
jQuery.fn.updateNow = jQuery.iAuto.updateNow;
