/**
 * Autocomplete Plugin Script for Klett und Balmer.
 *
 * @version 1.0 (06. October 2009)
 * @author michael.kuck@h2g.ch
 */
(function($) {
	// defining global vars
	var acSuggests = 0;
	var acCurrent = -1;
	var acQuery = '';
	var acInput = false;
	var acPage = new Object();
	// 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);
		// initialize autocomplete service
		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'});
			// creating suggestion box
			init(ac);
			// setting focus and blur events
			$(this).focus(function() { acInput.val(''); showOnFocus(); });
			$(this).click(function() { acInput.val(''); });
			$(this).blur(function() { setTimeout( function() {acClear(true)}, 200) });
			// setting search form submit function
			$(acInput).parent().submit(function() {
				// check for selected search suggest
				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 {
					// no selected search suggest, perform default search
					if (($(acInput).val() == o.acTextDefault) ||
					    ($(acInput).val() == '')) {
						return false;
					} else {
						$(acInput).css({
							'text-indent': o.acDoSearch['text-indent'],
							'padding-left': o.acDoSearch['padding-left'],
							'width': o.acDoSearch['width'],
							'background': o.acDoSearch['background']
						});
						return true;
					}
				}
			});
			// on key up listener
			$(this).keyup(function (e) {
				// get keyCode (window.event is for IE)
				var keyCode = e.keyCode || window.event.keyCode;
				acQuery = $(acInput).val();
				// update proceed anchor
				$("#"+o.cssSelector['acProceed']).find("a").attr({
					'href': o.acDefaultURL+acQuery
				});
				// check and treat up and down arrows
				if (updown(keyCode)) { return; }
				// check and treat left right arrows
				if (keyCode == 37 || keyCode == 39) { return; }
				// check for ESC key
				if (keyCode == 27) { acClear(true); return; }
				// if text, call ac with delay
				setTimeout(function() {autocomplete(acQuery)}, o.acDelay);
			});
		});
	};
	// autocomplete ajax request
	function autocomplete(q) {
		// if query is empty clear suggest box
		if ($(acInput).val() == '') {
			acClear(false); return;
		}
		// continue only query equals field value
		if ($(acInput).val() == q) {
			// get remote data as JSON
			$.getJSON((o.acResponseURL + escape(q)), function(data) {
				// getting total of suggest found
				acSuggests = parseInt(data.rows);
				// populate suggestion box with results
				if (acSuggests > 0) {
					// clearing old suggestions and show box
					$("#"+o.cssSelector['acList']).html('');
					$("#"+o.cssSelector['acProceed']).css({'display':'block'});
					$("#"+o.cssSelector['acBox']).show();
					// adding mouseout function on list box
					$("#"+o.cssSelector['acList']).mouseout(function() {
						highlight(-1);
					});
					// iterating suggestions
					$.each(data.results, function(i, item) {
						// creating suggest element
						var s = suggest(item.title,item.description,item.cover);
						// storint landing page url to global object
						acPage[i] = item.page;
						// adding functional classes to suggest element
						$(s).addClass(o.cssClasses['passive']);
						if (i > 0) $(s).find("div."+o.cssClasses['div-result']).addClass(o.cssClasses['border']);
						// adding mouseover and click functions
						$(s).mouseover(function() { acCurrent = i; highlight(i); });
						$(s).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 box
						$("#"+o.cssSelector['acList']).append(s);
					});
					// adding border at bottom of result
					$("#"+o.cssSelector['acProceed']).addClass(o.cssClasses['border']);
					// Fixing IE6 background shadow bug
					if ($.browser.msie && $.browser.version=="6.0") {
						$("#"+o.cssSelector['acBox']).find("div."+o.cssClasses['acCarrier'])
						.css({'height': ($("#"+o.cssSelector['acList']).height() - 48)+"px"});
					}
				} else {
					acClear(false);
				}
			});
		}		
	};
	// function to highlight mouseover and focus elements
	function highlight(c) {
		var subsequent = false;
		$("#"+o.cssSelector['acList']+" li").each(function(i, item) {
			// remove all classes first
			$(item).removeClass(o.cssClasses['active']);
			$(item).removeClass(o.cssClasses['passive']);
			if (i == c) {
				$(item).addClass(o.cssClasses['active']);
				if (acSuggests > 1) { subsequent = true; }
				else { if (c == 0) {
					$("#"+o.cssSelector['acProceed']).removeClass(o.cssClasses['border']);
				}}
			} else {
				// check for last item entry
				if (c == (acSuggests-1)) {
					// ok, we have the last entry, style the span proceed anchor
					$("#"+o.cssSelector['acProceed']).removeClass(o.cssClasses['border']);
				} else {
					$("#"+o.cssSelector['acProceed']).addClass(o.cssClasses['border']);
				}
				// check for subsequent list item
				if (!subsequent) {
					$(item).addClass(o.cssClasses['passive']);
				} else {
					subsequent = false;
				}
			}
		});
	};
	// creating suggestion box (shadow and bottom link)
	function init(ac) {
		// creating main suggestion box
		var acBox = $("<div>").attr({'id':o.cssSelector['acBox']});
		var acCanvas = $("<div>").attr({'class':o.cssClasses['acCarrier']});
		// setting up unordered list for results
		var acList = $("<ul></ul>").attr({'id':o.cssSelector['acList']});
		// creating proceed link at bottom
		var acProceed = $("<span></span>").
			attr({'id':o.cssSelector['acProceed']});
		var acProceedLink = $("<a></a>").attr({
			'class':o.cssClasses['acProceedLink'],
			'href':'javascript:void(0);'
		}).html('alle Suchergebnisse anzeigen');
		$(acProceed).append(acProceedLink);
		$(acCanvas).append(acList).append(acProceed);
		// creating suggestion box footer shadow
		var acFooter = $(o.acFooter['element']).attr({
			'class':o.acFooter['class'],
			'src':o.acFooter['src'],
			'width':o.acFooter['width'],
			'height':o.acFooter['height'],
			'alt':''
		});
		// appending elements to ac box
		$(acBox).append(acCanvas).append(acFooter);
		// adding suggestion box to search carrier
		$(ac).append(acBox);
	};
	function showOnFocus() {
		// creating main list entry
		var focus = $("<li></li>").addClass("non-focus").append(
			$("<div>").attr({'class':o.cssClasses['div-result']}).append(
			$("<div>").attr({'class':o.cssClasses['div-cover']})).append(
			$("<div>").attr({'class':o.cssClasses['div-content']})).append(
			$("<div>").attr({'class':'clear'}).html('<!-- clearer -->'))
		);
		// adding suggestion cover to result
		$(focus).find("div."+o.cssClasses['div-cover']).append(
			$("<img/>").attr({
				'src': o.acFocus['src'],
				'width': o.acFocus['width'],
				'height': o.acFocus['height'],
				'alt': ''
			})
		);
		// adding title and description
		$(focus).find("div."+o.cssClasses['div-content']).append(
			$("<h5></h5>").html(o.acFocusTitle)
		).append($("<p></p>").html(o.acFocusText));
		// disabling proceed link
		$("div."+o.cssClasses['acCarrier']).
			find("#"+o.cssSelector['acProceed']).
			css({'display':'none'});
		// show ac box with on focus element
		$("#"+o.cssSelector['acList']).append(focus);
		// show onfocus ac box
		$("#"+o.cssSelector['acBox']).show();
		// Fixing IE6 background shadow bug
		if ($.browser.msie && $.browser.version=="6.0") {
			$("#"+o.cssSelector['acBox']).
				find("div."+o.cssClasses['acCarrier']).
				css({'height':'84px'});
		}
	}
	function suggest(t,d,i) {
		// creating main list entry
		var suggest = $("<li></li>").append(
			$("<div>").attr({'class':o.cssClasses['div-result']}).append(
			$("<div>").attr({'class':o.cssClasses['div-cover']})).append(
			$("<div>").attr({'class':o.cssClasses['div-content']})).append(
			$("<div>").attr({'class':'clear'}).html('<!-- clearer -->'))
		);
		// adding suggestion cover to result
		$(suggest).find("div."+o.cssClasses['div-cover']).append(
			$("<img/>").attr({
				'src':i['src'],
				'width':i['width'],
				'height':i['height'],
				'alt':i['alt']
			})
		);
		// adding title and description
		$(suggest).find("div."+o.cssClasses['div-content']).append(
			$("<h5></h5>").html(t)
		).append(d);
		// return suggestion element
		return suggest;
	}
	// clearing autocomplete suggestion
	function acClear(def) {
		if (acInput) {
			$("#"+o.cssSelector['acList']).html('');
			$("#"+o.cssSelector['acBox']).hide();
			if(def) $(acInput).val(o.acTextDefault);
		}
	}
	// check for arrow up/down keys
	function updown(k) {
		if (k == 40 | k == 38) {
			if (k == 38) { // keyUp
				acCurrent = (acCurrent == 0 || acCurrent == -1) ?
					(acSuggests - 1) : (acCurrent - 1);
			} else { // keyDown
				acCurrent = (acCurrent == (acSuggests - 1) || acCurrent == -1) ?
					0 : (acCurrent + 1);
			}
			// highlight suggest
			highlight(acCurrent);
			return true;
		} else {
			acCurrent = (k == 13) ? acCurrent : -1;
			return false;
		}
	}
	// private debug function
	function debug(msg) {
		if (window.console && window.console.log)
			window.console.log('Debug: ' + msg);
	};
	$.fn.autocomplete.defaults = {
		acResponseURL: '/response/json/data_autocomplete.php?q=',
		acDefaultURL: '/shop/suche/?search=',
		acTextDefault: 'ISBN/Titel suchen',
		acFocusTitle: 'Während Ihrer Eingabe',
		acFocusText: 'unterstützt Sie die Suche in<br />Echtzeit mit passenden Vorschlägen<br />für die meistgesuchten Titel.',
		acDelay: 500,
		acDoSearch: {
			'background': 'url(/img/results_anim.gif) 2px 2px no-repeat #ebe9ed',
			'width': '127px',
			'text-indent': '-99999px',
			'cursor': 'wait',
			'padding-left': '2.0em'
		},
		cssSelector: {
			'acBox': 'suggestion',
			'acList': 'suggestion-list',
			'acProceed': 'proceed'
		},
		cssClasses: {
			'active': 'focus',
			'passive': 'non-focus',
			'border': 'bordered',
			'acCarrier': 'canvas',
			'acProceedLink': 'order',
			'div-result': 'result',
			'div-cover': 'cover',
			'div-content': 'content'
		},
		acFooter: {
			'element': '<img/>',
			'class': 'left',
			'src': '/img/box_suggestion_bot.png',
			'width': '348',
			'height': '10'
		},
		acFocus: {
			'src': '/img/ac_cover_focus.png',
			'width': '90',
			'height': '43',
			'alt': ''
		}
	};
})(jQuery);