
$(function()
{
	/* The backgrounds. */
	var $background = $("#background");
	var $background_images = $("#background img");
	var $bg_blue = $("#bg_blue");
	var $bg_green = $("#bg_green");
	var $bg_orange = $("#bg_orange");
	var $bg_yellow = $("#bg_yellow");
	var $bg_gray = $("#bg_gray");
	var bg_z = 0;
	var bg_curr;
	
	/* These sizes are used to proportionally size against. */
	var base_width = window.settings.base_width;
	var base_height = window.settings.base_height;
	var image_width = window.settings.image_width;
	var min_width = window.settings.min_width;
	var min_height = window.settings.min_height;
	var use_full_width = true;
	var current_height;
	var slide_time = 750;
	var slide_ease = "easeInOutQuint";
	var is_moving = false;
	
	/* The loading indicator. Removed at the start of main(). */
	var $loading = $("#loading");
	
	/* The main wrapper, containing the interface and the slides. */
	var $wrapper = $("#wrapper");
	var $interface = $("#interface");
	
	/* Contains the <div> that's used to make the menu visible. */
	var $menu_area = $("#menu_area");
	/* Contains the menu itself. */
	var $menu_main = $("#menu");
	var $menu_container = $("#menu_container");
	/* Each individual menu item and all submenus. */
	var $menu_items = $(".menu-item h2 a", $menu_container);
	var $menu_subs = $(".menu-item .sub", $menu_container);
	var $menu_sub_links = $("a", $menu_subs);
	var $last_menu_item = $("#last_button");
	
	/* Contains the information about the current slide. */
	var $item_info_wrapper = $("#item_info_wrapper");
	var $item_info = $("#item_info");
	var $item_title = $("#item_title");
	var $item_text = $("#item_text");
	/* Whether we've shown the navigation explanation yet. */
	var shown_nav_explanation = false;
	
	/* Contains the slideshows themselves. */
	var $slider = $("#slider");
	var $sliders_container = $("#sliders");
	var $sliders = $(".slider", $slider);
	var $slides = $(".slide", $slider);
	var $images = $("img", $slider);
	var $active_slider;
	var current_slide;
	var current_collection;
	var current_collection_n;
	var last_collection_n = $menu_items.length;
	/* Whether to fade the sliders themselves in and out. */
	var fade_sliders = false;
	
	/* The arrows used to move to the next and previous slides. */
	var $arrow_prev = $("#arrow_prev");
	var $arrow_next = $("#arrow_next");
	
	/* The slider information. */
	var slider_data = window.slider_data;
	window.console && console.info("We Are Robey");
	window.console && console.info("Copyright (C) 2011, Robey Inc.");
	window.console && console.log("Slider data: %o", slider_data);
	
	/* Used to constantly keep the interface at the right size. */
	function updateSize()
	{
		var viewport_width = $(document).width();
		var viewport_height = $(document).height();
		viewport_width = viewport_width < min_width ? min_width : viewport_width;
		viewport_height = viewport_height < min_height ? min_height : viewport_height;
		var is_sub_1024 = viewport_width < 1024 || viewport_height < 768;
		
		var min = Math.sqrt(1024 * 768);
		var max = Math.sqrt(1440 * 900);
		var c = (Math.sqrt(viewport_width * viewport_height) - min) / (max - min);
		if (c < 0) c = 0;
		if (c > 1) c = 1;
		
		/* Modify the viewport so that we conform to valid proportions. */
		var item_info_w = $item_info_wrapper.width();
		var item_info_h = $item_info.height();
		var menu_pos = $menu_main.position();
		var last_menu_w = $("h2", $last_menu_item).width();
		var last_menu_pos = $last_menu_item.position();
		var interface_width = last_menu_pos.left + last_menu_w + menu_pos.left + 120 + item_info_w;
		
		/* Lots of complicated stuff because the way the menu needs to work is
		   counterintuitive. */
		var last_menu_offset = $last_menu_item.offset();
		$item_info_wrapper.css({left: (last_menu_offset.left + 36 + last_menu_w)+"px", top: (last_menu_offset.top - 20)+"px"});
		
		//var viewport_base = resizeWithinArea(2000 - (500 * c), 1200, viewport_width, viewport_height, "inside");
		var viewport_base = resizeWithinArea(interface_width, viewport_height, interface_width, viewport_height, "inside");
		if (viewport_height <= viewport_base.height) {
			viewport_width = viewport_base.width;
			viewport_height = viewport_base.height;
		}
		
		if (is_sub_1024) {
			$interface.attr({"class": "w1024"});
		} else {
			$interface.attr({"class": ""});
		}
		
		current_height = viewport_height;
		var prop_base = resizeWithinArea(base_width, base_height, 99999, current_height, "inside");
		var img_base = resizeWithinArea(image_width, base_height, 99999, current_height, "inside");
		if (prop_base.width > viewport_width) {
			prop_base.width = viewport_width;
		}
		if (use_full_width) {
			prop_base.width = viewport_width;
		}
		
		/* Set everything to the correct size. */
		$interface.css({width: prop_base.width+"px", height: prop_base.height+"px", marginLeft: -((prop_base.width / 2) << 0)+"px"});
		$sliders.css({width: img_base.width+"px"});
		$slides.css({width: img_base.width+"px", height: img_base.height+"px"});
		var image, size;
		for (var a = 0, z = $images.length; a < z; ++a) {
			image = $images[a];
			size = $.data(image, "s");
			image.width = size.w * (img_base.width / image_width);
			image.height = size.h * (img_base.height / base_height);
		}
		$sliders_container.css({marginLeft: (((prop_base.width - img_base.width) / 2) << 0) + "px"});
	}
	
	function processImages()
	{
		$images.each(function()
		{
			var w_h = $(this).attr("class").split("_");
			$.data(this, "s", {w: Number(w_h[0]), h: Number(w_h[1])});
		});
	}
	
	/* Used for resizing objects proportionally. */
	function resizeWithinArea(itemW, itemH, areaW, areaH, position)
	{
		if (position == null) {
			position = "inside";
		}
		if (itemW == 0 || itemH == 0 || areaW == 0 || areaH == 0) {
			// FIXME: 0 should mean "any size" in context of area.
			return;
		}
		var ratio = (areaW / areaH) > (itemW / itemH);
		var c = (position == "outside" && ratio) || (position == "inside" && !ratio) ? itemW / areaW : itemH / areaH;
		var w = itemW / c;
		var h = itemH / c;
		return {width: Math.round(w), height: Math.round(h), x: Math.round((areaW - w) / 2), y: Math.round((areaH - h) / 2), position: position};
	}
	
	/* Used to set the top-right explanation text of a slide. */
	function setSlideText(title, text, show_text)
	{
		if (show_text == null) {
			show_text = true;
		}
		if (show_text) {
			if (title != null && text != null) {
				var html_title, html_text, first_modification = false;
				if (shown_nav_explanation == false) {
					html_title = "";
					html_text = "<p><img src=\""+window.site_url+"resources/images/interface/keyboard-buttons.png\"></p><p>Navigate this site<br>by using keyboard controls.</p>";
					shown_nav_explanation = true;
					first_modification = true;
				} else {
					html_title = title;
					html_text = "<p>"+text.split("\r\n").join("\n").split("\n\n").join("</p><p>").split("\n").join("<br>")+"</p>";
				}
				if (first_modification) {
					$item_title.text(html_title);
					$item_text.html(html_text);
				} else {
					$item_info.fadeOut(function()
					{
						$item_info.fadeTo(400, 1, function()
						{
							/* Fix IE bug. */
							$item_info.css({filter: ""});
						});
						$item_title.text(html_title);
						$item_text.html(html_text);
					});
				}
			}
			$item_info.fadeTo(400, 1, function()
			{
				/* Fix IE bug. */
				$item_info.css({filter: ""});
			});
		} else {
			$item_info.fadeTo(400, 0);
		}
		updateSize();
	}
	
	/* Set a background as the default. */
	function setDefaultBackground($bg)
	{
		bg_curr = $bg.attr("id");
		window.console && console.log("Setting default background: %s.", bg_curr);
		$background_images.css({zIndex: bg_z});
		$bg.css({zIndex: ++bg_z});
	}
	
	/* Fades to a certain background. */
	function setBackground($bg)
	{
		var new_bg = $bg;
		if (typeof $bg != "string") {
			new_bg = $bg.attr("id");
		} else {
			new_bg = "bg_" + $bg;
			$bg = $("#" + new_bg);
		}
		if (new_bg == bg_curr) {
			return;
		}
		window.console && console.log("Switching from background %s to background: %s.", bg_curr, new_bg);
		$background_images.css({zIndex: bg_z});
		$("#"+bg_curr).css({zIndex: ++bg_z});
		bg_curr = new_bg;
		$bg.hide();
		$bg.css({zIndex: ++bg_z});
		$bg.fadeIn();
	}
	
	function stepActiveSlider(n)
	{
		if ($active_slider == null) {
			return;
		}
		stepSlide($active_slider, n);
	}
	
	function stepSlide($slider, n)
	{
		is_moving = true;
		var slider_amount = $(".slide-container .slide", $slider).length;
		var $new_collection;
		var going_back = false;
		if (current_slide + n >= slider_amount || (current_slide + n < 0 && current_collection_n > 0)) {
			$new_collection = $(".slider.n-"+(current_collection_n + n), $sliders_container);
			if ($new_collection[0] == null) {
				/* This only happens when going from the last item to the first item (wrapping back to the start). */
				$new_collection = $(".slider.n-0", $sliders_container);
			}
		}
		if (current_slide + n < 0) {
			$new_collection = $(".slider.n-"+(current_collection_n - 1 < 0 ? last_collection_n - 1 : current_collection_n - 1), $sliders_container);
			going_back = true;
		}
		if ($new_collection != null && $new_collection[0]) {
			var collection = $new_collection.attr("id").split("_")[1];
			var $menu_items = $("a[href*="+collection+"]", $menu_subs);
			var $menu_item;
			if (going_back) {
				return openSlide(collection, slider_data[collection].items.length - 1, -1);
			} else {
				$menu_item = $($menu_items[0]);
			}
			if ($menu_item[0] == null) {
				$menu_item = $($("a[href*="+collection+"]", $menu_container)[0]);
			}
			$menu_item.click();
			return;
		}
		return moveSlide($slider, current_slide + n, false, n);
	}
	
	function moveSlide($slider, n, changing_collection, direction)
	{
		var a, z;
		var $slide_container = $(".slide-container", $slider);
		var $slide = $(".slide.n-"+n, $slider);
		direction = direction == null ? 0 : direction;
		changing_collection = changing_collection == null ? false : changing_collection;
		if ($slide[0] == null) {
			return false;
		}
		current_slide = n;
		var data = slider_data[current_collection].items[n];
		/* If changing the background (or collection) do a different transition that hides the "box" around the images. */
		var change_bg = "bg_"+data.bg != bg_curr || changing_collection;
		var performed_bg_change = false;
		for (a = 0, z = $slides.length; a < z; ++a) {
			if ($slides[a] != $slide[0] && $.data($slides[a], "v")) {
				$($slides[a]).stop().fadeTo(change_bg ? 200 : slide_time, 0, slide_ease, function()
				{
					$(this).css({visibility: "hidden"});
					$.data(this, "v", false);
					if (performed_bg_change == false) {
						performed_bg_change = true;
						setBackground(data.bg);
					}
				});
			}
		}
		_activateNewSlide($slide, $slide_container, data, n, change_bg, direction, changing_collection);
	}
	
	function _activateNewSlide($slide, $slide_container, data, n, change_bg, direction, changing_collection)
	{
		/* Preload images. */
		direction = direction == null ? 0 : direction;
		changing_collection = changing_collection == null ? false : changing_collection;
		loadImage($('img', $slide));
		loadImage($('img', $slide.next()));
		loadImage($('img', $slide.prev()));
		$.data($slide[0], "v", true);
		$slide.css({visibility: "visible"});
		var sc_d = 0, s_d = 0;
		if (change_bg) {
			sc_d = slide_time / 4;
			s_d = slide_time / 4;
		}
		if (changing_collection) {
			/* Minor hack. Fix later. Maybe. */
			if (direction == 0) {
				direction = 1;
			}
			if (direction == 1) {
				$slide_container.css({left: (100)+"%"});
			}
			if (direction == -1) {
				/* Move to the back of the slider. */
				var items_amount = $(".slide", $slide_container).length;
				$slide_container.css({left: (-100 * items_amount)+"%"});
			}
		}
		$slide_container.delay(sc_d).animate({left: -(n * 100) + "%"}, {duration: slide_time, easing: slide_ease});
		$slide.stop().delay(s_d).fadeTo(slide_time, 1, slide_ease, function()
		{
			is_moving = false;
		});
		setSlideText(data.title, data.text, data.show_text);
	}
	
	function openSlide(collection, n, direction)
	{
		window.console && console.log("Opening slider \"%s\", item #%d.", collection, n);
		is_moving = true;
		var a, z;
		direction = direction == null ? 0 : direction;
		current_slide = n;
		var changing_collection = collection != current_collection && collection != null && current_collection != null;
		current_collection = collection;
		current_collection_n = Number($(".menu-item.type-"+collection, $menu_container).attr("class").match(/n-(\S+)/)[1]);
		var $s = $("#item_"+collection);
		if ($active_slider == null || $active_slider[0] != $s[0]) {
			window.console && console.log("Setting active slider to %s.", collection);
			$active_slider = $s;
		}
		/* Hide the other sliders. */
		if (fade_sliders) {
			for (a = 0, z = $sliders.length; a < z; ++a) {
				if ($sliders[a] != $active_slider[0] && $.data($sliders[a], "v")) {
					$($sliders[a]).fadeOut();
				}
			}
		}
		$.data($active_slider[0], "v", true);
		moveSlide($active_slider, n, changing_collection, direction);
		if (fade_sliders) {
			$active_slider.fadeIn();
		}
	}
	
	function setHandlers()
	{
		/* Sets up most of the actual code. */
		window.console && console.log("Setting up handlers.");
		
		/* Set minimum widths and heights. */
		$background_images.css({minHeight: min_height+"px"});
		$wrapper.css({minHeight: min_height+"px", minWidth: min_width+"px"});
		
		/* Processes the images and stores their actual sizes. */
		processImages();
		
		/* Set some basic properties. */
		$sliders.each(function()
		{
			$.data(this, "v", false);
		});
		$slides.each(function()
		{
			$.data(this, "v", false);
		});
		$slides.css({visibility: "hidden"});
		$slides.fadeTo(0, 0);
		
		/* The menu handler. */
		$menu_container.fadeTo(0, 0);
		$menu_area.mouseenter(function()
		{
			$menu_container.stop().fadeTo(400, 1, function()
			{
				$menu_container.css({filter: ""});
			});
		});
		$menu_area.mouseleave(function()
		{
			window.console && console.log("Hiding menus.");
			$menu_subs.stop().fadeTo(400, 0);
			$menu_container.stop().fadeTo(400, 0);
		});
		
		/* When hovering menu items, show their submenu. */
		var sub_index = 1;
		$menu_items.each(function()
		{
			var $menu_item = $(this);
			var $sub = $(".sub", $menu_item.parents(".menu-item")[0]);
			$menu_item.mouseenter(function()
			{
				window.console && console.log("Enter menu item: %s.", $menu_item.text());
				var a, z;
				for (a = 0, z = $menu_subs.length; a < z; ++a) {
					if ($menu_subs[a] != $sub[0]) {
						$($menu_subs[a]).stop().fadeTo(400, 0);
					}
				}
				$sub.stop().css({zIndex: ++sub_index}).fadeTo(400, 1, function()
				{
					$(this).css({filter: ""});
				});
			});
			$menu_item.click(function()
			{
				/* Open the first item in case we click the main item. */
				var $this = $(this);
				if ($this.hasClass("single")) {
					var href = $this.attr("href");
					href = href.split("_");
					openSlide(href[1], 0);
				} else {
					$("a:first", $sub).click();
				}
				return false;
			});
		});
		$menu_sub_links.each(function()
		{
			var $menu_sub_item = $(this);
			$menu_sub_item.click(function()
			{
				var href = $menu_sub_item.attr("href");
				href = href.split("_");
				openSlide(href[1], parseInt(href[2], 10));
				return false;
			});
		});
		
		/* Allow the arrows to move the slider. */
		$arrow_prev.click(function()
		{
			if (is_moving) {
				return false;
			}
			stepActiveSlider(-1);
			return false;
		});
		$arrow_next.click(function()
		{
			if (is_moving) {
				return false;
			}
			stepActiveSlider(1);
			return false;
		});
		
		/* Listen for keyboard events. */
		var key_left = 37;
		var key_right = 39;
		$(document).keydown(function(e){
			if (e.keyCode == key_left) { 
				$arrow_prev.click();
				return false;
			}
			if (e.keyCode == key_right) { 
				$arrow_next.click();
				return false;
			}
		});
		
		/* Preload the first image of each slider. */
		$sliders.each(function(n, slider)
		{
			var $first_image = $($("img", slider)[0]);
			loadImage($first_image);
		});
		
		/* Update the size and keep it up-to-date. */
		updateSize();
		$(window).bind("resize", function()
		{
			updateSize();
		});
		var updateInterval = setInterval(updateSize, 50);
	}
	
	function openDefaultPage()
	{
		var $first_item = $($menu_items[0]);
		$first_item.click();
		updateSize();
	}

	function loadImage($element)
	{
		if ($element.attr("data-loaded") == "0")
		{
			$element.attr("src", $element.attr("data-source"));
			$element.attr("data-loaded", "1");
		}
	}
	
	/* The main code. */
	function main()
	{
		$wrapper.show();
		$wrapper.fadeTo(0, 0);
		setDefaultBackground($bg_gray);
		
		/* This sets up most of the code. */
		setHandlers();
		setSlideText();
		
		/* Open the first page. */
		openDefaultPage();
		
		/* Now make everything appear. */
		$loading.fadeOut();
		$wrapper.fadeTo("slow", 1, function()
		{
			if ($.browser.msie == true && parseInt($.browser.version, 10) <= 8) {
				/* Minor fix for IE7: make sure the wrapper has no filter CSS attribute. */
				$wrapper.css({filter: ""});
			}
		});
	}
	
	main();
});
