/**
 * $Id: jquery.liveUpdate.js peter.cyr $
 **/

jQuery.fn.liveUpdate = function(options){
  
  /*
    Plugin
    Plugin can be attached to an element which has a value. Can be an input, a, etc.
    Search mode all will match against all test in searchContainer. Search mode first
    will match every letter of this element's value with the first letter of the searchContainer
  */
  
  var o = jQuery.extend ({
    container: '',                            // main container
    subContainer: '',                         // sub element containing individual elements to be searched / hidden
    searchContainer: '',                      // element to search in
    listener: 'keyup',                        // (optional) events to listen for ("change click keyup") etc.
    typingTimer: 0,                           // (optional) milliseconds to wait after keystroke to start. Gets reset every time user types
    searchMode: 'all',                        // (optional) all = all text within searchContainer | first = first letter of searchContainer
    paginationContainer: '',                  // (optional) where pagination should be displayed
    elementsPerPage: 5,
    callback: null,
    resultCount: 0
  }, options);
  
  var cache, t, term;
  var target = $(o.container + " " + o.subContainer);
  
  list = jQuery(o.searchContainer);           // Initially cache all results so they don't have to be put to lower case every time you search
  if ( list.length ) {
    cache = list.map(function(){
      return this.innerHTML.toLowerCase();
    });
  }

  $(this).bind( o.listener, function() {
    
    var term = $(this).attr("value").toLowerCase();     // Switch everything to lowercase to do a case insensitive search
    term = term.replace(/&/, "&amp;");                  // Replace & with &amp; as all the data comes from XML and & is always encoded
    term = term.replace(/^\s+|\s+$/g, '');              // Trim whitespace around search term
    
    clearTimeout(t);
    t = setTimeout( function() {
      o.resultCount = 0;                                // Reset search result count
      cache.each( function(i) {
        var currentElement = $(target[i]);
        if( term == "" ) {
          $(currentElement).addClass('filterMatch');
        } else {
          switch(o.searchMode) {

            // SEACH FOR FIST LETTER
            case 'first':
              if( term.length > 1 ) {
                $(currentElement).removeClass('filterMatch');
                for(z = 0; z < term.length; z++) {
                  if( this.substring(0, 1) == term.substring(z,z+1) ) {
                    $(currentElement).addClass('filterMatch');
                    o.resultCount++;
                  }
                }
              } else {
                if( this.substring(0, 1) == term ) {
                 $(currentElement).addClass('filterMatch');
                 o.resultCount++;
                } else {
                 $(currentElement).removeClass('filterMatch');
                }
              }
              break;
              
            // SEACH THROUGH ENTIRE STRING
            case 'all':
              if( this.match(term) != null ) {
                $(currentElement).addClass('filterMatch');
                o.resultCount++;
              } else {
                $(currentElement).removeClass('filterMatch');
              }
              break;
          }
        }
      });
      
      // select all active elements
      var activeElements = $(target).filter('.filterMatch');
      
      
      if( o.paginationContainer != "" ) {
        var paginationTarget = $("div#" + o.paginationContainer);
      
        // hide all elements
        $(target).hide();
        
        var pages = Math.ceil(activeElements.size() / o.elementsPerPage);
        var currentPage = 1;
        
        // Create pagination elements
            // Empty the pagination container
            $(paginationTarget).empty();
            
            // Fill pagination with current proper pagination
            $(paginationTarget).append("<a style='display: none;' href='#!'>Prev</a>");
            for( i = 1; i < pages+1; i++ ) {
              $(paginationTarget).append("<a href='#!'>" + i + "</a>");
            }
            $(paginationTarget).append("<a style='display: none;' href='#!'>Next</a>");
        
        
        // Assign Click behavior to pagination links
            $(paginationTarget).children("a").click(function() {
              // Previous button
              if( $(this).html() == 'Prev' ) {
                if( currentPage > 1 ) {
                  currentPage--;
                }
              // Next Button
              } else if( $(this).html() == 'Next' ) {
                if( currentPage < pages ) {
                  currentPage++;
                }
              } else {
                currentPage = $(this).html();
              }
              if( currentPage == 1 ) {
                $(this).blur().parent().children("a:contains('Prev')").hide();
              } else if ( currentPage > 1 ) {
                $(this).blur().parent().children("a:contains('Prev')").show();
              }
              if( currentPage < pages ) {
                $(this).blur().parent().children("a:contains('Next')").show();
              } else if ( currentPage == pages ) {
                $(this).blur().parent().children("a:contains('Next')").hide();
              }
              
              // Activate appropriate button
              $(this).parent().children().removeClass('active');
              $(this).blur().parent().children("a:contains(" + currentPage + ")").addClass('active').blur();
              
              activeElements = $(o.container + " " + o.subContainer + ".filterMatch");
              $(activeElements).hide();

              for( i = (currentPage * o.elementsPerPage - o.elementsPerPage); i < (currentPage * o.elementsPerPage); i++ ) {
                $(activeElements).eq(i).fadeIn('slow');
              }
            });

        $(paginationTarget).children("a").eq(0).click();
        if(o.callback) o.callback();
      } else {
        $(target).hide();
        $(activeElements).fadeIn('slow');
        if(o.callback) o.callback();
      }
      
    }, o.typingTimer);
  });
        
}