/**
 * Autocomplete Plugin for Klett und Balmer by H2G Internetagentur
 *
 * Plugin to handle autocomplete search suggest from database,
 * rewritten for layout facelift 2010/2011 by adopting new html
 * structure. improved usability.
 *
 * @author michael.kuck@h2g.ch
 * @version 2.00 06.12.2010
 */
(function($) {
	var ac;
	// defining global vars
	var acSuggests = 0;
	var acCurrent = -1;
	var acQuery = '';
	var acInput = false;
	var acHasFocus = false;
	var acPage = new Object();
	var acFocus = '';
	// var used for options
	var o = false;
	// plugin definition
	$.fn.autocomplete = function(ac, options) {
		// build main options before ac initial procedure
		var opts = $.extend({}, $.fn.autocomplete.defaults, options);
		// getting onfocus elements to store in global var
		acFocus = $(ac).html(); ac = $(ac).html('');
		// initialize autocomplete plugin
		return this.each(function() {
			acInput = $(this);
			// build element specific options
			o = $.meta ? $.extend({}, opts, $this.data()) : opts;
			// disabling nasty browser suggestion box
			$(this).attr({'autocomplete':'off'});
			// setting focus and blur events
			$(this).bind('focus', function() {
				acHasFocus = true; $(acInput).val('');
				$(ac).html(acFocus).show();
			});
			$(this).bind('click', function() { $(acInput).val(''); });
			$(this).bind('blur', function() { setTimeout(function() {
				// clear ac input field and reset ac box on blur
				acHasFocus = false; $(acInput).val(o.acTextDefault); clear(ac);
			}, 200); });
			// binding search form submit function
			$(this).parent().submit(function() {
				if (acPage[acCurrent]) {
					// send autocomplete request to google analytics
					if (pageTracker) pageTracker._trackEvent(
						'autocomplete','click',acPage[acCurrent]
					); // redirect to landing page
					window.location.href = acPage[acCurrent];
					return false;
				} else {
					return ($(acInput).val() != "") ? true : false;
				}
			});
			// on key up listener
			$(this).bind('keyup', function(event) {
				// get keyCode (window.event is for IE)
				var keyCode = event.keyCode || window.event.keyCode;
				// setting query string to global var
				acQuery = $(acInput).val();
				// check and treat up and down arrows
				if (updown(ac,keyCode)) { return; }
				// check and treat left/right arrows
				if (keyCode == 37 || keyCode == 39) { return; }
				// check for ESC key
				if (keyCode == 27) { clear(ac,true); return; }
				// if text, call ac with delay
				setTimeout(function() { autocomplete(ac, acQuery); }, o.acDelay);
			});
		});
	};
	// autocomplete ajax request
	function autocomplete(ac,q) {
		// if query is empty clear ac box
		if ($(acInput).val() == '') {
		clear(ac); return; }
		// continue only query equals field value
		if ($(acInput).val() == q) {
			// get remove data as JSON
			$.getJSON((o.acResponseURL + escape(q)), function(data) {
				// getting total of suggests found
				acSuggests = parseInt(data.rows);
				// reseting search results if input has lost focus
				acSuggests = (acHasFocus) ? acSuggests : 0;
				// populate suggestion box width results
				if (acSuggests > 0) { $(ac).show();
					// create ac unordered suggestion list element
					var list = $("<ul></ul>").attr({'id':'ac-list'});
					// binding mouseeave on ul list element
					$(list).bind('mouseleave', function() { highlight(ac,-1); });
					// iterating json suggestion list items
					$.each(data.results, function(i, item) {
						// creating suggest item entry
						var suggest = $(entry(item)).attr({'id':'sid-'+i});
						// storing landing page url to global object
						acPage[i] = item.page;
						// adding passive state class to list item
						$(suggest).addClass(o.cssClasses['non-focus']);
						// binding mouseover function to suggest item
						$(suggest).bind('mouseover', function() { highlight(ac,i); });
						// bind click event on ac suggest item
						$(suggest).one('click', function() {
							// send autocomplete request to google analytics
							if (pageTracker) pageTracker._trackEvent(
								'autocomplete','click',item.page
							); // redirect to landing page
							window.location.href = item.page;
						});
						// adding suggest to suggestion list element
						$(list).append(suggest);
					});
					// adding skip link to reach all results at bottom
					$(list).append(skip(ac,q));
					// adding suggestion list to autocomplete container
					$(ac).html('').append($("<div></div>")
						.addClass(o.cssClasses['outer'])
						.append(list)
					);
				} else { clear(ac); }
			});
		}
	};
	// private function to highlight given suggest item
	function highlight(ac,i) {
		// removing current highlighted list entry
		if (acCurrent != -1) $(ac).find("#sid-"+acCurrent)
			.removeClass(o.cssClasses['focus'])
			.addClass(o.cssClasses['non-focus']);
		// removing all focus - off classes to omit preceding border
		$(ac).find('li').removeClass(o.cssClasses['focus-off']);
		// adding focus to current list entry
		$(ac).find("#sid-"+i)
			.removeClass(o.cssClasses['non-focus'])
			.addClass(o.cssClasses['focus']);
		// adding off class on preceeding list entry
		if (!((i-1) < 0)) $(ac).find("#sid-"+(i-1)).addClass(o.cssClasses['focus-off']);
		// setting highlighted list item as current
		acCurrent = i;
	};
	// private function to handle up/down arrow key actions
	function updown(ac,k) {
		if (acSuggests > 0) {
			if (k == 40 | k == 38) {
				if (k == 38) { // keyUp
					current = (acCurrent < 0) ? (acSuggests - 1) : (acCurrent - 1);
				} else if (k == 40) { // keyDown
					current = (acCurrent == (acSuggests - 1) || acCurrent == -1) ? 0 : (acCurrent + 1);
				}
				// highlight current suggest item
				highlight(ac,current);
				// return true to continue
				return true;
			} else {
				// set ac current if enter action hit
				acCurrent = (k == 13) ? acCurrent : -1;
				// return false to stop action
				return false;
			}
		}
	};
	// private function to create suggestion entry
	function entry(i) {
		// building cover division layer
		var cover = $("<div></div>").addClass(o.cssClasses['cover'])
			.append($("<img />").attr({
				'src': i.cover['src'],
				'width': i.cover['width'],
				'height': i.cover['height'],
				'alt': i.cover['alt']
			}));
		// building content division layer
		var content = $("<div></div>").addClass(o.cssClasses['content'])
			.append($("<h1></h1>").html(i.title))
			.append($("<p></p>").html(i.description));
		// wrapping list element and return item
		return $("<li></li>").append(
			$("<div></div>").addClass(o.cssClasses['inner'])
				.append(cover).append(content)
				.append($("<br />").addClass('clear'))
			);
	};
	// private function to create the skip link at list bottom
	function skip(ac,q) {
		var skip = $("<li></li>").addClass(o.cssClasses['skip-link'])
			.append($("<div></div>").addClass(o.cssClasses['content'])
				.append($("<a></a>").attr({
					'href': (o.acDefaultURL+escape(q))
				}).addClass('more').html(o.acTextSkipLink)
			));
		// binding mouseover event on skip link
		$(skip).bind('mouseover', function() { highlight(ac,-1); });
		// returning skip link
		return skip;
	};
	// private function to clear ac layer
	function clear(ac) {
		// resetting global vars
		acSuggests = 0;	acCurrent = -1;
		acQuery = '';	acPage = new Object();
		// hide autocomplete canvas box
		$(ac).html('').hide();
	};
	// private debug function
	function debug(msg) {
		if (window.console && window.console.log)
			window.console.log('debug: '+msg);
	};
	$.fn.autocomplete.defaults = {
		acResponseURL: '/response/json/autocomplete.php?q=',
		acDefaultURL: '/Shop/Suche/?search=',
		acTextDefault: 'ISBN/Titel suchen',
		acTextSkipLink: 'alle Suchergebnisse anzeigen',
		acDelay: 500,
		cssClasses: {
			'focus': 'focus',
			'non-focus': 'non-focus',
			'focus-off': 'off',
			'skip-link': 'skip',
			'outer': 'canvas',
			'inner': 'suggestion',
			'cover': 'cover',
			'content': 'content'
		}
	};
})(jQuery);
