(function($) {
   $.fn.extend( {
      advsuggest : function(options) {
         return this.each(function() {        	 
            new $.advsuggestz(this, options)}
         )}
      , configure : function(options) {
         return this.trigger("configure", [options])}
      , load : function() {
         return this.trigger("load")}
      , clear : function() {
         return this.trigger("clear")}
      }
   );
  $.advsuggestz = function(input, options) {
	   
      var tagbox = input; var defaults = {
         field : "tags", url : "jsontags.php", tagsep : ",", enclose : "", max : 10, cache : true, delay : 500, charMin : 1, dblClick : true, postData : null, onRenderItem : function(row) {
            return decodeURIComponent(row.tag)}
         , onSelectItem : function(val) {
            return true}
         , onLoadList : function(filter) {
            return true}
         }; 
      var options = $.extend(defaults, options); 
      
      var input = $(tagbox);

      input.wrap("<div id='"+$(input).attr('id')+"_box' class='advsuggest_box'></div>");
      
      
      //var lkup = $('#'+input.attr('id')+'_box');
      
      
      //$(input).wrap("<div id='dcde_"+$(input).attr('id')+"_box' class='dcde_box'></div>");
      //var lkup = $('#'+'dcde_'+$(input).attr('id')+'_box'); 
      
      //input = $(input);
      //var input = $("#" + options.field); 
      
      var search_started = 0;
      $(input).attr("autocomplete", "off"); 
      
      
      //var lkup = document.createElement("div");
    //$(lkup).attr('id', 'tagbox-lkup').addClass('search_hint_suggest');
      var lkup = $('<div class="search_hint_suggest" id="tagbox-lkup"></div>');

      
      //$(lkup, tagbox).show();      
      input.after(lkup);

      input.wrap("<div class='advsuggest_input_bg tpng'></div>");
      //$('#'+input.attr('id')+'_box').append();
      
      //var lkuplst = document.createElement("span"); $(lkup, tagbox).append(lkuplst); 
      var cursor =- 1; var length = 0; var loading = false; var loaded = false; var cacheLst = null; var inserted = false; 
      
      var hideLkup = function() {
    	 $(lkup, tagbox).empty(); 
         $(lkup, tagbox).hide(); 
         loaded = false; 
         cacheLst = null; 
         inserted = false;
         
         $(document).unbind('click');
      }; 
         
         var insertTag = function(filter, tag) {
           /*
           var cur = input.val();
           var words = tag.split(" ").length;
           var enclose = (words > 1) ? options.enclose.length > 0 ? options.enclose : "" : "";
           cur = cur.replace(eval("/" + filter + "$/i"), enclose + tag + enclose);
           input.val(cur); cursor =- 1;
           */
           $(input).val(tag);           
         	//xmlrpc_search_process(1,0,0);
         }; 
         
         var addItem = function(obj, val, filter, index) {
           var row = val; var val = options.onRenderItem(val, index, length, filter);
           //var li = document.createElement("li");
           var li = $('<li></li>');
           //$().append(li);
           $(li).click(function(e) {
             options.onSelectItem(row);
             //insertTag(filter, val);
             insertTag(filter, $(this).text());
             e.preventDefault();
             hideLkup();
             inserted = true;
             input.focus();
          });

           //lkuplst.appendChild(li);
           $(obj, lkup).append(li);

           var aLink = document.createElement("span");
           /*$(aLink).attr( {
              href : "#"}
           );*/

           $(aLink, tagbox).text(val); $(aLink, tagbox).addClass(index % 2 == 0 ? "td-odd" : "td-even");
             $(aLink, tagbox).html($(aLink, tagbox).text().replace(eval("/(" + filter + ")/gi"), "<em>$1</em>"));
           //li.appendChild(aLink);
           li.append(aLink);
           /*
           $(aLink).click(function(e) {
              options.onSelectItem(row); insertTag(filter, val); e.preventDefault(); hideLkup(); inserted = true; input.focus()}
           )
           */
         }; 
         var loadList = function() {
        	 
	         inserted = false; 
	         var filter = parseFilter(input.val());

	         options.onLoadList(filter); 
	         
	         $(tagbox).empty(); 
	         
	         $.ajax( {
	            type : "POST", 
	            url : options.url, 
	            data : $.extend( {text : encodeURIComponent(filter), max : options.max}, options.postData), 
	            dataType : "json", 
	            cache : options.cache, 
	            success : function(json) {
	        	 
	               $(lkup, tagbox).empty(); 
	               length = json.length; 
	               cacheLst = json; 
	               cursor =- 1; 
	               if (length > 0){
	            	   //var ol = document.createElement("ol");
	            	   var ol = $('<ol></ol>'); 
	            	   $(lkup, tagbox).append(ol);
	               }
	               for(i = 0; i < json.length && i < options.max; i++) {
	                  addItem(ol, json[i], filter, i);
	               }
	               if (json!="" && search_started==0) $(lkup, tagbox).slideDown(); 
	               loading = false; 
	               loaded = true;
	               
	               $(document).bind('click', function(e){ 
	            	  if (e.target && e.target.id != 'tagbox-lkup' && e.target.id != 'search_field' ){
	            		  hideLkup();
	            	  }
	               });
	               
	         	}, 
	         	error : function(XMLHttpRequest, textStatus, errorThrown) {
	               length = 0; cacheLst = null; loading = false; loaded = false}
	         });
         
         };
         
         var parseFilter = function(val) {
         if(options.tagsep.length == 0) {
            return val}
         if(val.indexOf(options.tagsep) >- 1) {
            val = val.substring(val.lastIndexOf(options.tagsep) + 1, val.length)}
         return val}; 
         
         var triggerLoad = function() {
           if(inserted || search_started) {
              return false
           }else{

              var filter = parseFilter(input.val());
              if(filter.length >= options.charMin) {
                 loading = true;

                setTimeout(function() {loadList();},
                 options.delay);
              }else {
                 hideLkup()
              }
           }
         }; 
         $("*", input.form).focus(function(e) {
           //alert($("*", input.form).html()); 
           if(this.id == options.field) {
              //triggerLoad();
             }
           else {
              //hideLkup()
           }
         }
      ); 
         
         input.dblclick(function(e) {
         if(options.dblClick &&!loading) {
            //triggerLoad();
            }
         }
         
      ); 
      
         /*
      $(lkuplst, tagbox).blur(function(e) {
         hideLkup()}
      );
      */
      var handleSpecials = function(e) {
    	  
         var e = e || window.event; var key = e.charCode || e.keyCode; if(!loaded) {
            return true}
         switch(key) {
            case 40 : cursor = ((cursor + 1) < length) ? cursor + 1 : cursor; if(cursor < length) {
               $("li:eq(" + cursor + ")", lkup).addClass("hl"); if((cursor - 1) >- 1) {
                  $("li:eq(" + (cursor - 1) + ")", lkup).removeClass("hl")}
               e.preventDefault();}
            break; 
            case 38 : cursor = (cursor - 1 >= 0) ? cursor - 1 : cursor; if(cursor >= 0) {
               $("li:eq(" + cursor + ")", lkup).addClass("hl"); $("li:eq(" + (cursor + 1) + ")", lkup).removeClass("hl"); e.preventDefault()}
            break; 
            case 13 : if(input[0].type != "textarea") {
               e.preventDefault()}
            if(cursor >= 0 && cursor < length) {
               options.onSelectItem(cacheLst[cursor]); insertTag(parseFilter(input.val()), $("li:eq(" + (cursor) + ")", lkup).text()); e.preventDefault();
              hideLkup()
            }
            break; 
            case 27 : hideLkup(); e.preventDefault(); 
            break
         }
         
      };

    var handleKey = function(e) {
         var e = e || window.event; var key = e.charCode || e.keyCode; 
        /*
         if(key == 13) {
        	 
        	 if ($(input).val() && $(input).val()!='Поиск mp3')
        	 {
        		 search_started = 1;
        		 hideLkup();
        		 //xmlrpc_search_process(1,0,0);
        		 
        	 }
            return true;
         }
      */
         if(key > 48 && key < 123) {
        	 search_started = 0;
         }
         if(key > 8 && key < 46 && key != 32) {
        	 
            return false}
         if(loading == false) {
            triggerLoad()}
         
         //$(lkup, tagbox).show()
         
         };
      $(input).keyup(handleKey);
      $(input).keydown(handleSpecials);

      $(tagbox).bind("configure", function() {
         $.extend(options, arguments[1])}
      ); $(tagbox).bind("load", function() {
         triggerLoad()}
      ); $(tagbox).bind("clear", function() {
         hideLkup()}
      )}
   }
)(jQuery); 

