/**
 * Live search plugin.
 */



(function($) {


	/**
	 * Automatically set up input fields for livesearch,
	 * if they have the 'oi-livesearch' class set.
	 * (Important: input fields must be inside a form!)
	 */
	
	$(document).ready(function() {
		$('form .oi-livesearch').each(function() {
			
			var target = $(this).parents('form').attr('action');
			$(this).oiLivesearch(target);
		});
		
	});
	

 	$.fn.oiLivesearch = function(url, options) {
								
		// Merge custom and (a copy of) default options.
		options = $.extend($.extend({},$.fn.oiLivesearch.defaults), options);
					
					

		return this.each(function() {
										
			var obj = $(this);

			obj.data("lastsearch", "");	
			obj.data("timerID", 0);


			/**
			 * We don't query on every key up or down event.
			 * Instead we check after a predefined interval (=> $.fn.oiLivesearch.defaults.interval)
			 * if the value of the input has changed, in which case we send a request. (=> $.fn.oiLivesearch.search())
			 */
			
			obj.focus(function() {
				var that 	= this;
				var timerID	= setInterval(function() {
					$.fn.oiLivesearch.search(url, options, that, function(json) {
					});
				}, 500);
				
				obj.data("timerID", timerID);
			});
			
			
			/**
			 * Clear the timer when the input loses focus.
			 */

			obj.blur(function() {
				if (options.willblur()) {
					clearInterval(obj.data("timerID"));
		
					setTimeout(function() {
						if (typeof options.container == 'string') {
							options.animate ? $('#'+options.container).fadeOut(100) : $('#'+options.container).hide() ;
						}
						else {
							options.animate ? $(options.container).fadeOut(100) : $(options.container).hide() ;
						}
						options.didhide();
					},100);
				}
			});

		});
			
		
	};
	
	
	
	/**
	 * The actual search request. Takes a callback function
	 * as second argument, because the request is asynchronous.
	 */
	
	var _request = null; // XmlHttpRequest of the current search
	$.fn.oiLivesearch.search = function(url, options, input, callback) {
		
		var $input	= $(input);
		
		var s 	= $input.val();
		
		if (s == $input.data("lastsearch")) {
			return;
		}
		
		
	 	$input.data("lastsearch", s);
		
		var params = {livesearch: 'true'};
		params[$input.attr('name')] = s;

		
		var resultContainer = options.container;
		// Prepare the result container.
		if (typeof resultContainer == 'string') {
			resultContainer = $('#'+resultContainer);
			if (resultContainer.length == 0) {
				$(document.body).append('<div id="'+options.container+'"><\/div>');
				resultContainer = $('#'+options.container);
			}
		}
		else {
			resultContainer = $(resultContainer);
		}
		

		if (s == '') {
			options.animate ? resultContainer.fadeOut() : resultContainer.hide();
			$input.removeClass('searching');
			options.didhide();
			return;
		}
		
		
		options.animate ? resultContainer.fadeIn() : resultContainer.show();
		options.didshow();
		
		if (_request) _request.abort();

		$input.addClass('searching');
		if (options.format=='html') {
			_request = $.get(url, params, function(ret) {
				$input.removeClass('searching');
				resultContainer.html(ret);
				callback(ret);		
				options.didupdate();	
			});
		}
		else {
			_request = $.getJSON(url, params, function(ret) {
				$input.removeClass('searching');
				callback(ret);
				options.didupdate();	
			});
		}
		
	};
	
	
	
	/**
	 * Expose defaults, makes it easier to overwrite these.
	 */
	
	$.fn.oiLivesearch.defaults = {
		animate: true,
		willblur: function() { return true; },
		didhide: function() {},
		didshow: function() {},
		didupdate: function() {},
		interval: 500,						// min. interval between requests
		format: 'html',						// html or json
		container: 'oi-livesearch-results'	// Result container, can be an id or an object. The container will be created if it doesn't exist.
	};

	
})(jQuery);
