var AutoComplete=Class.create({selector:null,input:null,_timeout:null,visible:false,drawn:false,_hideTimeout:null,options:null,initialize:function(e,f,d){this.action=f;this.input=$(e);this.input.autocomplete="off";this.options=new AutoComplete.Options(d||{});if(!this.input){alert("No input field/binding field given or found")}if(!this.action){alert("No action url specified")}this.selector=document.createElement("select");Event.observe(this.input,"focus",this._onInputFocus.bindAsEventListener(this));Event.observe(this.input,"keydown",this._onInputKeyDown.bindAsEventListener(this));Event.observe(this.input,"blur",this._onInputBlur.bindAsEventListener(this));Event.observe(this.selector,"blur",this._onSelectorBlur.bindAsEventListener(this));Event.observe(this.selector,"focus",this._onSelectorFocus.bindAsEventListener(this));Event.observe(this.selector,"change",this._onSelectorChange.bindAsEventListener(this));Event.observe(window,"resize",this._reposition.bind(this));Event.observe(window,"scroll",this._reposition.bind(this))},_onInputFocus:function(b){this._onSelectorFocus(b)},_onSelectorBlur:function(b){this._onInputBlur(b)},_onInputBlur:function(b){this._hideTimeout=setTimeout(this._checkOnBlur.bind(this),100)},_checkOnBlur:function(){this._hideTimeout=null;this.hide()},_onInputKeyUp:function(b){this._suggest(b)&&Event.stop(b)},_onInputKeyDown:function(b){this._suggest(b)&&Event.stop(b)},_onSelectorFocus:function(b){if(this._hideTimeout){clearTimeout(this._hideTimeout);this._hideTimeout=null}},_onSelectorChange:function(b){this.select()},draw:function(){if(this.drawn){return}if(this.options.cssClass){this.selector.className=this.options.cssClass}Element.setStyle(this.selector,{display:"none",position:"absolute",width:this.input.offsetWidth+"px"});this.selector.size=this.options.size;document.body.appendChild(this.selector);this.input.autocomplete="off";this.drawn=true},hide:function(){if(!this.drawn||!this.visible){return}this.visible=false;if(window.Scriptaculous){new Effect.BlindUp(this.selector,{duration:this.options.delay,queue:"end",afterFinish:function(b){Element.setStyle(this.selector,{display:"none"});this.selector.options.length=0;setTimeout(this._restoreFocus.bind(this),50)}.bind(this)})}else{Element.setStyle(this.selector,{display:"none"});this.selector.options.length=0;setTimeout(this._restoreFocus.bind(this),50)}},_restoreFocus:function(){this.input.focus()},show:function(){if(!this.drawn){this.draw()}var b=null;if(this.selector.options.length){if(window.Scriptaculous){new Effect.BlindDown(this.selector,{duration:this.options.delay,queue:"end"})}else{Element.setStyle(this.selector,{display:"inline"})}this._reposition();this.visible=true}},_cancelTimeout:function(){if(this._timeout){clearTimeout(this._timeout);this._timeout=null}},_suggest:function(f){this._cancelTimeout();var d=Event.keyPressed(f);var e=[20,16,17,91,121,122,123,124,125,126,127,128,129,130,131,132,45,36,35,33,34,144,145,44,19,93,];if(e.indexOf(d)>-1){return false}switch(d){case Event.KEY_LEFT:case Event.KEY_RIGHT:return false;break;case Event.KEY_TAB:case Event.KEY_BACKSPACE:case 46:this.cancel();return false;break;case Event.KEY_RETURN:if(this.visible){this.select();return true}return false;break;case Event.KEY_ESC:this.cancel();return true;break;case Event.KEY_UP:case Event.KEY_DOWN:this._interact(f);return true;break;default:break}if(this.input.value.length>=this.options.threshold-1){this._timeout=setTimeout(this._sendRequest.bind(this),1000*this.options.delay)}return false},_sendRequest:function(){this._request=new Ajax.Request(this.action+this.input.value,{onComplete:this._process.bind(this),method:this.options.requestMethod})},_reposition:function(){if(!this.drawn){return}var b=Position.cumulativeOffset(this.input);b.push(b[0]+this.input.offsetWidth);b.push(b[1]+this.input.offsetHeight);Element.setStyle(this.selector,{left:b[0]+"px",top:b[3]+"px"})},_process:function(c,d){this.selector.options.length=0;switch(this.options.resultFormat){case AutoComplete.Options.RESULT_FORMAT_XML:this._parseXML(c.responseXML);break;case AutoComplete.Options.RESULT_FORMAT_JSON:if(!d){d=c.responseText&&c.responseText.isJSON()?c.responseText.evalJSON():null}this._parseJSON(d);break;case AutoComplete.Options.RESULT_FORMAT_TEXT:this._parseText(c.responseText);break;default:alert("Unable to parse result type. Make sure you've set the resultFormat option correctly");break}if(this.selector.options.length>(this.options.size)){this.selector.size=this.options.size}else{this.selector.size=this.selector.options.length>1?this.selector.options.length:2}if(this.selector.options.length){this.selector.selectedIndex=-1;this.show()}else{this.cancel()}},_parseXML:function(d){var e=null;for(var f=0;f<d.childNodes.length;f++){if(d.childNodes[f].tagName){e=d.childNodes[f].childNodes}}if(!e){alert("Could not parse response XML.");return}for(f=0;f<e.length;f++){suggestion=e.item(f).firstChild.nodeValue;this._addOption(suggestion)}},_parseJSON:function(b){if(!b){b=[]}for(i=0;i<b.length;i++){this._addOption(b[i])}},_parseText:function(c){var d=(c||"").split(/\n/);for(i=0;i<d.length;i++){this._addOption(d[i])}},_addOption:function(d){var c=new Option(d,d);Prototype.Browser.IE?this.selector.add(c):this.selector.add(c,null)},cancel:function(){this.hide()},select:function(){if(this.selector.options.length){this.input.value=this.selector.options[this.selector.selectedIndex].value}this.cancel();if(typeof this.options.onSelect=="function"){this.options.onSelect(this.input)}},_interact:function(d){if(!this.visible){return}var e=Event.keyPressed(d);if(e!=Event.KEY_UP&&e!=Event.KEY_DOWN){return}var f=this.selector.options.length;if(e==Event.KEY_UP){if(this.selector.selectedIndex==0){this.selector.selectedIndex=this.selector.options.length-1}else{this.selector.selectedIndex--}}else{if(this.selector.selectedIndex==this.selector.options.length-1){this.selector.selectedIndex=0}else{this.selector.selectedIndex++}}}});AutoComplete.Options=Class.create({size:10,cssClass:null,onSelect:null,threshold:3,delay:0.2,requestMethod:"GET",resultFormat:"xml",initialize:function(b){Object.extend(this,b||{})}});Object.extend(AutoComplete.Options,{RESULT_FORMAT_XML:"xml",RESULT_FORMAT_JSON:"json",RESULT_FORMAT_TEXT:"text"});Object.extend(Event,{KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,KEY_SHIFT:16,KEY_CONTROL:17,KEY_CAPSLOCK:20,KEY_SPACE:32,keyPressed:function(b){return Prototype.Browser.IE?window.event.keyCode:b.which}});