//
// Select Box Auto Complete V1.0 2009-03-04 by SOFTWAY
// 
// Replaces each matched element with a textbox with autocomplete functionality.
// Autocomplete data is automatically extracted from each SELECT options an optiongroups
/*********************************************************************************
USAGE:
$('select#SELECT_ID').get(0).onHit = function(texto, val) {	alert(texto,val): }		//OVERIDE DO onHit (opcional)

$(document).ready(function() { $('select.SELECT_CLASS').swSelectAutoComplete(); });

RECOMENDED CSS:
.divAutoComplete {cursor:default; height:300px; width:1px; overflow:auto; overflow-y:scroll; position:absolute; border:1px solid black; background-color:#FFF; }
.divAutoComplete ul {list-style:none; list-style-type:none; list-style-image:none; margin:0px; padding:0px;}
.divAutoComplete li {margin:0px; padding:0px 2px 0px 2px; white-space:nowrap;}
.divAutoComplete li.optgroup {list-style:none; font-weight:bold;}
.divAutoComplete li.option {padding-left:10px; font-weight:normal;}
.divAutoComplete li.selected { background-color:#006; color:#FFF;}

HTML EXAMPLE:
<form>
<select name="FORMVARNAME" id="SELECT_ID" style="width:60px;" class="SELECT_CLASS">
	<option value="">Texto OnEmpty</option>
	<optgroup label="GRUPO 1">
		<option value="1" >Option 1</option>
		<option value="2" >Option 2</option>
		<option value="3" >Option 3</option>
	</optgroup>
	<optgroup label="GRUPO 2">
		<option value="4" >Option 4</option>
		<option value="5" >Option 5</option>
		<option value="6" >Option 6</option>
	</optgroup>
</select>
</form>
*************************************************************************************/


(function($) {
	$.fn.swSelectAutoComplete = function(settings) {
		var jQueryMatchedObj = this;
		var oAllDivs = new Object;
		
		function _initialize() {
			jQueryMatchedObj.each(function() {
				//$(this).hide();
				
				var oProperties = new Object();
				oProperties.__sDivAutoCompleteId = 'iDivAutoComplete_' + $(this).attr('id');
				oProperties.__sSearchTextId = 'iSearchText_' + $(this).attr('id');
				
				
				oProperties.__$divautocomplete = $('<div class="divAutoComplete" mysearchtext="'+oProperties.__sSearchTextId+'" id="'+oProperties.__sDivAutoCompleteId+'"></div>').hide().insertAfter($(this));		
				oProperties.__$autocomplete = $('<ul class="autocomplete"></ul>').appendTo(oProperties.__$divautocomplete);
				oProperties.__$searchText = null;
				oProperties.__selectedItem = null;
				oProperties.__onEmptyValue= '';
				
				if(this.onHit) oProperties.onHit = this.onHit;
				
				oProperties.set_selected_item = function(item) {
					if(item === undefined) return;
					this.__selectedItem = item;
					if(this.__selectedItem === null || this.__selectedItem < 0) {	this.hide_auto_complete(); return;}
					this.__$autocomplete.find('li').removeClass('selected');
					var mySel = this.__$autocomplete.find('li#'+item).addClass('selected');
					this.show_auto_complete();
					return (mySel);
				}
				
				oProperties.set_select_index = function(idx) {
					var ID = this.__$autocomplete.find('li.option[@idx='+idx+']').attr('id');
					return (this.set_selected_item(ID));
				}
				
				oProperties.set_prev_selected_item = function() {
					var curIdx = this.__$autocomplete.find('li#'+this.__selectedItem).attr('idx');
					if (curIdx <= 0) return;
					var myNewSel = this.set_select_index(parseInt(curIdx)-1, true);
					if(myNewSel) myNewSel.focus().get(0).scrollIntoView(false);
				}
				
				oProperties.set_next_selected_item = function() {
					var curIdx = this.__$autocomplete.find('li#'+this.__selectedItem).attr('idx');
					var myNewSel = this.set_select_index(parseInt(curIdx)+1, true);
					if(myNewSel) myNewSel.focus().get(0).scrollIntoView(false);
				}
				
				oProperties.populate_search_field = function (texto, val) {
					this.__$searchText.val(texto);
					this.set_selected_item(null);
					this.__$searchText.blur();
					if(this.onHit) this.onHit(texto, val);
				}
				
				oProperties.show_auto_complete = function() {
					//var offset = this.__$searchText.offset();
					var offset = this.__$searchText.position();
					//this.__$divautocomplete.get(0).style.left = (offset.left) + 'px';
					this.__$divautocomplete.get(0).style.right = '0px';
					this.__$divautocomplete.get(0).style.top = (offset.top + this.__$searchText.outerHeight()) + 'px';
					this.__$divautocomplete.slideDown(150);
				}
				
				oProperties.filter_results = function() {
					var i=0;
					
					sCurSearchTextVal = this.__$searchText.val().toUpperCase();
					this.__$autocomplete.find('li.optgroup').hide();
					this.__$autocomplete.find('li.option').each(function(){
						if($(this).text().toUpperCase().indexOf(sCurSearchTextVal) >= 0 ) { 
							$(this).show(); // mostra a LI que tem match
							$(this).attr('idx',i); 
							$(this).parent().parent().show(); // mostra a parent LI (equivalente à option group) que tem match
							i++; 
						} else { 
							$(this).hide(); // esconde a LI que não tem match
							$(this).attr('idx',-1); 
						}
					});
					if(i>0) {
						var foo = this.set_select_index(0);
						//if(foo) {alert('scrollIntoView'); foo.focus().get(0).scrollIntoView(false);  }
						this.show_auto_complete();
					} else {
						this.set_selected_item(null);	
						this.hide_auto_complete();
					}
					
					if(this.__$divautocomplete.get(0).scrollWidth > this.__$divautocomplete.get(0).clientWidth) this.__$divautocomplete.width(this.__$divautocomplete.get(0).scrollWidth + 25);
				}
				
				oProperties.hide_auto_complete = function() {this.__$divautocomplete.hide();}
				
				oProperties.__$divautocomplete.bind("mouseenter",function(){this.isMouseOver = true;}).bind("mouseleave",function(){this.isMouseOver = false;});

				var i=0;
				$(this).children().each(function() {
					if(this.tagName == 'OPTION') {
						if(oProperties.__onEmptyValue=='') oProperties.__onEmptyValue=$(this).html();
					} else if(this.tagName == 'OPTGROUP') {
						var $optgrplabel = $('<li class="optgroup"></li>').text($(this).attr('label')).appendTo(oProperties.__$autocomplete);
						var $optgrp = $('<ul></ul>').appendTo($optgrplabel);
						$(this).children().each(function(index) { 
							$myLi = $('<li class="option" idx="'+i+'" id="iLI_'+$(this).attr('value')+'" val="'+$(this).attr('value')+'"></li>');
							$myLi.get(0).oMyProps = oProperties;
							
							$myLi.text($(this).text())
								.appendTo($optgrp)
								.mouseover(function(){this.oMyProps.set_selected_item(this.id)})
								.click(function(){this.oMyProps.populate_search_field($(this).text(), $(this).attr('val')); hideAllAutoCompletes();});
							i++;
						});
					}
				});
				
				
				$(this).replaceWith('<input type="text" style="'+$(this).attr('style')+'" myautocomplete="'+$(this).attr('id')+'" name="'+$(this).attr('name')+'" id="'+oProperties.__sSearchTextId+'" value="'+oProperties.__onEmptyValue+'" onempty="'+oProperties.__onEmptyValue+'" />');
				oProperties.__$searchText = $('#'+oProperties.__sSearchTextId);
				oProperties.__$searchText.get(0).oMyProps = oProperties;
				oAllDivs[$(this).attr('id')] = oProperties;
								
				
				oProperties.__$searchText.attr('autocomplete','off').keyup(function(event) {
					if(event.keyCode > 40 || event.keyCode == 8) {
						this.oMyProps.filter_results();
					} else if (event.keyCode == 38 && this.oMyProps.__selectedItem !== null) {
						this.oMyProps.set_prev_selected_item()
						event.preventDefault();
					} else if (event.keyCode == 40 && this.oMyProps.__selectedItem !== null) {
						this.oMyProps.set_next_selected_item()
						event.preventDefault();
					} else if (event.keyCode == 27 && this.oMyProps.__selectedItem !== null) {
						this.oMyProps.set_selected_item(null);
					} 
				}).keypress(function(event) {
					if (event.keyCode == 13 && this.oMyProps.__selectedItem !== null) {
						_$curSelItemLI = this.oMyProps.__$autocomplete.find('li#'+this.oMyProps.__selectedItem);
						this.oMyProps.populate_search_field(_$curSelItemLI.text(), _$curSelItemLI.attr('val'));
						this.oMyProps.set_selected_item(null);
						event.preventDefault();
					} 
				}).blur(function(event) { 
					oMyAC = this.oMyProps;
					if($(this).val() == '') $(this).val($(this).attr('onempty'));
					setTimeout(function() { if(!oMyAC.__$divautocomplete.get(0).isMouseOver) oMyAC.set_selected_item(null); else oMyAC.__$searchText.get(0).focus(); }, 250);
				}).focus(function() {
					if($(this).val() == $(this).attr('onempty')) { 
						$(this).val(''); 
						this.oMyProps.filter_results();
					}
					
				});
			});
		}
		
		function hideAllAutoCompletes() {
			for(i in oAllDivs) {
				oAllDivs[i].hide_auto_complete();
			}
		}
		
		_initialize();
		hideAllAutoCompletes();
	}
})(jQuery);