(function($){$.fn.hintbox=function(options){inputs=this;var ACTIONS={ENTER:13,LEFT:37,UP:38,RIGHT:39,DOWN:40,SPACE:32}
var MATCHRULE={STARTS_WITH:"S",ENDS_WITH:"E",CONTAINS:"C"}
var defaults={backgroundColor:'#3369F9',color:'#FFFFFF',autoDimentions:false,minChars:1,width:'120px',separator:'\n',delay:400,slideDownTime:0,slideUpTime:0,inputClass:'hintbox_input',inputLoadingClass:'hintbox_loading',hintboxContainerClass:'hintbox_list_container',url:'',params:{},extraParams:'',json:false,useCache:true,matchHint:false,matchRule:MATCHRULE.STARTS_WITH,sort:false,limit:0,onBeforeListLoad:function(){},onListLoaded:function(){},onItemSelected:function(){}}
if(options.matchRule!=undefined){options.matchRule=options.matchRule.toUpperCase();if(options.matchRule!=MATCHRULE.STARTS_WITH&&options.matchRule!=MATCHRULE.ENDS_WITH&&options.matchRule!=MATCHRULE.CONTAINS){options.matchRule=defaults.matchRule;}}
var options=jQuery.extend(defaults,options);var levenshtein=function(a,b){var i;var j;var cost;var d=new Array();if(a.length==0){return b.length;}
if(b.length==0){return a.length;}
for(i=0;i<=a.length;i++){d[i]=new Array();d[i][0]=i;}
for(j=0;j<=b.length;j++){d[0][j]=j;}
for(i=1;i<=a.length;i++){for(j=1;j<=b.length;j++){cost=(a.charAt(i-1)==b.charAt(j-1))?0:1;d[i][j]=Math.min(d[i-1][j]+1,d[i][j-1]+1,d[i-1][j-1]+cost);if(i>1&&j>1&&a.charAt(i-1)==b.charAt(j-2)&&a.charAt(i-2)==b.charAt(j-1)){d[i][j]=Math.min(d[i][j],d[i-2][j-2]+cost);}}}
return d[a.length][b.length];}
var bindKeyboard=function(input){jQuery(document).bind('keydown',function(event){selectHintElement(event,input);});}
var unbindKeyboard=function(){jQuery(document).unbind('keydown');}
var rebindKeyboard=function(input){unbindKeyboard();bindKeyboard(input);}
var getUnsortedList=function(input){return getHintListContainer(input).find('ul');}
var getHintListContainer=function(input){return input.next('.'+options.hintboxContainerClass);}
var hintListContainerExists=function(input){if(getHintListContainer(input).get()==''){return false;}
return true;}
var init=function(input){var prevVal='';input.attr('autocomplete','off');input.keyup(function(event){if(event.keyCode!=ACTIONS.UP&&event.keyCode!=ACTIONS.DOWN&&event.keyCode!=ACTIONS.ENTER&&event.keyCode!=ACTIONS.LEFT&&event.keyCode!=ACTIONS.RIGHT){var currentVal=jQuery.trim(input.val());if(currentVal!=prevVal){if(currentVal.length>=options.minChars){setTimeout(function(){loadList(input);},options.delay);}
else{getHintListContainer(input).slideUp(options.slideUpTime);}}
prevVal=currentVal;}
if(event.keyCode==ACTIONS.ENTER){var container=getHintListContainer(input);if(container.get()!=''){closeHintResults(input);}}});}
var selectHintElementByClick=function(input){if(hintListContainerExists(input)){var unsortedList=getUnsortedList(input);unsortedList.find('li').click(function(){var curLi=jQuery(this);input.val(curLi.text());closeHintResults(input);options.onItemSelected(curLi);});}}
var selectHintElement=function(event,input){if(hintListContainerExists(input)){var cssBackup=jQuery.data(input,"cssBackup");var unsortedList=getUnsortedList(input);var firstLi=unsortedList.find('li:first');var lastLi=unsortedList.find('li:last');var selectedLi=unsortedList.find('.selected');if(selectedLi.get()==''){if(event.keyCode==ACTIONS.DOWN){selectedLi=firstLi;}
else if(event.keyCode==ACTIONS.UP){selectedLi=lastLi;}
selectLi(selectedLi);return;}
if(event.keyCode==ACTIONS.DOWN){deselectLi(selectedLi,cssBackup);var nextLi=selectedLi.next('li');if(nextLi.get()==''){nextLi=firstLi;input.focus();unsortedList.find('.selected').removeClass('selected');}
else{selectedLi=nextLi;selectLi(selectedLi);}}
else if(event.keyCode==ACTIONS.UP){deselectLi(selectedLi,cssBackup);var prevLi=selectedLi.prev('li');if(prevLi.get()==''){prevLi=lastLi;input.focus();unsortedList.find('.selected').removeClass('selected');}
else{selectLi(prevLi);selectedLi=prevLi;}}
else if(event.keyCode==ACTIONS.ENTER){if(selectedLi.get()!=''){input.val(selectedLi.text());}
closeHintResults(input);options.onItemSelected(selectedLi);}}}
var buildUrl=function(input){var url=options.url;url.indexOf('?')!=-1?url+='&':url+='?';url+='q='+escape(jQuery.trim(input.val()));for(i in options.params){url+='&'+i+'='+escape(jQuery.trim(options.params[i]));}
var extraParams=jQuery.trim(options.extraParams);if(extraParams.length>0){if(extraParams.indexOf('&')>0){url+='&'+extraParams;}
else{url+=extraParams;}}
return url;}
var getCache=function(){var cache=jQuery(document).data('hintbox_cache');if(cache==undefined){var cache=new Array();cache.getItem=function(cKey){return this[cKey];}
cache.putItem=function(cKey,cValue){this[cKey]=cValue;}
cache.hasItem=function(cKey){if(this[cKey]==undefined){return false;}
return true;}
jQuery(document).data('hintbox_cache',cache);}
return cache;}
var onAjaxCallSuccess=function(input,queryUrl,html){input.removeClass(options.inputLoadingClass);if(jQuery.trim(html).length>0){if(options.useCache){var cache=getCache();if(!cache.hasItem(queryUrl)){cache.putItem(queryUrl,html);}}
createList(input,html);var cssBackup={backgroundColor:getUnsortedList(input).find('li').css('background-color'),color:getUnsortedList(input).find('li').css('color')}
jQuery.data(input,'cssBackup',cssBackup);applyOptions(input);fixIssues(input);highlight(input);rebindKeyboard(input);selectHintElementByClick(input);options.onListLoaded(getUnsortedList(input));}}
var loadList=function(input){input.addClass(options.inputLoadingClass);options.onBeforeListLoad();var queryUrl=buildUrl(input);var entries=null;if(options.useCache){var cache=getCache();if(cache.hasItem(queryUrl)){entries=cache.getItem(queryUrl);}}
if(entries==null){if(!options.json){jQuery.ajax({url:queryUrl,success:function(html){onAjaxCallSuccess(input,queryUrl,html);}});}
else{jQuery.getJSON(queryUrl,function(data){var str="";var list=jQuery(data.list);var listSize=list.size();var i=1;list.each(function(){str+=this;if(i<listSize){str+=options.separator;}
i++;});onAjaxCallSuccess(input,queryUrl,str);});}}
else{onAjaxCallSuccess(input,queryUrl,entries);}}
var positionateHintListContainer=function(input){var offset=input.offset();var container=getHintListContainer(input);var unsortedList=getUnsortedList(input);container.css({'display':'block','position':'absolute'});}
var sortList=function(input,entries){var inputVal=jQuery.trim(input.val());var matrix=new Array();var i=0;jQuery.each(entries,function(){var distance=levenshtein(inputVal,jQuery.trim(this));if(matrix[i]==undefined){matrix[i]=new Array();}
matrix[i]=new Array(distance,jQuery.trim(this));i++;});var swap=function(i,j){if(parseInt(matrix[j])<parseInt(matrix[i])){var temp=matrix[i];matrix[i]=matrix[j]
matrix[j]=temp;if(i>0){swap(i-1,i);}}}
for(var j=0;j<matrix.length-1;j++){swap(j,j+1);}
entries=new Array();for(var j=0;j<matrix.length;j++){var temp=matrix[j];entries.push(temp[1]);}
return entries;}
var matchHint=function(input,entries){var inputVal=jQuery.trim(input.val());var matched=new Array();jQuery.each(entries,function(){var curItem=jQuery.trim(this).toLowerCase();var toMatch=inputVal.toLowerCase();if(options.matchRule==MATCHRULE.STARTS_WITH){if(curItem.match("^"+toMatch)==toMatch){matched.push(jQuery.trim(this));}}
else if(options.matchRule==MATCHRULE.ENDS_WITH){if(curItem.match(toMatch+"$")==toMatch){matched.push(jQuery.trim(this));}}
else{if(curItem.match(toMatch)==toMatch){matched.push(jQuery.trim(this));}}});return matched;}
var createList=function(input,html){var divContainer=getHintListContainer(input);if(divContainer.get()==''){divContainer=jQuery('<div></div>').addClass(options.hintboxContainerClass).css({'margin':0,'padding':0,'display':'none','z-index':100});}
else{divContainer.empty();}
var ul=jQuery('<ul></ul>').css({'cursor':'default'});var entries=jQuery.trim(html).split(options.separator);if(options.matchHint){entries=matchHint(input,entries);}
if(options.sort){entries=sortList(input,entries);}
if(options.limit>0){entries=entries.slice(0,options.limit);}
jQuery.each(entries,function(){ul.append(jQuery('<li></li>').text(jQuery.trim(this)));});divContainer.append(ul);input.after(divContainer);positionateHintListContainer(input);divContainer.slideDown(options.slideDownTime);}
var applyOptions=function(input){var unsortedList=getUnsortedList(input);if(unsortedList.find('li').length>0){if(options.autoDimentions){var blw=parseInt(input.css('border-left-width'));var brw=parseInt(input.css('border-right-width'));var w=input.outerWidth();options.width=(w-blw-brw)+'px';unsortedList.find('li').css({'line-height':input.outerHeight()+'px'});}
unsortedList.css({'width':options.width,'overflow-x':'hidden'});}
else{unsortedList.remove();}}
var closeHintResults=function(input){unbindKeyboard();var container=getHintListContainer(input);container.slideUp(options.slideUpTime,function(){jQuery(this).remove();});}
var highlight=function(input){var unsotedList=getUnsortedList(input);var cssBackup=jQuery.data(input,'cssBackup');unsotedList.find('li').hover(function(){deselectLi(unsotedList.find('.selected'),cssBackup);selectLi(jQuery(this));},function(){deselectLi(jQuery(this),cssBackup);});}
var selectLi=function(li){li.addClass('selected');}
var deselectLi=function(li,cssBackup){li.removeClass('selected');}
var fixIssues=function(input){if(!jQuery.support.boxModel){getUnsortedList(input).css({'width':(parseInt(options.width)+parseInt(input.css('border-left-width'))*2)+'px'}).find('li').css({'width':(parseInt(options.width)+parseInt(input.css('border-left-width'))*2)+'px'});}}
jQuery(inputs).each(function(){var input=jQuery(this);if(!input.hasClass(options.inputClass)){input.addClass(options.inputClass);}
init(input);input.click(function(){rebindKeyboard(input);});input.focus(function(){rebindKeyboard(input);});input.blur(function(){rebindKeyboard(input);});});return inputs;};})(jQuery);
