/*************************************************
 * This jQuery plugin is based off the quicksearch jQuery plugin,
 * found at: http://rikrikrik.com/jquery/quicksearch/.
 *
 * It has been modified to include an option to add a reset button next
 * to the search box that will clear the current search and return the
 * table back to its original state.  The additional functions/script are
 * documented below.
 */

(function($, window, document, undefined) {
  $.fn.quicksearch = function (target, opt) {
		
    var timeout, cache, rowcache, jq_results, val = '', e = this, options = $.extend({ 
      delay: 100,
      selector: null,
      stripeRows: null,
      loader: null,
      noResults: '',
      bind: 'keyup',
      onBefore: function () { 
        return;
      },
      onAfter: function () { 
        return;
      },
      show: function () {
        $(this).css('display',"");
      },
      hide: function () {
        $(this).css('display',"none");
        //this.style.display = "none";
      },
      prepareQuery: function (val) {
        return val.toLowerCase().split(' ');
      },
      testQuery: function (query, txt, _row) {
        for (var i = 0; i < query.length; i += 1) {
          if (txt.indexOf(query[i]) === -1) {
            return false;
          }
        }
        return true;
      }
    }, opt);
		
    this.go = function () {
			
      var i = 0, 
      noresults = true, 
      query = options.prepareQuery(val),
      val_empty = (val.replace(' ', '').length === 0);
			
      for (var i = 0, len = rowcache.length; i < len; i++) {
        if (val_empty || options.testQuery(query, cache[i], rowcache[i])) {
          options.show.apply(rowcache[i]);
          noresults = false;
        } else {
          options.hide.apply(rowcache[i]);
        }
      }
			
      if (noresults) {
        this.results(false);
      } else {
        this.results(true);
        this.stripe();
      }
			
      this.loader(false);
      options.onAfter();
			
      return this;
    };
		
    this.stripe = function () {
			
      if (typeof options.stripeRows === "object" && options.stripeRows !== null)
      {
        var joined = options.stripeRows.join(' ');
        var stripeRows_length = options.stripeRows.length;
				
        jq_results.not(':hidden').each(function (i) {
          $(this).removeClass(joined).addClass(options.stripeRows[i % stripeRows_length]);
        });
      }
			
      return this;
    };
		
    this.strip_html = function (input) {
      if(input == undefined){
        return false;
      }else{
        var output = input.replace(new RegExp('<[^<]+\>', 'g'), "");
        output = $.trim(output.toLowerCase());
        return output;
      }
    };
		
    this.results = function (bool) {
      if (typeof options.noResults === "string" && options.noResults !== "") {
        if (bool) {
          $(options.noResults).hide();
        } else {
          $(options.noResults).show();
        }
      }
      return this;
    };
		
    this.loader = function (bool) {
      if (typeof options.loader === "string" && options.loader !== "") {
        (bool) ? $(options.loader).show() : $(options.loader).hide();
      }
      return this;
    };
		
    this.cache = function () {
			
      jq_results = $(target);
			
      if (typeof options.noResults === "string" && options.noResults !== "") {
        jq_results = jq_results.not(options.noResults);
      }
			
      var t = (typeof options.selector === "string") ? jq_results.find(options.selector) : $(target).not(options.noResults);
      cache = t.map(function () {
        return e.strip_html(this.innerHTML);
      });
			
      rowcache = jq_results.map(function () {
        return this;
      });
			
      return this.go();
    };
		
    this.trigger = function () {
      this.loader(true);
      options.onBefore();
			
      window.clearTimeout(timeout);
      timeout = window.setTimeout(function () {
        e.go();
      }, options.delay);
			
      return this;
    };
		
    this.cache();
    this.results(true);
    this.stripe();
    this.loader(false);
		
    return this.each(function () {
      $(this).bind(options.bind, function () {
        val = $(this).val();
        e.trigger();
      });
    });
		
  };

}(jQuery, this, document));
