var Search = {
	request: null,
	pendingRequest: false,
	// The cursor is the search result that has been selected with the up and down keys.
	// A value of -1 indicates that none is selected.
	cursor: {
		value: -1,
		max: -1,
		increment: function() {
			if(this.value != this.max) {
				this.value++;
			}
		},
		decrement: function() {
			if(this.value >= 0) {
				this.value--;
			}
		}
	},
	types: {
		AlbumArticle: {label: 'A', directory: 'albums', css: 'album'},
		GigArticle: {label: 'G', directory: 'gigs', css: 'gig'},
		InterviewArticle: {label: 'I', directory: 'interviews', css: 'interview'},
		FeatureArticle: {label: 'F', directory: 'features', css: 'feature'},
	}
};

(function($) {	
    $(function () {
		$('#searchField').bind('focus', function() {
			showInstantResults();
		}).bind('blur', function() {
			// The results box is not hidden if the user clicks inside it.
			if(!$('#searchResultsBox').data('hovered')) {
		        hideInstantResults();
			}
		});
		$('#searchField').keypress(function(e) {
			if(e.keyCode == 13) {
				e.preventDefault();
				// If the user has selected a result with the keyboard, pressing enter should go to that page.
				// Otherwise it should go to the full search results page.
				if(Search.cursor.value != -1) {
					window.location = $('#searchResultsBox ul li').eq(Search.cursor.value).find('a').attr('href');
					return false;
				} else {
					$('#searchForm').submit();
					return false;
				}
			}
		}).keyup(function(e) {
			switch(e.keyCode) {
			case 38:
				e.preventDefault();
				Search.cursor.decrement();
				repaintResultsBox();
				break;
			case 40:
				e.preventDefault();
				Search.cursor.increment();
				repaintResultsBox();
				break;
			default:
				// Update the results as the user types.
				var searchField = $('#searchField');
				if(searchField.data('lastQuery') != searchField.val()) {
					searchField.data('lastQuery', searchField.val());
					submitQuery(searchField.val());
				}
			}
		});
		// This allows the blur event on #searchField to know if the user is clicking on a link inside the results box.
		$('#searchResultsBox').hover(
			function(e) { $(this).data('hovered', true); },
			function(e) { $(this).data('hovered', false); }
		);
    });
	
	function hideInstantResults() {
		$('#searchResultsBox').removeClass('visible');
	}
	
	function showInstantResults() {
		$('#searchResultsBox').addClass('visible');
	}
	
	function updateResultsBox(results) {
		$('#searchField').removeClass('searching');
		if(results != null && results.length > 0) {
			Search.cursor.max = results.length - 1;
			Search.cursor.value = -1;
			$('#searchResultsBox ul').children().remove();
			var count = 0;
			for (var result in results) {
				if(result % 2 == 0) {
					$('<li class="odd"><span class="typeLabel ' + Search.types[results[result].type].css + '">' + Search.types[results[result].type].label + '</span><a href="' + Search.types[results[result].type].directory + '/' + results[result].id + '">' + results[result].title + '</a></li>').appendTo('#searchResultsBox ul');
				} else {
					$('<li><span class="typeLabel ' + Search.types[results[result].type].css + '">' + Search.types[results[result].type].label + '</span><a href="' + Search.types[results[result].type].directory + '/' + results[result].id + '">' + results[result].title + '</a></li>').appendTo('#searchResultsBox ul');
				}
			}
		} else {
			$('#searchResultsBox ul').html('<li>No results found...</li>');
		}
	}
	
	function repaintResultsBox() {
		$('#searchResultsBox ul li').removeClass('selected');
		if(Search.cursor.value > -1) {
			$('#searchResultsBox ul li').eq(Search.cursor.value).addClass('selected');
		}
	}
	
	function submitQuery(query) {
		Search.cursor.value = -1;
		Search.cursor.max = -1;
		repaintResultsBox();
		if(Search.pendingRequest == true) {
			Search.request.abort();
		}
		if(query.length < 1) {
			$('#searchResultsBox ul').html('<li><i>Enter your search query...</i></li>');
		} else if(query.length < 3) {
			$('#searchResultsBox ul').html('<li><i>You must enter at least 3 characters...</i></li>');
		} else {
			Search.pendingRequest = true;
			$('#searchField').addClass('searching');
			Search.request = $.getJSON(
				'services/search',
				{ 'query' : query },
				function(results){           
					updateResultsBox(results);
					Search.pendingRequest = false;
				}
			);
		}
	}
})(jQuery);
