jQuery.fn.log = function (msg) {
    console.log("%s: %o", msg, this);
    return this;
};


(function($){  
 $.fn.displaylist = function(options) {    
  
 var defaults = {
    waitHTML : '<img class="wait right" src="/@@/ztm.topiclisting/icon/loader.gif" alt="">'
  };  
  
  var options = $.extend(defaults, options);      
  return this.each(function() {
    var displaylistId = Math.floor(Math.random()*100)
    var STATUS_AUTOMATIC = 1;
    var STATUS_LOCKED = 2;
    var STATUS_EMPTY = 3;
    var MSG_ERROR_INSERT = "Could not lock the slot to this position due to an server error.";
    var MSG_ERROR_RELEASE = "Could not release the slot due to an server error";
    var LBL_LOCK_DESCRIPTION = "Please confirm that you want to lock the topic to this slot"
    var LBL_RELEASE_DESCRIPTION = "Please confirm that you want to release the topic from this slot."
    
    var $displaylist = $(this);   
 
    var initTabs = function(container){
      $('.tabs > ul', container).tabs({selected: null, event: 'click', fx: [null, { height: 'show', opacity: 'show' }]});
    }
    
    var insert =  function(event){      
      event.stopPropagation();
      event.preventDefault();     

      var $this = $(this);            
      var data = event.data
      
      //serial is either given by the element invoking the action or the current in the list slot
      var $slot = $($this.parents('li.slot, li.insert').eq(0));      
      var slotSerial = $slot.attr('ztm:serial');       
      var selectedSerial = $this.attr('ztm:serial') || slotSerial;
      
      //slotFilter says whether we are in an insert-slot or an filled-slot
      var slotFilter = $slot.hasClass("slot") && "slot" || "insert";
      
      if (slotFilter == "insert"){
        setWaitState($slot.next());        
        $slot.trigger("mouseleave", "rebuild");        
      }else{
        setWaitState($slot);
      }
      
      //position is deferred based on the slotfilter.
      var request = {   operation: 'position'
                  , position: $('li.'+slotFilter, $displaylist).index($slot)
                  , serial: selectedSerial
                  };
      
      //position the slot
      $.ajax({
        type: "POST",
        url: window.location.href.replace(window.location.hash,"").replace("#",""),
        data: JSON.stringify(request),
        dataType: "json",
        contentType: 'application/json',
        success: function(slots){
          //state of the entire list is returned. Rebuild it.          
          rebuild(slots);          
          if(typeof(data) != "undefined" && data.tool == "search"){
            //select detail tab, disable search tab             
            $('.tabs > ul', $slot)
              .tabs('select',0)           
              .tabs('disable',1);
          }
          //Remove wait state
          if (slotFilter == "insert"){
            removeWaitState($slot.next());
          }else{
            removeWaitState($slot);
          }      
        },
        error:function(XMLHttpRequest, textStatus, errorThrown){
          humanMsg.displayMsg(MSG_ERROR_INSERT);
          if (slotFilter == "insert"){
            removeWaitState($slot.next());
          }else{
            removeWaitState($slot);
          }     
        }
      });
    }    
    var setLockedState = function($slot){
      //Mark slot as locked
      $slot.addClass("locked");
        
      //change lock slot button to release button
      $(".action_lock", $slot)
        .removeClass("action_lock")
        .addClass("action_release")
        .unbind('click')
        .bind('click', {tool:'release'} ,release)
        .removeAttr("disabled");
      //Change status icon of slot
      $(".status", $slot)
        .hide()
        .removeClass("automatic")
        .removeClass("emptyslot")
        .addClass("lock")
        .html("<span>Locked</span>")
        .fadeIn(250);      
      //Change text of lock/unlock-tab
      $(".tabs .lock", $slot)
        .removeClass("lock")
        .addClass("automatic")
        .find("span")
        .html("Unlock slot");
      //disable search tab 
      $('.tabs > ul', $slot)
        //enable details tab
        .tabs('enable', 0)
        //disable search and lock tab
        .tabs('disable',1)
        //enable unlock tab
        .tabs('enable',2)
        //enable rearrange tab        
        .tabs('enable',3);
      //Change help-text for the lock/unlock pane
      $(".action_lock_description", $slot)
        .html(LBL_RELEASE_DESCRIPTION);
      //Enable the previous insert slot
      $slot
        .prev()
          .droppable("enable")
          .unbind("click")
          .bind("click", buildInsertSlot)
          .removeClass("notallowed")          
          .html('<a class="smallicon add" href="#">Click to insert a new slot</a>')
          .show()
          .end()
        .next()
          .droppable("enable");
    }
    var setReleasedState = function($slot){
      //remove locked slot mark
      $slot.removeClass("locked");
      //change release slot button to lock button
      $(".action_release", $slot)
        .removeClass("action_release")
        .addClass("action_lock")
        .unbind('click')
        .bind('click', {tool:'insert'} ,insert);
     //Change status icon of slot
      $(".lock", $slot)
        .hide()
        .removeClass("lock")
        .addClass("automatic")
        .html("Automatic")
        .fadeIn(250);
      //Change text of lock/unlock-tab
      //HACK, sometimes this flap gets the class auto instead of automatic, for some reason...
      $(".tabs .auto", $slot)
        .removeClass("auto")
        .addClass("lock")
        .html("<span>Lock slot</span>");
      //normal
      $(".tabs .automatic", $slot)
        .removeClass("automatic")
        .addClass("lock")
        .html("<span>Lock slot</span>");
      //Change help-text for the lock/unlock pane
      $(".action_lock_description", $slot)
        .html(LBL_LOCK_DESCRIPTION);
      //Enable the previous insert slot
      $slot
        .prev()
          .droppable("enable")
          .unbind("click")
          .bind("click", buildInsertSlot)
          .removeClass("notallowed")          
          .html('<a class="smallicon add" href="#">Click to insert a new slot</a>')
          .show()
          .end()
        .next()
          .droppable("enable");
          
      //enable search tab
      $('.tabs > ul', $slot)
        .tabs('enable',1)
      //enable rearrange tab      
        .tabs('enable',3);            
    }
    
    //function that gives slot status
    var slotstatus = function($slot){
      var status = $(".status", $slot);
      if(status.hasClass("automatic")){
        return STATUS_AUTOMATIC; 
      }
      else if(status.hasClass("lock")){
        return STATUS_LOCKED;
      }
      else if(status.hasClass("empty")){
        return STATUS_EMPTY;
      }      
    }
    //utility methods in order to determine slot status
    var isLocked = function($slot){
      return (slotstatus($slot) == STATUS_LOCKED);        
    }
    var isAutomatic = function ($slot){
      return (slotstatus($slot) == STATUS_AUTOMATIC);
    }
    var isEmpty = function($slot){
      return (slotstatus($slot) == STATUS_EMPTY);      
    }
    
    //releases a locked slot
    var release = function(event){      
      event.stopPropagation();
      event.preventDefault();          
      var $this = $(this);
      var $slot = $($this.parents('li.slot').eq(0));
      setWaitState($slot);      
      var slotSerial = $slot.attr('ztm:serial');      
      var request = {   
                        operation: 'release'                      
                      , serial: slotSerial
                    };      
      $.ajax({
        async:true,
        type: "POST",
        url: window.location.href.replace(window.location.hash,"").replace("#", ""),
        data: JSON.stringify(request),
        dataType: "json",
        contentType: 'application/json',
        success: function(slots){                    
          setReleasedState($slot);
          removeWaitState($slot);          
          rebuild(slots);
        },
        error:function(XMLHttpRequest, textStatus, errorThrown){
          humanMsg.displayMsg(MSG_ERROR_RELEASE);
          removeWaitState($slot);
        }
      });
            
    }
    //sets wait staus on the slot. status icon is "replaced" by twirling wait-icon
    var setWaitState = function($slot){      
      $(".status", $slot).hide().after($(options.waitHTML))
    }
    //Removes twirling wait-icon and displays status
    var removeWaitState = function ($slot){
      $(".wait", $slot).remove();
      $(".status", $slot).show();
    }
    
    //rebuilds all slots by the given status.    
    var rebuild = function (slots){
      var listItems = $("li.slot", $displaylist)
      for (var i=0,ilength=slots.length; i<ilength; i++){
        var slot = slots[i];
        var listItem = $(listItems[i]);
        var currentSerial = listItem.attr("ztm:serial");              
        
        if(!slot.empty){
          //set slot details          
          $("h2 span.title", listItem).html(slot.topic.name);
          listItem
            //.removeClass("empty")
            //.removeClass("locked")            
            .attr("ztm:serial", slot.topic.stringserial);        
          //$(".fullname", listItem).html(slot.topic.fullname);
          //$(".serial", listItem).html(slot.topic.stringserial);
          $(".url", listItem).attr("href", slot.topic.url).html(slot.topic.fullname);
          
          var edit = $(".edit", listItem);
          if(slot.topic.editable){                        
            if(edit.length == 0){
              $(".url", listItem).after($('<a class="smallicon edit" href="'+ slot.topic.url +'/@@uib-wizard">Go to wizard</a>'))
            }
            else{
              edit.attr("href", slot.topic.url+"/@@uib-wizard").show();
            }            
          }          
          else{
            edit.hide();
          }

          $(".description", listItem).html(slot.topic.description);          
          $(".typenames", listItem).html("(Type: "+slot.topic.typenames+")");          
        }      
        //empty slot        
        else{
          $("h2 span.title", listItem).html("");
          $(".typenames", listItem).html("");
          listItem
            .attr("ztm:serial", "")
	    .removeClass("locked")
            .addClass("empty")
            .prev()
              .droppable("enable")
              .unbind("click")
              .html('')
          ;
          $('.tabs > ul', listItem)
            .tabs('select',1)
            //details            
            .tabs('disable',0)
            //search and lock
            .tabs('enable',1)
            //lock/unlock
            .tabs('disable',2)
            //rearrange
            .tabs('enable',3)
            $(".status", listItem).removeClass("automatic").addClass("emptyslot").html("Empty");            
        }
        if(slot.pinned){
          listItem
            .attr("ztm:serial", slot.topic.stringserial)
            .removeClass("empty")
            setLockedState(listItem);
        }
        //release slots which are set locked but are automatic
	if (slot.automatic == 1 && listItem.hasClass("locked")){
	  setReleasedState(listItem);
	}

	//close all slots after action...
	if (listItem.hasClass("expanded")){
	  listItem.removeClass("expanded");
	  $(".tabs", listItem).slideUp(0);
	}	  

        $(".wait", listItem).remove();                        
      }
    }      
    //invoked when an insert slot is clicked
    var buildInsertSlot = function(event){            
      event.stopPropagation();
      event.preventDefault();      
      var $this = $(this);      
      //Give the user a preview of how the new list will look like by moving all slots one position down.
      //must considerate locked slots that are not going to be moved.
            
      //get all locked slots
      $this.nextAll("li.locked.slot").each(function(){              
          var $this = $(this);
          //get the slot that will be moved below the locked slot. We skip the insert slot.
          var skipper = $(this).prev().prev();          
          if(!isLocked(skipper)){            
            //clone slot and move it below the locked slot. Then hide it.
            var skipperClone = skipper.clone();            
            var insertElement = skipper.hide().prev();            
            var insertElementClone = insertElement.clone();                          
            insertElement.hide();            
            $(skipper).nextAll("li.locked.slot:first").after(skipperClone.addClass("clone"));
            insertElementClone.addClass("clone");            
            skipperClone.before(insertElementClone);           
          }
      })
      
      //remove hovering 
      $this
        .unbind('mouseenter')
        .unbind('mouseout')
        .unbind('mouseleave')
        .unbind('click')
        .fadeOut(250, function(){
          //change opacity of filled elements in list so the user focuses on the insert-form
          $("li.slot", $displaylist)
            .fadeTo(0, 0.5);          
          //the last slot will disappear from the list, indicate this by giving it low opacity.
          $("li.slot:last", $displaylist)
            .fadeTo(0, 0.1);
          $this
            //create the searchform
            .searchform({onSelect : insert})            
            .addClass("enabled")
            .fadeIn(100);        
          var currentNumber = parseInt($('li.insert', $displaylist).index($this))+1;
          $("span.number", $this).text(currentNumber);
          //change the numbering on all elements below to complete the preview-mode
          $this.nextAll("li.slot").each(function(){              
            var $this = $(this);
            if(!isLocked($this)){
              var numberContainer = $("span.number", $this);              
              var value = numberContainer.html();
              value = parseInt(value)+1;                
              numberContainer.html(value);       
            }                                   
          })
        });
        
        //mouse moves away from the clicked insert slot. This cancels it
        
        $this.bind("mouseleave", function(event, data){            
            //remove all cloned nodes
            $("li.clone", $displaylist).remove();
            //display original nodes
            $(this).nextAll("li.locked").each(function(){
                var $this = $(this);
                var skipper = $(this).prev().prev();    
                if(!isLocked(skipper)){
                  var insertElement = skipper.show().prev();
                  insertElement.show();
                  
                }          
            })
            
            $this              
              .unbind("mouseleave")
              .unbind("mouseout")
              //Recreate the insert slot again
              .fadeOut(250, function(){
                  $this
                    .removeClass("enabled")                    
                    //TODO: potential memory leaks              
                  $(".searchform", $this).remove();                  
                  $this                          
                    .show()
                    .fadeTo(0, 0.25)
                    .bind('click', buildInsertSlot)             
                    .hover(function(){        
                        $(this).fadeTo(40,1).addClass("hover");        
                    }, 
                    function(){        
                      $(this).fadeTo(0, 0.25).removeClass("hover");
                    }) 
                    if(data != "rebuild"){
                      $this.html('<a class="smallicon add" href="#">Click to insert a new slot</a>').html('<a class="smallicon add" href="#">Click to insert a new slot</a>')
                    }
                    $("li.slot", $displaylist).fadeTo(0, 1);
            });
            //change back to original numbering
            $this.nextAll("li.slot").each(function(){
              var $this = $(this);
              if(!isLocked($this)){
                var numberContainer = $("span.number", $this);              
                var value = numberContainer.html();              
                value = parseInt(value)-1;
                numberContainer.html(value);
              }              
            })              
          })
    }
    
    
    //Initialization code   
    
    $('> li.slot', this)
      //add insert slots
      .before($('<li class="insert"><a class="smallicon add" href="#">Click to insert a new slot</a></li>'))     
      
      
      $('li.slot', $displaylist)        
        .draggable({ 
          revert: "invalid",
          handle:".action_rearrange",
          axis: "y",
          helper: 'clone',      
          refreshPositions: true, 
          scroll: true,
          scrollSensitivity:30,
          cursorAt: {top:50, left:50},
          start: function(ev, ui){
            //Make empty siblings not droppable
            var $this = $(this);
            ui.helper.addClass("drag");
            $this.prev().addClass('blocked').droppable("disable").html('<a class="smallicon no" href="#">Not possible to insert a slot here</a>');            
            var oldPosition = $("span.number", $this).html();
            $("span.number", $this).html(oldPosition);
            //$("li.slot", $displaylist).fadeTo(0, 0.25)
          },
          stop: function(ev, ui){
            //Make empty siblings droppable again
            var $this = $(this);
            var prev = $this.prev();
            var next = $this.next();
            ui.helper.removeClass("drag");
            prev.removeClass('blocked').droppable("enable").html('<a class="smallicon add" href="#">Click to insert a new slot</a>');                       
          }
        })    
        .bind('click', function(event){            
            //event.stopPropagation();
            //event.preventDefault();
            var $this = $(this);
            $(".tabs", $this).slideDown(800, function(){
                $this.addClass("expanded");
            });
            
        })
        .bind('mouseleave', function(event){
            //var $this = $(this);
            //$(".tabs", $this).slideUp(0);
            //initTabs($this);      
        })        
        .hover(
          function(){
            var $this = $(this);
            $this.addClass("hover");
            $('.expand', $this).removeClass("hidden");
          },
          function(){
            var $this = $(this);
            $this.removeClass("hover");
            $('.expand', $this).addClass("hidden");
          })  
        .find(".confirm.action_release")
          .bind('click', release)   
          .end()
        .find(".confirm.action_lock")
          .bind('click', insert)
          .end()
        .find(".searchtool").searchform({onSelect : insert});
        
      $('li.insert', $displaylist)
        .bind('click', buildInsertSlot )      
        .fadeTo(0, 0.25)
        .hover(function(){        
            $(this).stop().fadeTo(40,1).addClass("hover");        
        }, 
        function(){        
          $(this).stop().fadeTo(0, 0.25).removeClass("hover");
        })      
        .filter("li.insert:not(.notallowed)").droppable({ 
          accept: "li.slot",
          tolerance: "intersect", 
          drop: function(ev, ui) { 
              var $dropTarget = $(this);              
              var $dropped =  $(ui.draggable);                          
              var selectedSerial = $dropped.attr('ztm:serial');
              var $slot = $dropTarget.next();      
              var slotSerial = $slot.attr('ztm:serial');      
              $dropTarget.removeClass("accept");              
              setWaitState($slot);
              var newPosition = $('li.insert', $displaylist).index($dropTarget);
              var oldPosition = $('li.slot', $displaylist).index($dropped);
              var request = { operation: 'position'
                        , oldPosition: oldPosition
                        , position: newPosition
                        , serial: selectedSerial
              };
              $.ajax({
                  type: "POST",
                  url: window.location.href.replace(window.location.hash,"").replace("#",""),
                  data: JSON.stringify(request),
                  dataType: "json",
                  contentType: 'application/json',
                  success: function(slots){                    
                    //$(".slot", $displaylist).filter(function(){return $(".status.automatic", this).length}).each(rebuild);
                    rebuild(slots);
                    removeWaitState($slot);
                  },
                  error:function(XMLHttpRequest, textStatus, errorThrown){
                    humanMsg.displayMsg(MSG_ERROR_INSERT);
                    removeWaitState($slot);
                  }
              });              
          },          
          over: function(ev, ui){
            $(ui.element).addClass("accept");
            var position = $('li.insert', $displaylist).index(ui.element)+1;
            var oldPosition = $("span.number", ui.draggable).html();            
            $("span.number", ui.helper).html(position);
            ui.helper.addClass("accept");            
          },          
          out: function(ev, ui){                
            
            $(ui.element).removeClass("accept");
            ui.helper.removeClass("accept");
            var oldPosition = $("span.number", ui.draggable).html();
            $("span.number", ui.helper).html(oldPosition);
          }
      }).end()
           
      
      var buildConfigurationForm = function(){
        var markup =  '<div class="displaylist_configuration">' +                        
                        '<form name="" action="" method="post">' +
                          '<div>'+
                            '<label for="title_$id">Title</label>' +
                            '<input class="title" id="title_$id" type="text" name="title">' +
                            '<div class="checkboxcontainer">' +
                              '<input id="automatic_$id" type="checkbox" name="listing.automaticonly:bool"><label for="automatic_$id">Automatic only</label>' +
                            '</div>' +
                            '<div class="topictypes checkboxcontainer">' +                                                    
                              '<h3>Searchable topic types:</h3>' +                           
                            '</div>' +
                            '<div class="checkboxcontainer">' +
                              '<input name="listing.reverse:bool" type="checkbox" id="reverse_$id"><label for="reverse_$id">Reverse?</label>' +
                            '</div>' +
                            '<label for="listingsize_$id">Number of slots</label>' +
                            '<input id="listingsize_$id" name="listing.size:int" type="text">' +
                            '<label for="sort_$id">Sort by</label>' +
                            '<select id="sort_$id" name="sort"><option value="date">Date</option><option value="title">Title</option></select><br><br>' +                        
                            '<input type="submit" value="Save">'+
                          '</div>' +
                        '</form>' +
                      '<div>'
                                  
        
        
        markup = markup.replace("_$id", displaylistId, "gi");
        
        var $configurationForm = $(markup);
        $displaylist.before($configurationForm);
        
        // set correct values that is configured for the list
        var request = { operation: 'configuration'};
        
        $.ajax({
              type: "GET",
              url: window.location.href.replace(window.location.hash,"").replace("#",""),
              data: request,
              dataType: "json",
              contentType: 'application/json',
              success: function(data){
                //TODO: should probably check out some of the js template libraries for this
                //set retrived values in the configuration form                
                $("[name=title]", $configurationForm).val(data.title);
                $("[value="+data['query.sort']+"]", $configurationForm).attr("selected", true);
                $("[name=listing.size:int]", $configurationForm).attr("value", data['listing.size']);
                if(data['query.reverse'] === true){
                  $("[name=listing.reverse:bool]", $configurationForm).attr("checked", true)              
                }
                if(data['listing.automaticonly'] === true){
                  $("[name=listing.automaticonly:bool]", $configurationForm).attr("checked", true)              
                }                                
                var $topictypes = $(".topictypes", $configurationForm);                
                for (i in data['topictypes']){
                  var topictype = data['topictypes'][i]
                  //console.log(typeof topictype.selected)
                  checked = topictype.selected ? 'checked' : '';                  
                  $topictypes.append($('<input '+checked+' id="serial_'+topictype.stringserial+'" name="topictype" type="checkbox" value="'+ topictype.psi +'"><label for="serial_'+topictype.stringserial+'">'+topictype.fullname+'</label><br>'))
                }                                
              },
              error: function(){               
               
              }
          })
        
        
        // TODO: make the title more connected to the displaylist
        $title = $("#listings h1:first");
        $titleinput = $("[name=title]", $configurationForm)//.val($title.text())       
        
       
        $(":submit", $configurationForm).bind('click', function(event){            
            event.stopPropagation();
            event.preventDefault(); 
            
            // save configuration
            topictypes = []
            $("[name=topictype]:checked", $configurationForm).each(function(){
                topictypes.push($(this).val())
            })
            
                       
            var request = {   operation: 'configure',
                              'title': $titleinput.val(),
                              'listing.automaticonly' : $("[name=listing.automaticonly:bool]:checked", $configurationForm).length == 0 ? false : true,
                              'listing.size': parseInt($("[name=listing.size:int]", $configurationForm).val()),
                              'query.reverse' : $("[name=listing.reverse:bool]:checked", $configurationForm).length == 0 ? false : true,
                              'query.sort' : $("option:selected", $("[name=sort]")).val(),
                              'listing.topictypes' : topictypes
            }; 
            
            
            $.ajax({
              type: "POST",
              url: window.location.href.replace(window.location.hash,"").replace("#",""),
              data: JSON.stringify(request),
              dataType: "json",
              contentType: 'application/json',
              success: function(slots){         
                //do a refresh of the page. Displaylist is not ready for handling changes in configuraton on the fly
                window.location.href = window.location.href;
              },
              error: function(){               
                humanMsg.displayMsg("An error occured and you were not able to save the new title");
              }
            });
            
          });
               
      }
      // Initalization
      
      $('<a href="" class="show_configuration">&raquo; Show configuration form</a>')
        .toggle(function(){
            var dc = $('.displaylist_configuration');
            if(dc.length == 0){
              buildConfigurationForm();
            }            
            else{              
              dc.show();                         
            } 
            $(this).html("&raquo; Hide configuration form");
            //TODO: make h1 part of displaylist
            $('h1').hide();
            $displaylist.hide();
          }
          , function(){
            //TODO: make h1 part of displaylist
            $('h1').show();
            var dc = $('.displaylist_configuration');
            dc.hide();
            $(this).html("&raquo; Show configuration form");
            $displaylist.show();
          }).insertBefore($displaylist);
       
        
      
      
      
      initTabs(this);
      
      $("li.empty.slot", $displaylist).each(function(){     
          var $this = $(this);
          $('.tabs > ul', $this)
          //disable detail tab
          .tabs('disable', 0)
          //disable lock/unlock tab
          .tabs('disable', 2)
          //enable rearrange tab
          .tabs('enable', 3);
          $this
            .prev()
              .droppable("enable")
              .unbind("click")
              .html('')
      })      
      $(".slot .contract", $displaylist).bind('click', function(event){
          event.stopPropagation();
          event.preventDefault();
              
          var $this = $(this);
          var $slot = $this.parents('.slot');
          $slot.removeClass('expanded');
          $(".tabs", $slot).slideUp(0, function(){
        
          });          
      });
      $("li.locked.slot", $displaylist).each(function(){
        var $this = $(this);
        setLockedState($this);        
      });
      
      
     
    

  });  
 };  
})(jQuery); 

(function($){  
 $.fn.searchform = function(options) {  
  
  var rand_no = Math.ceil(100*Math.random())
  var defaults = {
    html : '<form method="get" action="" class="searchform"><div class="searchinput"><h2><label for="query_'+rand_no+'">Find new topic</label></h2><input type="text" class="query" id="query_'+rand_no+'" name="query"><input type="submit" value="Find topics"><img class="wait" src="/@@/ztm.topiclisting/icon/loader.gif" alt=""><br/><input id="areasearchon" checked name="areasearch" type="radio" value="on"> Limit search to area<br/><input id="areasearchoff" name="areasearch" type="radio" value="off"> Search all areas</div><span class="filter_placeholder"></span><div style="clear:both;"></div></form>'
    , onSelect : function(event){
        event.stopPropagation();
        event.preventDefault();              
    }
  };
  if (typeof options == "string") { 
    
  }
  else{
    var options = $.extend(defaults, options);
  } 
  
  return this.each(function(){ 
    var MSG_ERROR_SEARCH = "Could not perform the search due to an server error";
    var search = function (page) {
      var page = page || 0;
      $('input.query, :submit',$form).attr('disabled', 'true');
      $('img.wait',$form).show();
      //generate filter string from all .selected elements in filter-list
      var filter = $('.filter li.selected', $form).map(function (index, element) {return $(element).attr('ztm:serial')})
      
      var areawide = "false";
      if ($('#areasearchon', $form).attr('checked')){
	areawide = "true";
      }
      
      var request = {'areafilter' : areawide 
	            ,'page:int': page
                    , 'query:ustring:utf8': $('input[name=query]', $form).attr('value') || ''
                    , 'sortindex': 'date'
                    , 'reversed:boolean': ''
                    , 'filter': $.makeArray(filter).join(',')
                    };

      $('ol.results li', $form).addClass('disabled');
      window.location.href.replace(window.location.hash,"").replace("#","")
      $.ajax({ 
        type: "GET",
        url: window.location.href.replace(window.location.hash,"").replace("#",""),
        data: request,
        dataType: "json",
        contentType: 'application/json',
        success: function(data){
          $('img.wait',$form).hide();
          $('input.query, :submit',$form).removeAttr( 'disabled' );
          //remove previous results
          $('ol.results', $form).remove()
          var list = $('<ol class="results"></ol>').appendTo($searchinput);
          
          var topics = data.topics;            
          var current = data.current;        
          var pages = data.pages;        
          for( i=0; ilength=topics.length, i<ilength; i++) {
            var topic = data.topics[i];
            var line = $('<li class="newtopic"><a class="topic"></a></li>').appendTo(list);
            line.hover(function(){$(this).addClass("hover")}, function(){$(this).removeClass("hover")})
                .bind('click', {tool:'search'} ,options.onSelect)
                .attr('ztm:serial', topic.stringserial);
            line.find('a').attr('href', topic.url)                        
                          .text(topic.name);                       
          }
          
          //remove pager
          $('.pager', $form).remove();      
          
          var pager = $('<div class="pager"></div>').appendTo($searchinput);
          
          var previous = $('<a href="#" class="prev">Previous</a>').appendTo(pager);
          var prevEnabled = (current > 0);
          if(!prevEnabled){
            previous.addClass("disabled");
          }
          previous.bind('click', function(event){
              if (prevEnabled){
                search(current-1);
              }              
              event.stopPropagation();
              event.preventDefault();
          });          
                
          
          $('<span class="progress">Page '+(parseInt(current)+1)+' of '+(pages)+'</span>').appendTo(pager);                  
          
            var next = $('<a href="#" class="next">Next</a>').appendTo(pager);
            var nextEnabled = (current < pages-1); 
            if(!nextEnabled){
              next.addClass("disabled");
            }
            next.bind('click', function(event){
                if (nextEnabled){
                  search(current+1);   
                }              
                event.stopPropagation();
                event.preventDefault();
            });                              
        },
        error:function(XMLHttpRequest, textStatus, errorThrown){          
          humanMsg.displayMsg(MSG_ERROR_SEARCH);
          $('img.wait',$form).hide();
          $('input.query, :submit',$form).removeAttr( 'disabled' )
        }
      });
    }    
    var $this = $(this);
    $this.addClass("searchEnabled");
    $this.html(options.html);
    //filter list is generated and already present in the template. Find, clone it and make it part of this searchform
    $(".filter_placeholder", $this).replaceWith($("#filter").clone().removeAttr('id'));
    //must do this in a separate operation due to an ie mystery
    $(".filter", $this).show();
    
    $(".filter .all", $form).bind('click', function(event){
      event.stopPropagation();
      event.preventDefault();
      var $this = $(this);
    });    
    var $form = $('form', this).eq(0); 
    var $searchinput = $(".searchinput", $form);
    $(".filter li", $form).bind('click', function(event){
        event.stopPropagation();
        event.preventDefault();        
        $(this).toggleClass("selected");
        //remove selected state for subtypes
        $("li", this).removeClass("selected");
        search();
    });
    $(":submit", this).bind('click', function(event){        
        search()        
        event.stopPropagation();
        event.preventDefault();
    });
    $('input.query', $form).focus();    
  });  
 };  
})(jQuery);


$(document).ready(function(){    
  $("ol.displaylist").displaylist();
})


