var Autocompleter=new Class({Implements:[Options,Events],options:{onAfterSelect:$empty,minLength:1,markQuery:true,width:"inherit",maxChoices:10,injectChoice:null,customChoices:null,emptyChoices:null,visibleChoices:true,className:"autocompleter-choices",zIndex:42,delay:400,observerOptions:{},fxOptions:{},autoSubmit:false,overflow:false,overflowMargin:25,selectFirst:false,filter:null,filterCase:false,filterSubset:false,forceSelect:false,selectMode:true,choicesMatch:null,multiple:false,separator:", ",separatorSplit:/\s*[,;]\s*/,autoTrim:false,allowDupes:false,cache:true,relative:false},initialize:function(B,A){this.element=$(B);this.setOptions(A);this.build();this.observer=new Observer(this.element,this.prefetch.bind(this),$merge({delay:this.options.delay},this.options.observerOptions));this.queryValue=null;if(this.options.filter){this.filter=this.options.filter.bind(this)}var C=this.options.selectMode;this.typeAhead=(C=="type-ahead");this.selectMode=(C===true)?"selection":C;this.cached=[]},build:function(){if($(this.options.customChoices)){this.choices=this.options.customChoices}else{this.choices=new Element("ul",{"class":this.options.className,styles:{zIndex:this.options.zIndex}}).inject(document.body);this.relative=false;if(this.options.relative){this.choices.inject(this.element,"after");this.relative=this.element.getOffsetParent()}this.fix=new OverlayFix(this.choices)}if(!this.options.separator.test(this.options.separatorSplit)){this.options.separatorSplit=this.options.separator}this.fx=(!this.options.fxOptions)?null:new Fx.Tween(this.choices,$merge({property:"opacity",link:"cancel",duration:200},this.options.fxOptions)).addEvent("onStart",Chain.prototype.clearChain).set(0);this.element.setProperty("autocomplete","off").addEvent((Browser.Engine.trident||Browser.Engine.webkit)?"keydown":"keypress",this.onCommand.bind(this)).addEvent("click",this.onCommand.bind(this,[false])).addEvent("focus",this.toggleFocus.create({bind:this,arguments:true,delay:100})).addEvent("blur",this.toggleFocus.create({bind:this,arguments:false,delay:100}))},destroy:function(){if(this.fix){this.fix.destroy()}this.choices=this.selected=this.choices.destroy()},toggleFocus:function(A){this.focussed=A;if(!A){this.hideChoices(true)}this.fireEvent((A)?"onFocus":"onBlur",[this.element])},onCommand:function(B){if(!B&&this.focussed){return this.prefetch()}if(B&&B.key&&!B.shift){switch(B.key){case"enter":if(this.element.value!=this.opted){return true}if(this.selected&&this.visible){this.choiceSelect(this.selected);return !!(this.options.autoSubmit)}break;case"up":case"down":if(!this.prefetch()&&this.queryValue!==null){var A=(B.key=="up");this.choiceOver((this.selected||this.choices)[(this.selected)?((A)?"getPrevious":"getNext"):((A)?"getLast":"getFirst")](this.options.choicesMatch),true)}return false;case"esc":case"tab":this.hideChoices(true);break}}return true},setSelection:function(F){var G=this.selected.inputValue,H=G;var A=this.queryValue.length,C=G.length;if(G.substr(0,A).toLowerCase()!=this.queryValue.toLowerCase()){A=0}if(this.options.multiple){var E=this.options.separatorSplit;H=this.element.value;A+=this.queryIndex;C+=this.queryIndex;var B=H.substr(this.queryIndex).split(E,1)[0];H=H.substr(0,this.queryIndex)+G+H.substr(this.queryIndex+B.length);if(F){var D=H.split(this.options.separatorSplit).filter(function(J){return this.test(J)},/[^\s,]+/);if(!this.options.allowDupes){D=[].combine(D)}var I=this.options.separator;H=D.join(I)+I;C=H.length}}this.observer.setValue(H);this.opted=H;if(F||this.selectMode=="pick"){A=C}this.element.selectRange(A,C);this.fireEvent("onSelection",[this.element,this.selected,H,G])},showChoices:function(){var C=this.options.choicesMatch,B=this.choices.getFirst(C);this.selected=this.selectedValue=null;if(this.fix){var E=this.element.getCoordinates(this.relative),A=this.options.width||"auto";this.choices.setStyles({left:E.left,top:E.bottom,"min-width":(A===true||A=="inherit")?(E.width-2):(A-2)})}if(!B){return }if(!this.visible){this.visible=true;this.choices.setStyle("display","");if(this.fx){this.fx.start(1)}this.fireEvent("onShow",[this.element,this.choices])}if(this.options.selectFirst||this.typeAhead||B.inputValue==this.queryValue){this.choiceOver(B,this.typeAhead)}var D=this.choices.getChildren(C),F=this.options.maxChoices;var I={overflowY:"hidden",height:""};this.overflown=false;if(D.length>F){var J=D[F-1];I.overflowY="scroll";I.height=J.getCoordinates(this.choices).bottom;this.overflown=true}this.choices.setStyles(I);this.fix.show();if(this.options.visibleChoices){var H=document.getScroll(),K=document.getSize(),G=this.choices.getCoordinates();if(G.right>H.x+K.x){H.x=G.right-K.x}if(G.bottom>H.y+K.y){H.y=G.bottom-K.y}window.scrollTo(Math.min(H.x,G.left),Math.min(H.y,G.top))}},hideChoices:function(A){if(A){var C=this.element.value;if(this.options.forceSelect){C=this.opted}if(this.options.autoTrim){C=C.split(this.options.separatorSplit).filter($arguments(0)).join(this.options.separator)}this.observer.setValue(C)}if(!this.visible){return }this.visible=false;if(this.selected){this.selected.removeClass("autocompleter-selected")}this.observer.clear();var B=function(){this.choices.setStyle("display","none");this.fix.hide()}.bind(this);if(this.fx){this.fx.start(0).chain(B)}else{B()}this.fireEvent("onHide",[this.element,this.choices])},prefetch:function(){var F=this.element.value,E=F;if(this.options.multiple){var C=this.options.separatorSplit;var A=F.split(C);var B=this.element.getSelectedRange().start;var G=F.substr(0,B).split(C);var D=G.length-1;B-=G[D].length;E=A[D]}if(E.length<this.options.minLength){this.hideChoices()}else{if(E===this.queryValue||(this.visible&&E==this.selectedValue)){if(this.visible){return false}this.showChoices()}else{this.queryValue=E;this.queryIndex=B;if(!this.fetchCached()){this.query()}}}return true},fetchCached:function(){return false;if(!this.options.cache||!this.cached||!this.cached.length||this.cached.length>=this.options.maxChoices||this.queryValue){return false}this.update(this.filter(this.cached));return true},update:function(B){this.choices.empty();this.cached=B;var A=B&&$type(B);if(!A||(A=="array"&&!B.length)||(A=="hash"&&!B.getLength())){(this.options.emptyChoices||this.hideChoices).call(this)}else{if(this.options.maxChoices<B.length&&!this.options.overflow){B.length=this.options.maxChoices}B.each(this.options.injectChoice||function(D){var C=new Element("li",{html:this.markQueryValue(D)});C.inputValue=D;this.addChoiceEvents(C).inject(this.choices)},this);this.showChoices()}},choiceOver:function(C,D){if(!C||C==this.selected){return }if(this.selected){this.selected.removeClass("autocompleter-selected")}this.selected=C.addClass("autocompleter-selected");this.fireEvent("onSelect",[this.element,this.selected,D]);if(!this.selectMode){this.opted=this.element.value}if(!D){return }this.selectedValue=this.selected.inputValue;if(this.overflown){var F=this.selected.getCoordinates(this.choices),E=this.options.overflowMargin,G=this.choices.scrollTop,A=this.choices.offsetHeight,B=G+A;if(F.top-E<G&&G){this.choices.scrollTop=Math.max(F.top-E,0)}else{if(F.bottom+E>B){this.choices.scrollTop=Math.min(F.bottom-A+E,B)}}}if(this.selectMode){this.setSelection()}},choiceSelect:function(A){if(A){this.choiceOver(A)}this.setSelection(true);this.queryValue=false;this.hideChoices();this.fireEvent("onAfterSelect",A)},filter:function(A){return(A||this.tokens).filter(function(B){return this.test(B)},new RegExp(((this.options.filterSubset)?"":"^")+this.queryValue.escapeRegExp(),(this.options.filterCase)?"":"i"))},markQueryValue:function(A){return(!this.options.markQuery||!this.queryValue)?A:A.replace(new RegExp("("+((this.options.filterSubset)?"":"^")+this.queryValue.escapeRegExp()+")",(this.options.filterCase)?"":"i"),'<span class="autocompleter-queried">$1</span>')},addChoiceEvents:function(A){return A.addEvents({mouseover:this.choiceOver.bind(this,[A]),click:this.choiceSelect.bind(this,[A])})}});var OverlayFix=new Class({initialize:function(A){if(Browser.Engine.trident){this.element=$(A);this.relative=this.element.getOffsetParent();this.fix=new Element("iframe",{frameborder:"0",scrolling:"no",src:"javascript:false;",styles:{position:"absolute",border:"none",display:"none",filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"}}).inject(this.element,"after")}},show:function(){if(this.fix){var A=this.element.getCoordinates(this.relative);delete A.right;delete A.bottom;this.fix.setStyles($extend(A,{display:"",zIndex:(this.element.getStyle("zIndex")||1)-1}))}return this},hide:function(){if(this.fix){this.fix.setStyle("display","none")}return this},destroy:function(){if(this.fix){this.fix=this.fix.destroy()}}});Element.implement({getSelectedRange:function(){if(!Browser.Engine.trident){return{start:this.selectionStart,end:this.selectionEnd}}var E={start:0,end:0};var A=this.getDocument().selection.createRange();if(!A||A.parentElement()!=this){return E}var C=A.duplicate();if(this.type=="text"){E.start=0-C.moveStart("character",-100000);E.end=E.start+A.text.length}else{var B=this.value;var D=B.length-B.match(/[\n\r]*$/)[0].length;C.moveToElementText(this);C.setEndPoint("StartToEnd",A);E.end=D-C.text.length;C.setEndPoint("StartToStart",A);E.start=D-C.text.length}return E},selectRange:function(D,A){if(Browser.Engine.trident){var C=this.value.substr(D,A-D).replace(/\r/g,"").length;D=this.value.substr(0,D).replace(/\r/g,"").length;var B=this.createTextRange();B.collapse(true);B.moveEnd("character",D+C);B.moveStart("character",D);B.select()}else{this.focus();this.setSelectionRange(D,A)}return this}});Autocompleter.Base=Autocompleter;Autocompleter.Local=new Class({Extends:Autocompleter,options:{minLength:0,delay:200},initialize:function(B,C,A){this.parent(B,A);this.tokens=C},query:function(){this.update(this.filter())}});Autocompleter.Request=new Class({Extends:Autocompleter,options:{onRequest:$empty,postData:{},ajaxOptions:{},postVar:"value"},query:function(){var C=$unlink(this.options.postData)||{};C[this.options.postVar]=this.queryValue;var B=$(this.options.indicator);if(B){B.setStyle("display","")}var A=this.options.indicatorClass;if(A){this.element.addClass(A)}this.fireEvent("onRequest",[this.element,this.request,C,this.queryValue]);this.request.send({data:C})},queryResponse:function(){var B=$(this.options.indicator);if(B){B.setStyle("display","none")}var A=this.options.indicatorClass;if(A){this.element.removeClass(A)}return this.fireEvent("onComplete",[this.element,this.request])}});Autocompleter.Request.JSON=new Class({Extends:Autocompleter.Request,initialize:function(C,B,A){this.parent(C,A);this.request=new Request.JSON($merge({url:B,link:"cancel"},this.options.ajaxOptions)).addEvent("onComplete",this.queryResponse.bind(this))},queryResponse:function(A){this.parent();this.update(A)}});Autocompleter.Request.HTML=new Class({Extends:Autocompleter.Request,initialize:function(C,B,A){this.parent(C,A);this.request=new Request.HTML($merge({url:B,link:"cancel",update:this.choices},this.options.ajaxOptions)).addEvent("onComplete",this.queryResponse.bind(this))},queryResponse:function(A,B){this.parent();if(!B||!B.length){this.hideChoices()}else{this.choices.getChildren(this.options.choicesMatch).each(this.options.injectChoice||function(C){var D=C.innerHTML;C.inputValue=D;this.addChoiceEvents(C.set("html",this.markQueryValue(D)))},this);this.showChoices()}}});Autocompleter.Ajax={Base:Autocompleter.Request,Json:Autocompleter.Request.JSON,Xhtml:Autocompleter.Request.HTML};