$(document).ready(function() {

	var CONVENANT = "arboconvenanten";
	var CATALOGUS = "arbocatalogi";
	var BRANCHE = "brancheorganisaties";
	var BOTTOM_MARGIN = 10;
	var NOTIFY_LENGTH = 3000;
	var ERROR_MSG = "Een zoekterm moet bestaan uit drie of meer karakters";
	
	$brancheSelector = $('#brancheSelector');
	$brancheBox = $('#brancheSelector .selector .header');
	$brancheBtn = $('#brancheSelector button').eq(0);
	
	var timer;
	var msgTimer;
	var bSearchInput = $("#branchesearch").eq(0);
	var currentSelection = null;
	var selIdx = -1;
	
	initializeBoxBehaviour();
	
	/**
	 * This method creates an ajax request to retrieve branch search results
	 */
	function doBranchRequest(event) {
		
		var value = bSearchInput.val() ? $.trim(bSearchInput.val()) : "";
		if (value != "" && value.length > 2) {
			
			$.ajax({
					"url" : (typeof(URL_BASE) != "undefined" ? URL_BASE : "") + "/branchsearch",
					"data": { "query" : value },
					"dataType" : "json",
					"type" : "get",
					"fixture" : (typeof(URL_BASE) != "undefined" ? URL_BASE : "") + "/js/fixtures/branchesearch.fixture.js", 
					"success" : function(data) {
							if (data.status == 200) {
								$brancheBox.hide();
								setupSelectorContents(data.data);
								showBrancheBox(event);
							}
							else {
								$brancheBox.hide();
							}
						}
				});
		}
	}
	
	
	/**
	 * Setup the contents of the branch selector
	 * 
	 * @param bInfo is the branch information that needs to be displayed inside the 
	 *   	  widget result box.
	 */
	function setupSelectorContents(bInfo) {
		
		clearTimeout(msgTimer);
		
		$("#selectorContents *").remove();
		
		var list = $("<ul />");
		for (var idx = 0; idx < bInfo.length; ++idx) {
			
			var li = $("<li />");
			var link = $("<a />", { "href" : bInfo[idx].url });
			
			link.text(bInfo[idx].label);
			li.append(link);

			if (bInfo[idx].type == BRANCHE)
				link.addClass("branche");
			
			if (bInfo[idx].type == CONVENANT)
				link.addClass("convenant");
				
			if (bInfo[idx].type == CATALOGUS) 
				link.addClass("catalogus");
		
			li.mouseenter(function() {
				selIdx = $(this).index();
				$("li", $(this).closest("ul")).removeClass("focus");
				$(this).addClass("focus");
			});
			
			list.append(li);
		}
		
		list.append(getLastElement());
		
		$("#selectorContents").append(list);
		selIdx = -1;
	}
	
	
	/**
	 * This function sets up the "show all" results link
	 */
	function getLastElement() {
		var link = 
			$("<a />", { 
					"class" : "all", 
					"title" : "Alle resultaten", 
					"href" : (typeof(URL_BASE) != "undefined" ? URL_BASE : "") + "/zoeken/in-branches"}
			);

		link.text("Alle resultaten");
		link.bind(
				'click',
				function(evt) {
					$("form", $brancheSelector).submit();
					evt.preventDefault();
				}
			);
		
		var element = $("<li />", { "class" : "last" }).append(link);
					
		return element;
	}
	
	
	/**
	 * This function shows the branche box by moving making it 
	 * visible, and calculate the necessary amount we need to scroll.
	 */
	function showBrancheBox(event) {
		if ( !$brancheBox.is(':visible') ) {
			$brancheBox.show();
		}

		var positionY = 
			$brancheBox.offset().top + 
			$brancheBox.height() + BOTTOM_MARGIN - 
			determineViewportHeight();

		// if the viewport should move down, scroll there
		if (getScrollPosition() < positionY) {
			$("body").scrollTo( positionY, 750 );			
			event.stopPropagation();
		}
	}
	
	
	/**
	 * This function initializes the behaviour of the controls
	 * inside the branche information box.
	 */
	function initializeBoxBehaviour() {

		// init
		$brancheBox.hide();
		
		$brancheSelector.mouseenter(function() {
			$brancheBox.closest('.block').css('overflow', 'visible');
		});
		
		// branche button behavior
		$brancheBtn
			.css('cursor', 'pointer')
			.hover(function() {
				$brancheBtn.addClass('hover');
			}, function() {
				$brancheBtn.removeClass('hover');
			})
			.click(function(event) {
				showBrancheBox();
			});

		// hide the branchebox when not used
		$brancheBox
			.mouseleave(function() {
				timer = setTimeout(function () {
					$brancheBox.closest('.block').css('overflow', 'hidden');
					$brancheBox.hide();
				}, 750);
			}).mouseenter(function() {
				clearTimeout(timer);
			});
		
		// click outside the box somewhere and is visible, then hide it!
		$("body").click(function() {
			
			if ($(this).closest("#brancheSelector .selector").length == 0) {
				if ($brancheBox.is(":visible")) {
					$brancheBox.hide();
				}
			}
		});

		$("#branchesearch").attr("autocomplete", "off");
		
		$("#brancheSelector form").bind("submit", function(evt) {
			var val = bSearchInput.val();
			if (val == "" || val.length <= 2) {
				setupMsgContents(ERROR_MSG, evt);
				evt.preventDefault();
			}
			
			switchText.apply(bSearchInput);
		});
		
		// set request timer on key up
		$("#branchesearch").bind('keyup', function(evt) {
		
			switch (evt.keyCode) {
			
				case 13: // return key
					
					if (selIdx > 0) {
						var link = $("a", $("#selectorContents li").eq(selIdx))
						if (!link.hasClass("all")) {
							window.location.href = link.attr("href");
						}
						evt.preventDefault();
					}
					else {
						var val = bSearchInput.val();
						if (val == "" || val.length <= 2) {
							setupMsgContents(ERROR_MSG, evt);
							evt.preventDefault();
						}
					}
					
					return false;
					
				case 40: // down key
					++selIdx;
					if (selIdx >= $("#selectorContents li").length) {
						selIdx = $("#selectorContents li").length - 1;
					}
					
					$("#selectorContents li").removeClass("focus");
					$("#selectorContents li").eq(selIdx).addClass("focus");
					break;
					
				case 38: // up key
					$("#selectorContents li").removeClass("focus");

					--selIdx;
					if (selIdx < 0) {
						selIdx = -1;
					}
					else {
						$("#selectorContents li").eq(selIdx).addClass("focus");
					}
					
					break;
					
				default:
					selIdx = -1;
				
					if (timer) {
						clearTimeout(timer);
					}
					
					timer = 
						setTimeout(
							function() {
								doBranchRequest(evt)
							}, 50);
								
			}
			
			evt.preventDefault();
		});
		
	}	
	
	
	// --------------------------------------------------------------
	// 		Helper functions
	// --------------------------------------------------------------


	/**
	 * This function will show a simple notification area underneath
	 * the search input box. It will disappear in NOTIFY_LENGTH milliseconds 
	 * 
	 * @param string msg is the message to show in the notification area
	 * @param original event
	 */
	function setupMsgContents(msg, evt) {
		clearTimeout(msgTimer);
		
		$brancheBox.hide();
		
		var label = $("<span />").text(msg);
		
		$("#selectorContents *").remove();
		$("#selectorContents").append(label);
		
		msgTimer = setTimeout(function() { $brancheBox.fadeOut(); }, NOTIFY_LENGTH);
		showBrancheBox(evt);
	}
	
	/**
	 * Get the current scroll position of the viewport, works
	 * cross-browser
	 */
	function getScrollPosition() {
		var scrollTop = document.body.scrollTop;

		if (scrollTop == 0)
		{
		    if (window.pageYOffset)
		        scrollTop = window.pageYOffset;
		    else
		        scrollTop = (document.body.parentElement) ? document.body.parentElement.scrollTop : 0;
		}
		
		return scrollTop;
	}
	
	/**
	 * Determine the height of the visible area
	 */
	function determineViewportHeight() {
		 var viewportheight;
		 
		 // the more standards compliant browsers (mozilla/netscape/opera/IE7) use window.innerWidth and window.innerHeight
		 
		 if (typeof window.innerWidth != 'undefined') {
		      viewportheight = window.innerHeight
		 }
		 
		// IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
		 else if (
				 	typeof document.documentElement != 'undefined' && 
				 	typeof document.documentElement.clientWidth != 'undefined' && 
				 	document.documentElement.clientWidth != 0
				 )
		 {
		       viewportheight = document.documentElement.clientHeight
		 }
	 
		 // older versions of IE
		 else {
		       viewportheight = document.getElementsByTagName('body')[0].clientHeight
		 }

		 return viewportheight;
	}
	
	
});

