
var Autocomplete = new Class({
	/***********************************************************************************
	/ Autocomplete Class Made with mootools
	/ Author : Frédéric George for Tentwelve
	/ Parameters :
	/	- field (string) : id of the field to autocomplete
	/	- autocomplete (string) : id of the div where the autocomplete result must be shown
	/	- ajax_script (string) : path to the script for the ajax request
	/	- params (Object) : Javascript object containing other parameters
	/		- parameter (String) : name of the parameter sent with the ajax request
	/		- method (String) : Method ('get' or 'post') used with the ajax request
	/ 		- afterUpdate (function) : function to execute after the autocomplete has filled the field
	/		- mandatory (boolean) : makes the selection of an element in the list mandatory
	/		- parameters (String) : other parameters to send to the ajax request
	/**********************************************************************************/
	initialize : function(field, autocomplete, ajax_script, params){
		// Where to place the global events
			// with Microsoft Internet Explorer
		if (window.ie){
			this.global = $$('body');
			// with other browsers
		}else{
			this.global = window;
		}
		// Init variables
		this.keyboradmode = false;
		this.hideOnBlur = true;
		this.tohide = false;
			// field
		this.field = $(field);
			// autocomplete div
		this.autocomplete = $(autocomplete);
			// autocomplete name
		this.acname = this.autocomplete.getProperty('id');
			//ajax script name
		this.ajax_script = ajax_script;
		//parameters
		this.params = params;
			// parameter sent to ajax name
		if (! params.parameter){
			this.paramname = 'content';
		}else{
			this.paramname = this.params.parameter;
		}
			// ajax parameter sending method
		if (! params.method){
			this.method = 'get';
		}else{
			this.method = 'post';
		}
			// mandatory
		this.mandatory = params.mandatory;
		
		// Get field width to change the autocomplete div width
		var fieldwidth = this.field.getStyle('width');
		if (window.ie || window.webkit){
			this.autocomplete.setStyle('width', (parseInt(fieldwidth))+'px');
			if (window.ie){
				this.autocomplete.setStyle('top', '-2px');
			}
		}else{
			this.autocomplete.setStyle('width', fieldwidth);
		}
		
		// Hide the autocomplete div
		this.autocomplete.setStyle('visibility', 'hidden');
		
		// Copy this in an object to access it from other levels
		var obj = this;
		
		// Event when something is typed in the field
		obj.field.addEvent('keyup', function(event){
			var event = new Event(event);
			// Not if the key pressed is 'up', 'down' or 'enter'
			if (event.key != 'down' && event.key != 'up' && event.key != 'enter'){
				//get the field content
				var content = $(field).getProperty('value');
				if (content != ""){
					// Todo when ajax query is completed
					var completed = function(){
						// run function addevents
						obj.addevents(obj);
						// Selects the first element if selection mandatory
						if (obj.mandatory){
							obj.selectfirst();
						}
					};
					// Make Ajax query
					var myAjax = new Request.HTML({url : obj.ajax_script, method: obj.method, update: obj.autocomplete, onComplete : completed ,data: obj.paramname+'='+content+'&'+obj.params.parameters}).send();
					// Show autocomplete div
					// Get field position to change the autocomplete div position
					var position = obj.field.getLeft();
					obj.autocomplete.setStyle('left', position+'px');
					obj.autocomplete.setStyle('visibility', 'visible');
				}else{
					// Empty and hide autocomplete div
					obj.autocomplete.empty();
					obj.autocomplete.setStyle('visibility', 'hidden');
				}
			}
		});
		
		// Event when field looses the focus
		obj.field.addEvent('blur', function(){
			if (obj.hideOnBlur){
				obj.autocomplete.setStyle('visibility', 'hidden');
			}else{
				obj.hideOnBlur = true;
			}
		});
		
		// Event when a key is pressed
		obj.field.addEvent('keydown', function(event){
			if (obj.autocomplete.innerHTML != ""){
				var event = new Event(event);
				// If key is 'up' or 'down'
				if (event.key == 'down' || event.key == 'up'){
					obj.tohide = false;
					$clear(obj.hideAutocomplete);
					// If not in keyboard mode
					if ( ! obj.keyboardmode){
						// If no element is selected in the list
						var elm = $('current');
						if ( ! elm){
							// Select the first element
							obj.selectfirst();
							obj.keybactive = false;
						}
						// Turn on the keyboard mode
						obj.keyboardmode = true;
					}
				}
				// If key is enter
				if (event.key == 'enter'){
					// If an element is selected in the list
					var elm = $('current');
					if (elm){
						obj.hideOnBlur = false;
						obj.keyboardmode = false;
						// blur the field (to avoid the form to submit)
						obj.field.blur();
						elm.setProperty('id', obj.oldId);
						// Complete the field
						obj.complete(elm);
						obj.hideOnBlur = true;
						// Add a global event to set the focus back to the field when it's completed
						obj.global.addEvent('keyup', function(event){
							var event = new Event(event);
							if (event.key == 'enter'){
								obj.field.focus();
								obj.global.removeEvents('keyup');
							}
						});
					}
				}
			}
		});
		
		// Events when a key is released
		obj.field.addEvent('keyup', function(event){
			var event = new Event(event);
			// if keyboard mode is set and active
			if (obj.keyboardmode && obj.keybactive){
				// If key is 'up'
				if (event.key == 'up'){
					var element = $('current').getPrevious();
					// Unselect if select not mandatory
					if ( ! obj.mandatory){
						
					}
					// If there is an element before
					if (element){
						// Select the previous element
						$('current').removeProperty('class');
						$('current').setProperty('id', obj.oldId);
						obj.oldId = element.getProperty('id');
						element.setProperty('class', 'selected');
						element.setProperty('id', 'current');
					// If the first element is selected
					}else{
						// disable keyboard mode if select not mandatory
						if (! obj.mandatory){
							try{
								$('current').removeProperty('class');
								$('current').setProperty('id', obj.oldId);
							}catch(e){};
							obj.keyboardmode = false;
							obj.hideselect();
						}
						// else, do nothing
					}
				}
				
				// If key is 'down'
				if (event.key == 'down'){
					var element = $('current').getNext();
					// If there is an element after
					if (element){
						// Select the next element
						$('current').removeProperty('class');
						$('current').setProperty('id', obj.oldId);
						obj.oldId = element.getProperty('id');
						element.setProperty('class', 'selected');
						element.setProperty('id', 'current');
					}
				}
				
			}else{
				// If keyboard mode inactive
				if ( ! obj.keybactive){
					// activate
					obj.keybactive = true;
				}
			}
		});
	},
	
	// Function selectfirst : selects the first element of the list
	selectfirst : function(){
		var obj = this;
		try{
			var element = $$('#'+obj.acname+' ul').getFirst();
			obj.oldId = element.getProperty('id');
			element.setProperty('class', 'selected');
			element.setProperty('id', 'current');
		}catch(e){};
	},
	
	// Function addevents : add the mouse events on the list elements
	addevents : function(obj){
		// Events for the autocomplete div
		obj.autocomplete.addEvent('mouseout', function(){
			obj.hideOnBlur = true;
			//obj.field.focus();
			if ( ! obj.mandatory){
				obj.hideselect();
			}
		});
		obj.autocomplete.addEvent('mouseover', function(){
			obj.keyboardmode = false;
			obj.tohide = false;
			obj.hideOnBlur = false;
			$clear(obj.hideAutocomplete);
		});
		
		// Events for each element
			// mouseover
		$$('#'+obj.acname+' li').addEvent('mouseover', function(){
			$$('#'+obj.acname+' li').removeProperty('class');
			var elm = $('current');
			if (elm){
				elm.setProperty('id', obj.oldId);
			}
			obj.oldId = this.getProperty('id');
			this.setProperty('class', 'selected');
			this.setProperty('id', 'current');
		});
			// mouseout
		$$('#'+obj.acname+' li').addEvent('mouseout', function(){
			if (! obj.mandatory){
				this.removeProperty('class');
				this.setProperty('id', obj.oldId);
			}
		});
			// click
		$$('#'+obj.acname+' li').addEvent('click', function(){
			obj.field.focus();
			this.setProperty('id', obj.oldId);
			// Complete the field
			obj.complete(this);
			obj.hideOnBlur = true;
		});
	},
	
	// Function hide select : hide the autocomplete div with a 2.5 seconds delay
	hideselect : function(){
		var obj = this;
		obj.tohide = true;
		obj.hideAutocomplete = (function(){
			if (obj.tohide){
				obj.autocomplete.setStyle('visibility', 'hidden');
				obj.tohide = false;
			}
		}).delay(2500);
	},
	
	// Function complete : completes the field with the content of the selected element
	complete : function(elm){
		var obj = this;
		// Gets the text of the element
		var text = elm.get('text');
		// Gets the id of the element to send to the callback function
		var properties = elm.getProperties("id");
		// Fills the field with the text
		obj.field.setProperty('value', text);
		// Empty and hide the autocomplete div
		obj.autocomplete.empty();
		obj.autocomplete.setStyle('visibility', 'hidden');
		
		// Run the callback function if it's set
		if (obj.params.afterUpdate){
			obj.params.afterUpdate(text, properties);
		}
	}
});
