/**
jQuery-table-row-highlighter v0.3

Author			Michael Odden <code@michaelodden.com>
Last Updated	2009-06-04
Homepage		http://michaelodden.com/
Documentation	http://michaelodden.com/labs/js/table-row-highlighter/
Blogpost		http://michaelodden.com/webdevelopment/table-row-highlighterjs

License: Do whatever you like, but please leave a notice, and I'd love feedback/patches so I can upgrade the code.

TODO:
* Change column on header-click
* Keyboard-arrows to navigate to next/previous match
* Play nice when theres multiple tables activated

AVAILABLE PARAMS (and defaults)
		params = {
			highlightClass : "highlight", // CSS-class added to the matching row
			inputTimeout : 1000, // In millisec
			debugElement : null, // Should be a reference to an Input-element
			column : 1, // Which column to check in each row - defaults to "1" (first col)
		}

		
HOW TO

var params = {
			highlightClass : 'highlight',
			column : 1
		}
// You should by now make sure that you that the selector points to one single table
// I'm working on making it more flexible
$("#mytable").highlighter(params);
*/

jQuery.fn.highlighter = function(params) {
		this.version = 0.3;
	    params = $.extend(jQuery.fn.highlighter.defaults, params);
		var focusEl = $("<input />");
		
		// Taking care of the multichar-user-input
		var inputreader = function() {
				var _return = {
					active : false, // Will be used when extending for multiple tables
					onInput : null,	// Callback - method set here will be called after each input, current input-string will be sent as arg.
					
					// Settings
					input_lastupdate : -1,
					debug : false,
					debug_element : null,
					
					// Keeper of the current input
					cur_input : "", 
					
					toString : function() { return "[MIO.inputreader v" + jQuery.fn.highlighter.version + "]"; },
					
					// Initiates the listener 
					// Todo: modify to play nicer with the other kids
					init : function(listenat) {
						this.active = true;
						listenat = listenat ? listenat : document;
						var that = this;
						$(listenat).keyup(function(e) { that.listener(e) });
					},
					
					// 
					setDebugElement : function(el) {
						this.debug = true;
						this.debug_element = el;
					},
						
					// Called after every keypress
					register : function(code) {
						// Initiate an updated date-object
						var date = new Date();
						
						// On timeout - clear
						if( (date.getTime()-this.input_lastupdate) > params.inputTimeout ) {
							this.clear();
						}
						this.input_lastupdate = date.getTime();
						
						// Todo: sanitize
						var char = String.fromCharCode(code);
						this.cur_input += char;
						
						this.afterRegister();
					},
					
					// Takes care of callbacks etc
					afterRegister : function() {
						if(typeof this.onInput == "function") {
							this.onInput(this.cur_input);
						}
		
						if(this.debug==true && this.debug_element) {
							this.debug_element.val(this.cur_input);
						}
					},
					
					// Clears the input, either on timeout or on ESC
					clear : function() {
						this.cur_input = "";
						this.afterRegister();
					},
					
					// The event-listener, listening for keyup-events at document
					listener : function(e) {
						if(!this.active) return;
						
						// check for arrow-keys. TODO - allow for keyboard navigation between matches
						switch(e.keyCode) {
							case 38: // Arrow up
								break;
							case 40: // Arrow down
								break;
							case 27: // ESC
								this.clear();
								break;
							default: // All good
								this.register(e.keyCode);
								break;
						}
					}
				};
				return _return;
			};
		
		var ir = new inputreader();
		if(params.debugElement!=null) {
			ir.setDebugElement($(params.debugElement));
		}
		ir.init(document);
		
		// Going through each matching table
		return this.each(function() {
			if(this.nodeName != "TABLE") return;
			
			var rows = $("tbody tr", this);
			var cols = $("tbody tr td:nth-child(" + params.column + ")", this);
			
			ir.onInput = function(str) {
					rows.removeClass(params.highlightClass);
					
					if(str=="") return;
					
					var checkexp = new RegExp("^" + str, "i");
					var foundMatch = false;
					
					// Checking for matching rows
					cols.each(function() {
							if(!foundMatch && checkexp.test($(this).html())) {
								$(focusEl).appendTo(this).focus().remove();
								$(this).parent().addClass(params.highlightClass);
								foundMatch = true;
							}
						});
				};
		});
	};
jQuery.fn.highlighter.defaults = { highlightClass : "highlight", inputTimeout : 1000, debugElement : null, column : 1 };