(function($){$.fn.tokenInput=function(url,options){var settings=$.extend({url:url,hintText:options.hintText,noResultsText:"No results",searchingText:"Searching...",searchDelay:600,minChars:1,tokenLimit:null,jsonContainer:null,method:"GET",contentType:"json",queryParam:"name",ajaxCallbackFunction:null,onResult:null},options);settings.classes=$.extend({tokenList:"token-input-list",token:"token-input-token",tokenDelete:"token-input-delete-token",selectedToken:"token-input-selected-token",highlightedToken:"token-input-highlighted-token",dropdown:"token-input-dropdown",dropdownItem:"token-input-dropdown-item",dropdownItem2:"token-input-dropdown-item2",selectedDropdownItem:"token-input-selected-dropdown-item",inputToken:"token-input-input-token"},options.classes);return this.each(function(){var list=new $.TokenList(this,settings);});};$.TokenList=function(input,settings){var POSITION={BEFORE:0,AFTER:1,END:2};var KEY={BACKSPACE:8,TAB:9,RETURN:13,ESC:27,LEFT:37,UP:38,RIGHT:39,DOWN:40,COMMA:188};var saved_tokens=[];var token_count=0;var cache=new $.TokenList.Cache();var timeout;var input_box=$("<input type=\"text\" class='token-input-box'>").css({outline:"none"}).focus(function(){if(settings.tokenLimit==null||settings.tokenLimit!=token_count){show_dropdown_hint();}}).blur(function(){hide_dropdown();}).bind("keydown text",function(event){var previous_token;var next_token;switch(event.keyCode){case KEY.LEFT:case KEY.RIGHT:case KEY.UP:case KEY.DOWN:if(!$(this).val()){previous_token=input_token.prev();next_token=input_token.next();if((previous_token.length&&previous_token.get(0)===selected_token)||(next_token.length&&next_token.get(0)===selected_token)){if(event.keyCode==KEY.LEFT||event.keyCode==KEY.UP){deselect_token($(selected_token),POSITION.BEFORE);}else{deselect_token($(selected_token),POSITION.AFTER);}}else if((event.keyCode==KEY.LEFT||event.keyCode==KEY.UP)&&previous_token.length){select_token($(previous_token.get(0)));}else if((event.keyCode==KEY.RIGHT||event.keyCode==KEY.DOWN)&&next_token.length){select_token($(next_token.get(0)));}}else{var dropdown_item=null;if(event.keyCode==KEY.DOWN||event.keyCode==KEY.RIGHT){dropdown_item=$(selected_dropdown_item).next();}else{dropdown_item=$(selected_dropdown_item).prev();}
if(dropdown_item.length){select_dropdown_item(dropdown_item);}
return false;}
break;case KEY.BACKSPACE:previous_token=input_token.prev();if(!$(this).val().length){if(selected_token){delete_token($(selected_token));}else if(previous_token.length){select_token($(previous_token.get(0)));}
return false;}else if($(this).val().length==1){hide_dropdown();}else{setTimeout(function(){do_search(false);},5);}
break;case KEY.TAB:case KEY.RETURN:case KEY.COMMA:if(selected_dropdown_item){add_token($(selected_dropdown_item));return false;}
break;case KEY.ESC:hide_dropdown();return true;default:if(is_printable_character(event.keyCode)){setTimeout(function(){do_search(false);},5);}
break;}});var hidden_input=$(input).hide().focus(function(){input_box.focus();}).blur(function(){input_box.blur();});var selected_token=null;var selected_dropdown_item=null;var token_list=$("<ul />").addClass(settings.classes.tokenList).insertAfter(hidden_input).click(function(event){var li=get_element_from_event(event,"li");if(li&&li.get(0)!=input_token.get(0)){toggle_select_token(li);return false;}else{input_box.focus();if(selected_token){deselect_token($(selected_token),POSITION.END);}}}).mouseover(function(event){var li=get_element_from_event(event,"li");if(li&&selected_token!==this){li.addClass(settings.classes.highlightedToken);}}).mouseout(function(event){var li=get_element_from_event(event,"li");if(li&&selected_token!==this){li.removeClass(settings.classes.highlightedToken);}}).mousedown(function(event){var li=get_element_from_event(event,"li");if(li){return false;}});var dropdown=$("<div>").addClass(settings.classes.dropdown).insertAfter(token_list).hide();var input_token=$("<li />").addClass(settings.classes.inputToken).appendTo(token_list).append(input_box);init_list();function init_list(){hidden_input.val('');li_data=settings.prePopulate;if(li_data&&li_data.length){for(var i in li_data){if(li_data[i].id){var this_token=$("<li><p>"+li_data[i].name+"</p> </li>").addClass(settings.classes.token).insertBefore(input_token);$("<span>x</span>").addClass(settings.classes.tokenDelete).appendTo(this_token).click(function(){delete_token($(this).parent());return false;});$.data(this_token.get(0),"tokeninput",{"id":li_data[i].id,"name":li_data[i].name});input_box.val("").focus();hide_dropdown();var id_string=li_data[i].id;if(hidden_input.val()){id_string=','+ id_string;}
hidden_input.val(hidden_input.val()+ id_string);}}}}
function is_printable_character(keycode){if((keycode>=48&&keycode<=90)||(keycode>=96&&keycode<=111)||(keycode>=186&&keycode<=192)||(keycode>=219&&keycode<=222)){return true;}else{return false;}}
function get_element_from_event(event,element_type){var target=$(event.target);var element=null;if(target.is(element_type)){element=target;}else if(target.parent(element_type).length){element=target.parent(element_type+":first");}
return element;}
function insert_token(id,value){var this_token=$("<li><p>"+ value+"</p> </li>").addClass(settings.classes.token).insertBefore(input_token);$("<span>x</span>").addClass(settings.classes.tokenDelete).appendTo(this_token).click(function(){delete_token($(this).parent());return false;});$.data(this_token.get(0),"tokeninput",{"id":id,"name":value});return this_token;}
function add_token(item){var li_data=$.data(item.get(0),"tokeninput");var this_token=insert_token(li_data.id,li_data.name);input_box.val("").focus();hide_dropdown();var id_string=li_data.id;if(settings.ajaxCallbackFunction!=null){eval(settings.ajaxCallbackFunction+'( "select", id_string )')}
if(hidden_input.val()){id_string=','+ id_string;}
hidden_input.val(hidden_input.val()+ id_string);token_count++;if(settings.tokenLimit!=null&&settings.tokenLimit>=token_count){input_box.hide();hide_dropdown();}}
function select_token(token){token.addClass(settings.classes.selectedToken);selected_token=token.get(0);input_box.val("");hide_dropdown();}
function deselect_token(token,position){token.removeClass(settings.classes.selectedToken);selected_token=null;if(position==POSITION.BEFORE){input_token.insertBefore(token);}else if(position==POSITION.AFTER){input_token.insertAfter(token);}else{input_token.appendTo(token_list);}
input_box.focus();}
function toggle_select_token(token){if(selected_token==token.get(0)){deselect_token(token,POSITION.END);}else{if(selected_token){deselect_token($(selected_token),POSITION.END);}
select_token(token);}}
function delete_token(token){var token_data=$.data(token.get(0),"tokeninput");if(settings.ajaxCallbackFunction!=null){eval(settings.ajaxCallbackFunction+'( "delete", token_data.id )')}
token.remove();selected_token=null;input_box.focus();var str=hidden_input.val()
var resultantTokenStr='';if(str.indexOf(',')!=-1){var deleteTokenStr=','+ token_data.id;if(str.indexOf(token_data.id)==0){deleteTokenStr=token_data.id+',';}
var start=str.indexOf(deleteTokenStr);var end=start+ deleteTokenStr.length;resultantTokenStr=str.slice(0,start)+ str.slice(end,str.length);}
hidden_input.val(resultantTokenStr);token_count--;if(settings.tokenLimit!=null){input_box.show().val("").focus();}}
function hide_dropdown(){setTimeout(function(){dropdown.hide().empty();selected_dropdown_item=null;},300);}
function show_dropdown_searching(){dropdown.html("<p>"+settings.searchingText+"</p>").show();}
function show_dropdown_hint(){dropdown.html("<p>"+settings.hintText+"</p>").show();}
function highlight_term(value,term){return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+ term+")(?![^<>]*>)(?![^&;]+;)","gi"),"<b>$1</b>");}
function populate_dropdown(query,results){if(results.length){dropdown.empty();var dropdown_ul=$("<ul>").appendTo(dropdown).mouseover(function(event){select_dropdown_item(get_element_from_event(event,"li"));}).click(function(event){add_token(get_element_from_event(event,"li"));}).mousedown(function(event){return false;}).hide();for(var i in results){if(results.hasOwnProperty(i)){var this_li=$("<li>"+highlight_term(results[i].name,query)+"</li>").appendTo(dropdown_ul);if(i%2){this_li.addClass(settings.classes.dropdownItem);}else{this_li.addClass(settings.classes.dropdownItem2);}
if(i==0){select_dropdown_item(this_li);}
$.data(this_li.get(0),"tokeninput",{"id":results[i].id,"name":results[i].name});}}
dropdown.show();dropdown_ul.slideDown("fast");}else{dropdown.html("<p>"+settings.noResultsText+"</p>").show();}}
function select_dropdown_item(item){if(item){if(selected_dropdown_item){deselect_dropdown_item($(selected_dropdown_item));}
item.addClass(settings.classes.selectedDropdownItem);selected_dropdown_item=item.get(0);}}
function deselect_dropdown_item(item){item.removeClass(settings.classes.selectedDropdownItem);selected_dropdown_item=null;}
function do_search(immediate){var query=input_box.val().toLowerCase();if(query&&query.length){if(selected_token){deselect_token($(selected_token),POSITION.AFTER);}
if(query.length>=settings.minChars){show_dropdown_searching();if(immediate){run_search(query);}else{clearTimeout(timeout);timeout=setTimeout(function(){run_search(query);},settings.searchDelay);}}else{hide_dropdown();}}}
function run_search(query){var cached_results=cache.get(query);if(cached_results){populate_dropdown(query,cached_results);}else{var queryStringDelimiter=settings.url.indexOf("?")<0?"?":"&";var callback=function(results){if($.isFunction(settings.onResult)){results=settings.onResult.call(this,results);}
cache.add(query,settings.jsonContainer?results[settings.jsonContainer]:results);populate_dropdown(query,settings.jsonContainer?results[settings.jsonContainer]:results);};if(settings.method=="POST"){$.post(settings.url+ queryStringDelimiter+ settings.queryParam+"="+ query,{},callback,settings.contentType);}else{$.get(settings.url+ queryStringDelimiter+ settings.queryParam+"="+ query,{},callback,settings.contentType);}}}};$.TokenList.Cache=function(options){var settings=$.extend({max_size:50},options);var data={};var size=0;var flush=function(){data={};size=0;};this.add=function(query,results){if(size>settings.max_size){flush();}
if(!data[query]){size++;}
data[query]=results;};this.get=function(query){return data[query];};};})(jQuery);
