$().ready(function() {
	// *******************
	// ** initial state **
	// *******************
	
	// xhr in progress
	var running_request = false;
	var request = null;
	var last_name = null;
	var default_page_content = null;
	
	// banner
	var total_banners = 0;
	var banner_interval = 6000;
	
	// hide search button
	$("input#search").next("input").hide();
	
	// no search
	if($("input#search").val() == "") {
		// hide all child ul elements (i.e. sub categories)
		$("#categories li > ul").hide();
		
		// unless the user has navigated directly via url
		$("#categories li.selected > ul").slideDown();
		
		// show search icon
		$("span#search-icon").removeClass("clear");
		$("span#search-icon").addClass("search");
	}
	else {
		// show clear search icon
		$("span#search-icon").removeClass("search");
		$("span#search-icon").addClass("clear");
	}
	
	// clear search button click event
	$("span#search-icon").click(function() {
		if($("input#search").val() == "") {
			$("input#search").focus();
		}
		else {
			$("input#search").val("");
			$("span#search-icon").removeClass("clear");
			$("span#search-icon").addClass("search");
			
			// restore default content
			var params = {};
			params['action'] = ['get_categories'];
			params['name'] = "";
			do_query(params);
			$("#cards").html(default_page_content);
		}
	});
	
	// prevent search form submission
	$("input#search").closest("form").submit(function() {
		return false;
	});
	
	setup_banner_rotation();
	
	setup_category_events();
	
	setup_showhides();
	
	// ************
	// ** events **
	// ************
	function setup_category_events()
	{
		if($("input#search").val() == "") {
			// no search
			$("#categories li > ul").hide();
			
			// top level category clicked
			$("#categories > ul > li > a").click(function() {
				toggle_category($(this).parent("li"));

				return false;
			});

			// sub categories click
			$("#categories li > ul > li a").click(function() {
				toggle_sub_category($(this).parent("li"));

				return false;
			});
			
			// save the page content, so we can put it back when no category selected
			if($("#cards").children().length) {
				default_page_content = $("#cards").children();
			}
		}
		else {
			// search
			$("#categories > ul > li > a").click(function() {
				var list_item = $(this).parent("li");
				
				if(list_item.is(".selected")) {
					// remove selection from all items (including any sub categories selected)
					list_item.parent("ul").find("li.selected").removeClass("selected");
					
					// get all search results
					get_cards({name: $("input#search").val()});
				}
				else {
					// remove selection from all items (including any sub categories selected)
					list_item.parent("ul").find("li.selected").removeClass("selected");
					
					// select category
					list_item.addClass("selected");
					
					// get search results for this category
					var category = id_from_id_attr(list_item, "category-");
					get_cards({category: category, name: $("input#search").val()});
				}
				
				return false;
			});
			
			$("#categories li > ul > li a").click(function() {
				var list_item = $(this).parent("li");
				var parent_list_item = list_item.parent("ul").parent("li");
				
				if(list_item.is(".selected")) {
					list_item.removeClass("selected");
					
					// get all search results
					get_cards({name: $("input#search").val()});
				}
				else {
					// remove selection from all items
					parent_list_item.parent("ul").find("li.selected").removeClass("selected");
					
					// add selected class to sub category
					list_item.addClass("selected");
					
					// get search results for this sub category
					var sub_category = id_from_id_attr(list_item, "sub_category-");
					get_cards({sub_category: sub_category, name: $("input#search").val()});
				}
				
				return false;
			});
		}
	}
	
	$("input#postcode").keyup(function(event) {
		show_postcode_suggestions(event.which, $(this));
	});
	
	// var search_timeout = null;
	
	$("input#search").keyup(function() {
		if($(this).val() != "") {
			$("span#search-icon").addClass("clear");
			$("span#search-icon").removeClass("search");
		}
		else {
			$("span#search-icon").addClass("search");
			$("span#search-icon").removeClass("clear");
		}
		
		if(last_name != null && $(this).val() == last_name) {
			// return false if current query matches search string
			// allows user to highlight, select without doing another xhr
			return false;
		}
		
		// abort if running a request currently
		if(running_request) {
			request.abort();
		}
		
		running_request = true;
		
		get_search_result_cards($(this).val());
	});
	
	// ***************
	// ** functions **
	// ***************
	
	function toggle_category(list_item)
	{
		// remove selected class from main category (if it is not the category clicked), 
		// slide up its list of subcategories and remove selected class from a subcategory (if necessary)
		list_item.siblings("li.selected").removeClass("selected").children("ul").slideUp("slow").find("li.selected").removeClass("selected");
		
		
		if(list_item.is(".selected") && (list_item.find("li.selected").length > 0)) {
			// category clicked and one of its subcategory selected,
			// remove selection from subcategory and get the cards for this category
			list_item.find("li.selected").removeClass("selected");
			category = id_from_id_attr(list_item, "category-");
			get_category_cards(category);
		}
		else if(list_item.is(".selected")) {
			// just category selected, unselect category
			list_item.removeClass("selected");
			
			// slide up subcategories for category clicked,
			// remove selected class from a subcategory (if necessary)
			list_item.children("ul").slideUp("fast").children("li").removeClass("selected");
			
			// restore default content
			$("#cards").html(default_page_content);
		}
		else {
			list_item.addClass("selected");
			
			// slide down subcategories for category clicked
			list_item.children("ul").slideDown("fast");
			
			// selected, get the cards for the category
			category = id_from_id_attr(list_item, "category-");
			get_category_cards(category);

		}
	}
	
	function toggle_sub_category(list_item)
	{
		list_item.siblings("li.selected").removeClass("selected");
		
		if(list_item.is(".selected")) {
			// deselected, get the cards for this category
			list_item.removeClass("selected");
			
			category = id_from_id_attr(list_item.parent("ul").parent("li"), "category-");
			get_category_cards(category);
		}
		else {
			// selected, get the cards for this sub category
			list_item.addClass("selected");
			
			sub_category = id_from_id_attr(list_item, "sub_category-");
			get_sub_category_cards(sub_category);
		}
	}
	
	function id_from_id_attr(list_item, prefix)
	{
		return list_item.attr("id").replace(prefix, "");
	}
	
	function get_category_cards(category)
	{
		var params = {category: category};
		get_cards(params);
	}
	
	function get_sub_category_cards(sub_category)
	{
		var params = {sub_category: sub_category};
		get_cards(params);
	}
	
	function get_search_result_cards(name)
	{
		last_name = name;
		get_cards_and_categories({name: name});
	}
	
	function show_postcode_suggestions(key, postcode_box)
	{
		if(!postcode_box.siblings("div#postcode-suggestions").length) {
			postcode_box.after("<div id='postcode-suggestions'></div>");
			
			$("input#postcode").blur(function() {
				$("#postcode-suggestions").fadeOut();
			});
			
			$("input#postcode").focus(function() {
				$("#postcode-suggestions").fadeIn();
			});
		}
		
		if(key == 37) {
			// left arrow
		}
		else if(key == 38) {
			// up arrow
			var current_selection = $("#postcode-suggestions a.selected");
			var next_selection = $("#postcode-suggestions a.selected").parent("div").prev("div").children("a");
			
			if(current_selection.length && next_selection.length) {
				current_selection.removeClass("selected");
				next_selection.addClass("selected");
			}
		}
		else if(key == 39) {
			// right arrow
		}
		else if(key == 40) {
			// down arrow
			var current_selection = $("#postcode-suggestions a.selected");
			var next_selection = $("#postcode-suggestions a.selected").parent("div").next("div").children("a");
			
			if(current_selection.length && next_selection.length) {
				current_selection.removeClass("selected");
				next_selection.addClass("selected");
			}
		}
		else if(key == 13) {
			// enter key
			var current_selection = $("#postcode-suggestions a.selected");
			
			if(current_selection.length) {
				window.location = current_selection.attr("href");
			}	
		}
		else {
			get_postcode({action: "get_suggestions", postcode: postcode_box.val()});
		}
	}
	
	function setup_banner_rotation()
	{
		if($("#banner-montage").length && typeof(banners_json) == 'object') {
			total_banners = banners_json.length;
			
			// start slideshow if more than 1 banner
			if(total_banners > 1) {
				var img = $("#banner-montage img");
				
				// make a bottom image
				img.clone().appendTo("#banner-montage");
				var bottom_img = $("#banner-montage img:eq(1)");
				bottom_img.removeClass("top");
				
				window.setTimeout(function() {
					show_next_banner(1, img, bottom_img);
				}, banner_interval);
			}
		}
	}
	
	function show_next_banner(index, img, bottom_img)
	{	
		// reset if index out of bounds
		index = index % total_banners;
		
		// [1] make the top image show the same banner as the bottom image
		img.attr("alt", bottom_img.attr("alt"));
		img.attr("src", bottom_img.attr("src"));
		
		// [2] cover the bottom image with the top image
		img.show();
		
		// [3] change the bottom image to show the next banner
		var next_banner = banners_json[index];
		bottom_img.attr("alt", next_banner.alt);
		bottom_img.attr("src", next_banner.src);
		
		// [4] fade out the top image to reveal the new bottom image
		img.fadeOut("slow", function() {	
			// loop
			window.setTimeout(function() {
				show_next_banner(index + 1, img, bottom_img);
			}, banner_interval);
		});
	}
	
	function setup_showhides()
	{
		$(".showhide").hide();
		$(".toggle-showhide").click(function() {
			var id = $(this).attr("id").replace(/toggle-/, "");
			$("#" + id).slideDown("fast");
			$(this).fadeOut("slow");
		});
	}
	
	// ***************
	// ** callbacks **
	// ***************
	function get_cards_and_categories(params) 
	{
		params['action'] = ['get_cards', 'get_categories'];
		do_query(params);
	}
	
	function get_cards(params)
	{
		params['action'] = ['get_cards'];
		do_query(params);
	}
	
	function do_query(params)
	{
		params['area'] = AREA_ID;
		params['area_uri'] = AREA_URI;
		
		request = $.get(BASE + "/service/card/", params, function(data){
			if(array_search('get_cards', params['action'])) {
				$("#cards").html($(data).filter("#cards").html());
			}
			
			if(array_search('get_categories', params['action'])) {
				$("#categories").html($(data).filter("#categories").html());
				setup_category_events();
			}
			
			running_request = false;
		}, {dataType: "html"});
	}
	
	function array_search(needle, haystack)
	{
		for(var i in haystack) {
			if(haystack[i] == needle) {
				return true;
			}
		}
		
		return false;
	}
	
	function get_postcode(data)
	{
		$.get(BASE + "/service/postcode/", data, function(data){
			$("#postcode-suggestions").html(data);
			$("#postcode-suggestions > div:first-child a").addClass("selected");
		});
	}
});
