// This jquery plugin was written by Kevin Charles
//
//  Usage in html is to add 
//  <script>$.tablesearch </script>
//  to the top of an html page
//  the table needs to have the searchTable id: <table id="searchTable"> with
// <thead> and <tbody> defined
//
// Default settings
// matchmethod defaults to anywhere
// options are: anywhere, front, and exact
// casesensitive defaults to case insensitive so that abc will match ABC
//
//EXAMPLE EXACT MATCHING AND CASE SENSITIVE
//<script src="jquery.js" type="text/javascript"></script>  
//<script src="jquery.tablesearch.js" type="text/javascript"></script>  
//<script type="text/javascript">  
// $().ready(function() {  
//  $('#softwareTable').tablesearch({matchmethod: "exact",casesensitive: true});  
// });  
// </script> 
  
  var obj = "";
  var options = "";
  var timeoutID = "";
  var statusStartText = 'Type in any of the above text boxes to perform search.';
  
  //This is called by timer to start search
  function responsiveSearch(obj,options){
	  runSearch(obj,options)
	  $('tr:gt(0)',obj).removeClass("oddRow");  //remove all class oddRow
	  $('tr:visible:odd:gt(0)',obj).addClass("oddRow");  //add just to visible odd rows
	  var resultsFromSearchText = searchText(obj);
	  if (resultsFromSearchText == ""){		  
			$('#_statusText').text(statusStartText);
	  }else{
			$('#_statusText').text("Results from search for "+resultsFromSearchText);
	  }
  }
  
  //Forms the text or what was queried
  function searchText(obj){
		var inputBoxesText = "";
		var firstOne = true;
		$("input._searchText",obj).each(function(){  
	    	 if(this.value !=""){
	    		 if (firstOne){
	    		 inputBoxesText = inputBoxesText + "\"" + this.value + "\"";
	    		 firstOne = false;
	    		 }else{
	    			 inputBoxesText = inputBoxesText + " and \"" + this.value + "\"";
	    		 }
	    	 }
		});
		return inputBoxesText;
	}

  //This performs the showing and hiding
  function runSearch(obj,options){

		 //Build array of numbers for the columns which have text entered
		 var nonEmptyInputIndexes = new Array(); //stores all the non-empty column numbers starting at 0
		 var nonEmptyInputValues = new Array(); //stores all the non-empty column input boxes values
		 var fixThese = ['[[]','[\\\\]','[/]', '[.]', '[*]', '[+]', '[?]', '[|]','[(]', '[)]', '[{]', '[}]' ];

		 $("input._searchText",obj).each(function(inputCount){  

	    	 if(this.value !=""){
	    		 nonEmptyInputIndexes[nonEmptyInputIndexes.length] = inputCount;
	    		 nonEmptyInputValues[nonEmptyInputValues.length] = this.value;
	    		//Make nonEmptyInputValues into case insensitive regular expressions
	    		 for (var x=0; x < fixThese.length; x++) {
	    			 nonEmptyInputValues[(nonEmptyInputValues.length-1)] = nonEmptyInputValues[(nonEmptyInputValues.length-1)].replace(RegExp(fixThese[x],"g"),fixThese[x]);
	    			}
	    		 //use options to get correct match method and case sensitivity
	    		 var mode = "i";  
	    		 if (options.casesensitive){ mode = ""; }
	    		 if (options.matchmethod == "exact"){
	     		 nonEmptyInputValues[(nonEmptyInputValues.length-1)] = new RegExp("^"+nonEmptyInputValues[(nonEmptyInputValues.length-1)]+"$",mode);	    		 
	    		 }else if (options.matchmethod == "front"){
	    		 nonEmptyInputValues[(nonEmptyInputValues.length-1)] = new RegExp("^"+nonEmptyInputValues[(nonEmptyInputValues.length-1)],mode);
	    	     }else {
	    		 nonEmptyInputValues[(nonEmptyInputValues.length-1)] = new RegExp(nonEmptyInputValues[(nonEmptyInputValues.length-1)],mode);
	    	 }
	    	 }
		 });


		 if (nonEmptyInputIndexes.length == 0){
			 //All input boxes are empty so show all rows
			 $("tbody tr",obj).each(function(){
			 		$(this).show(); 
			 });
	       }else{
			 //check each row of first column which is non-empty for matches
			 $("tbody td:nth-child("+(nonEmptyInputIndexes[0]+1)+")",obj).each(function(){ 

				 if(!$(this).text().match(nonEmptyInputValues[0])){
						//Not matching in this column so hide row
						 $(this).parent().hide();

					}else{
						//1st non empty Input box matches this cell				
						var allMatch = true;  //flag to test if whole row matches
						var rowToCheck = $(this).parent().find("td");  //Array of td elements for row with one match already
						if(nonEmptyInputIndexes.length == 1){
//							This is the only non empty column and it matches so show this row
							 $(this).parent().show();
						}else{
//							Loop through all remaining non empty cells to look for non-matches
							var rowMatches = true;
						for(x=1;x < nonEmptyInputIndexes.length;x++){
							var columnNumber = nonEmptyInputIndexes[x]+1;
							rowToCheck.filter(":nth-child("+columnNumber+")").each(function(){
								if (!rowToCheck[nonEmptyInputIndexes[x]].textContent.match(nonEmptyInputValues[x])){
//									Hide if a nonmatch is not found in any other rows
									$(this).parents("tr").hide();
									rowMatches = false;
//									Don't check any more cells in this row it isn't what they are looking for
									return false;

								}
							});
							//If all values match then show the row
							if (rowMatches){
								$(this).parents("tr").show();
							}
						}
						}
						 
					}
		 });
	}
};
  
(function($){
 $.fn.tablesearch = function(options) {
    
  var defaults = {
   matchmethod: "anywhere",
   casesensitive: false,
   inputsize: "14"
  };
  
  options = $.extend(defaults, options);
    
  return this.each(function() {

	   obj = $(this);
	   searchRow = document.createElement('tr');
	   searchRow.setAttribute('bgcolor','#FFCC33');

	   
	   
	   $('tr:even:gt(0)',obj).addClass("oddRow");  //initialize adding class oddRow
	   
		$('tbody:first tr:first td',obj).each(function(iColCount) {
			
					var inputBox = document.createElement('input'),
					searchCell = document.createElement('td');													
					
					$(inputBox).attr('type','text').attr('size',options.inputsize).addClass('_searchText');
					
					$(inputBox).keydown(function() { 
						clearTimeout(timeoutID);
						$('#_statusText').text("Searching...");
					});
					
					$(inputBox).keyup(function() {  
						clearTimeout(timeoutID);
						timeoutID = setTimeout("responsiveSearch(obj,options);",800);
					});
					
					$(searchCell).append(inputBox);
					$(searchRow).append(searchCell);
					$('thead:first',obj).append(searchRow);			
	});
		
		var numberOfColumns = $('tbody:first tr:first td',obj).length;
		statusRow = document.createElement('tr');
		statusRow.setAttribute('bgcolor','#FFCC33');
		var statusCell=document.createElement('td');
		statusCell.setAttribute('colspan',numberOfColumns);
		statusCell.setAttribute('id','_statusText');
		statusRow.appendChild(statusCell);
		var statusText=document.createTextNode(statusStartText);
		statusCell.appendChild(statusText);
		$('thead:first',obj).append(statusRow);
		//Set focus on first inputbox
		$("input._searchText",obj)[0].focus();

  });
 };
})(jQuery);
