/**
 * document init
 */
$(document).ready( function(){
	$('#search input').gsearch();
});

/**
 * jQuery search field plugin
 *
 * Controls the value of the search field and its behavior.
 */
(function($){
	$.fn.livesearchfield = function(options, func){
		// if we don't have an options object, create one
		options = options || {};

		// auto-sense the search function
		var runfunc = $.isFunction(options) ? options : func;
		if(!$.isFunction(runfunc)){
			console.log('missing search function');
			return false;
		}

		// extend our defaults with our options
		var settings = $.extend({
			'help':			'Search...',
			'className':	'set',
			'min':			3,
			'keys':			{}
		}, options);

		// perform the rounding
		return this.each(function(){

			var $self = $(this);

			//------------------------------------------
			// internal functions
			//------------------------------------------

			// handle typing events in the search field
			// thanks for Jorn Zaefferer for this key sensing code
			var KEY = {
				UP: 38,
				DOWN: 40,
				DEL: 46,
				TAB: 9,
				RETURN: 13,
				ESC: 27,
				COMMA: 188,
				PAGEUP: 33,
				PAGEDOWN: 34,
				BACKSPACE: 8
			};
			var timeout, lastKeyPressCode;

			var f = {
				keyup: function(event){
					// track last key pressed
					lastKeyPressCode = event.keyCode;
					// if we have a handler for the just-pressed key, run it and return
					if( options.keys && $.isFunction(options.keys[event.keyCode]) ){
						options.keys[event.keyCode]();
						return false;
					}
					// otherwise, handle normally
					switch(event.keyCode){

						case KEY.UP:
						case KEY.DOWN:
						case KEY.PAGEUP:
						case KEY.PAGEDOWN:
						case KEY.TAB:
							break;

						case KEY.RETURN:
							event.preventDefault();
							break;

						case KEY.ESC:
							$(self).val(options.help);
							f.blur();
							break;

						case KEY.BACKSPACE:
							runfunc();
							break;

						default:
							clearTimeout(timeout);
							timeout = setTimeout(runfunc, 10);
							break;
					}
				},

				// on focus, if the field's text equals the setup text, get rid of it and remove the class name
				focus: function(){
					if($(this).val() == settings.help){
						$(this).val('');
						$(this).addClass(settings.className);
					}
				},

				// on blur, if the value is null, set the value to help and deal with the class name
				blur: function(){
					if($(this).val() == ''){
						$(this).val(settings.help);
						$(this).removeClass(settings.className);
					}else{
						$(this).addClass(settings.className);
					}
				}
			};

			// click event, so we can keep it from bubbling to the surrounding anchor
			$self.click(function(){
				return false;
			});

			//------------------------------------------
			// public events
			//------------------------------------------

			$self.keyup(f.keyup);
			$self.focus(f.focus);
			$self.blur(f.blur);

			//------------------------------------------
			// run on load
			//------------------------------------------

			// set the default text on load if there's nothing in there
			if($(this).val() == ''){
				$(this).val(settings.help);
			}

		});
	};
})(jQuery);

/**
 * jQuery google search plugin
 */
(function($){
	$.fn.gsearch = function(){
		return this.each( function(){

			var $self = $(this);

			$self.data('elm', {
				box: $self.parents('div:eq(0)')
			});

			//------------------------------------------
			// internal functions
			//------------------------------------------

			var f = {
				// build the html to enclose the search results
				create: function(){
					$self.data('elm').results	= $('body').append('<div id="search-results"><h2>Searching for</h2><div class="list"/></div>').find('#search-results');
					$self.data('elm').header	= $('h2', $self.data('elm').results);
					$self.data('elm').hits		= $('div.list', $self.data('elm').results);
					// handle close click
					$self.data('elm').header.click(f.reset);
					// fire the resize event
					f.rejigger();
				},

				// make sure the position of the search results is placed correctly
				rejigger: function(){
					var pos		= $self.offset();
					pos.width	= $self.width();
					pos.height	= $self.height();
					pos.padding	= parseInt($self.css('padding-left')) * 2;
					$self.data('elm').results.css({
						width: '400px',
						left: (pos.left + pos.width + pos.padding - 400 + 2) + 'px',
						top: (pos.top + pos.height + pos.padding + 1) + 'px'
					});
				},

				error: function(msg){
					msg = msg || 'Something went horribly wrong...';
					$self.data('elm').header.html(msg);
				},

				clear: function(){
					$self.data('elm').hits.empty();
				},

				reset: function(){
					$self.data('elm').results.fadeOut(f.clear);
					$self.val('');
					$self.trigger('blur');
				},

				show: function(){
					f.clear();
					if(!gws.results.length){
						f.error('Nothing matches your search...');
						return false;
					}
					if(gws.results.length < 8){
						$self.data('elm').header.html('Found ' + gws.results.length + ' result' + (gws.results.length == 1 ? '' : 's'));
					}else{
						$self.data('elm').header.html('Showing the top 8 results');
					}
					var i, hits = [];
					for(i = 0; i < gws.results.length; i++){
						$self.data('elm').hits.append('<p class="url"><a href="' + gws.results[i].url + '">' + gws.results[i].title + '</a></p><p class="excerpt">' + gws.results[i].content + '</p>');
					}
					return false;
				},

				search: function(){
					$self.data('elm').results.fadeIn();
					// search string
					var str = $self.val();
					if(!str || str.length < 4){
						f.error('Please enter something to search for...');
						return false;
					}

					// fart around with gws
					if(!gws){
						f.error('We had trouble communicating with Google.');
						$self.data('elm').hits.html('Please refresh the page and try again.');
						return false;
					}
					gws.setResultSetSize(GSearch.LARGE_RESULTSET);
					gws.setSearchCompleteCallback(null, f.show, [null]);
					//gws.setUserDefinedLabel('Searching ecjlaw.com...');
					//gws.setUserDefinedClassSuffix('siteSearch');
					gws.setSiteRestriction('ecjlaw.com');

					// ask google to do the search
					gws.execute(str);
				}
			};

			// attach the functions to data
			$self.data('f', f);

			//------------------------------------------
			// run on load
			//------------------------------------------

			// create the html
			f.create();

			// apply the searchfilter plugin to the search field
			$self.livesearchfield({
				'help':			'Search...',
				'className':	'set',
				'min':			3,
				'keys':			{'27': f.reset}
			}, f.search);

		});
	}
})(jQuery);
