function isInt(myNum) {
	// get the modulus: if it's 0, then it's an integer
	var myMod = myNum % 1;
	
	if (myMod == 0) {
	        return true;
	} else {
	        return false;
	}
}

var AutocompleteSelect = new Class
(
	{
		initialize: function(elementId, options)
		{
			this.elementId = elementId;
			this.options = options;
			this.list = Array();
			this.listUnsorted = Array();
			this.childs = Array();
			this.currentSelectedElement = 0;
			this.visible = false;
			this.limit = 40;
			this.limitCount = 0;

			/**
				Build the initial list
			*/
			this.first = true;			
			this.intIndexes = true;
			
			$(this.elementId).getChildren().each(function (option) {
													if(option.getTag() == 'option')
													{													
														if(!isInt(option.value))
														{
															this.intIndexes = false;
															return;
														}																								
														this.list[option.value] =  option.innerHTML;
														this.listUnsorted[option.value] = option.innerHTML;
													}
												}.bind(this));			
			if(this.intIndexes == false)
				return;
			
			this.searchInput = new Element('input');
			this.searchInput.setProperty('class', $(this.elementId).getProperty('class'));
			this.searchInput.addClass('autoCompleteField');
			this.searchInput.addClass('text');
			this.searchInput.addClass('regular');
			$(this.elementId).setStyle('display', 'none');
			
			this.list.sort();			
			
			if($(this.elementId).getValue() == "" || $(this.elementId).getValue() == "0")
				;
			else
				this.searchInput.value = this.listUnsorted[$(this.elementId).getValue()];			
			//this.searchInput.setProperty('autocomplete', 'off');		
			this.searchInput.addListener('mousedown', this.handleFocus.bind(this));
			this.searchInput.addListener('click', this.stopEvent.bind(this));
			this.searchInput.addListener('keydown', this.handleSearch.bind(this));
			this.searchInput.addListener('keydown', this.disableEnter.bind(this));

			this.searchResult = new Element('div');
	
			this.searchResult.addClass('searchResult');			
			this.searchResult.addListener('click', this.stopEvent.bind(this));
			
			document.addListener('click', this.handleUnfocus.bind(this));
			
			this.searchInput.injectBefore($(this.elementId));
			this.searchResult.injectAfter(this.searchInput);
		},
		
		destroy: function(e)
		{
			if(!window.webkit)
			{
				if($defined(this.searchResult))
				{
					this.searchResult.removeEvents();
					this.searchResult.empty();
					this.searchResult = null;
				}
				
				if($defined(this.searchInput))
				{
					this.searchInput.empty();
					this.searchInput.removeEvents();
					this.searchInput = null;				
				}				
				this.list = null;
				this.listUnsorted = null;
				
				this.childs.each(function (listItem, key) {
					this.childs[key] = null;
				}.bind(this) );		
				
				this.childs = null;
			}
		},		
		
		handleUnfocus: function(e)
		{
			this.visible = false;
			if($defined(this.searchResult))
				this.searchResult.setStyle('display', 'none');
		},
		
		handleFocus: function(e)
		{
			$$('.searchResult').each(function(element) { element.setStyle('display', 'none') } );
			this.searchInput.value = '';				
			if(this.first == true)
			{
				this.showList(this.list);
				this.first = false;
			}	
			if(this.visible == false)
			{
				this.visible = true;
				this.searchResult.setStyle('display', 'block');
				//this.searchInput.selectRange(0,1000);
			}
			else
			{
				this.visible = false;
			}
		},
		
		showList: function(aList)
		{
			this.searchResult.empty();
			this.childs = null;
			this.childs = Array();
			this.limitCount = 0;
			
			var keuzeElement = new SelectItem({'name' : 'Begin met typen om uw zoekresultaten te verfijnen.', 'key' : -1});
			keuzeElement.element.addClass('hulp');			
			this.searchResult.adopt(keuzeElement.element);	
			
			aList.each(function (listItem, key) {
					if(this.limitCount <= this.limit)
					{
						var name = listItem;
						if(name == '')
							name = '&nbsp;';
						var childItem = new SelectItem({'name' : name, 'key' : this.listUnsorted.indexOf(listItem)});

						// Select an item					
						childItem.element.addListener("click", function(e){
							$(this.elementId).value = this.listUnsorted.indexOf(listItem);
							this.searchInput.value = listItem;
							this.handleUnfocus();
							this.searchInput.focus();
						}.bind(this));

						// Hover over element
						childItem.element.addListener("mouseover", function(e){
							childItem.element.removeClass("selectItem");
							childItem.element.addClass("selectItemHover");
							this.unfocusElement(this.currentSelectedElement);
							this.currentSelectedElement = key;
						}.bind(this));
						
						// Leave hover
						childItem.element.addListener("mouseleave", function(e){
							childItem.element.addClass("selectItem");
							childItem.element.removeClass("selectItemHover");
						}.bind(this));					
						
						this.searchResult.adopt(childItem.element);	
						this.childs[key] = childItem;
						this.limitCount++;
					}
					
				}.bind(this) );
			this.currentSelectedElement = 0;
			this.focusElement(0);
		},		

		focusElement: function(key)
		{
			if(!$defined(this.childs[key]) || !$defined(this.childs[key].element))
				return;
			
			this.childs[key].element.removeClass("selectItem");
			this.childs[key].element.addClass("selectItemHover");
		},

		unfocusElement: function(key)
		{
			if(!$defined(this.childs[key]))
				return;

			this.childs[key].element.addClass("selectItem");
			this.childs[key].element.removeClass("selectItemHover");
		},

		doNext: function()
		{
			if(!$defined(this.childs[this.currentSelectedElement+1]))
				return;

			this.unfocusElement(this.currentSelectedElement);
			this.currentSelectedElement++;
			this.focusElement(this.currentSelectedElement);
		},
		
		doPrevious: function()
		{
			if(this.currentSelectedElement <= 0)
				return;
			
			if(!$defined(this.childs[this.currentSelectedElement-1]))
				return;
				
			this.unfocusElement(this.currentSelectedElement);
			this.currentSelectedElement--;
			this.focusElement(this.currentSelectedElement);
		},
		
		disableEnter: function(e)
		{
			if(e.key == 'enter')
				e = new Event(e).stop();
		},
		
		handleSearch: function(e)
		{
			e = new Event(e);
			
			searchValue = this.searchInput.getValue();

			if(e && e.key)
			{
				switch(e.key)
				{
					case 'left':
					case 'right':
					{
						break;
					}
					/*
						On tab and on enter the selection is accepted
					*/
					case 'enter':
					{
						e.stop();
					}
					case 'tab':
					{
						if(this.visible)
						{
							if(this.searchInput.value == "" && this.currentSelectedElement == 0)
							{
								$(this.elementId).value = 0;
								$(this.elementId).fireEvent('change');
							}
							else if($defined(this.childs[this.currentSelectedElement]))
							{
								$(this.elementId).value = this.listUnsorted.indexOf(this.childs[this.currentSelectedElement].options.name);
								this.searchInput.value = this.childs[this.currentSelectedElement].options.name;	
							
								$(this.elementId).fireEvent('change');
								this.searchInput.fireEvent('onChange');
							}
						
						
							this.handleUnfocus();
							//
						}
						// do nothing
						break;
					}
					case 'esc':
					{
						this.handleUnfocus();
					}
					case 'down':
					{
						// People tend to tab -> arrow down. This will make that work like expected
						if(!this.visible)
							this.handleFocus();
						this.doNext();
						break;				
					}
					case 'up':
					{
						this.doPrevious();
						break;
					}
					case 'backspace':
					{
						e.key = '';
						searchValue = searchValue.substr(searchValue.length-1);
					}
					default:
					{		
						if(!this.visible)
							this.handleFocus();

						if(searchValue == "" && this.currentSelectedElement == 0)
						{
							$(this.elementId).value = "";
						}						
					
						var filteredList = this.list.filter(function(element, index) 
						{
							if($defined(element))
							{
								//if(element.test(searchValue + e.key, "i"))
								if(element.toLowerCase().contains(searchValue.toLowerCase()))
								{
									return true;
								}
								else
								{
									return false;
								}
							}
							return false;
						}.bind(this));

						this.showList(filteredList);
						break;
					}
				}
			}

		},
		
		stopEvent: function(e)
		{
			e = new Event(e).stop();
		}
	}
);

//AutocompleteSelect.implement(new Options, new Events); 

var SelectItem = new Class
(
	{
		initialize: function(options)
		{
			this.options = options;
			this.element = new Element("div");
			this.element.addClass("selectItem");
			this.element.setHTML(this.options.name);
		}
	}
);

window.addEvent('load', function() {
	$$('.autoCompleteAjax').each(function(element)
	{
		if(element.id == null || element.id == '')
			element.id = 'autocompleteAjax' + AutoCompleteCountAjax;
		
		AutoCompletesAjax[AutoCompleteCountAjax] = new AutocompleteSelectAjax(element.id,null);
		AutoCompleteCountAjax++;
	}
	);
});
