jQuery(document).ready(function() {
	jQuery.fn.log = function (msg) {
//		console.log("%s: %o", msg, this);
		return this;
	};

	// install mouse over effects for each block
	jQuery(".block .inside").not(".block.noclick .inside").hover(
		function() {
			var parent = jQuery(this).parents(".block");
			if (!parent.hasClass("clicked")) {
				parent.addClass("hover");
			}
		}, 
		function() {
			jQuery(this).parents(".block").removeClass("hover");
		}
	);
	
	installClickHandlers();
	
	// Enable the fragmentChange event.
	jQuery.fragmentChange(true);
	
	// Bind parse_fragment to the fragmentChange event (using a namespace in case
	// we need to unbind later).
	jQuery(document).bind( "fragmentChange", hashChange );
	
	// clicking the "read more >>" link in a block should trigger the click-event of the containing block
	jQuery("a.more").click(function(){
		jQuery(this).parents(".block:first").trigger("click"); 
		return false;
	});

	// blocks have a hand-pointer only when javascript is turned on (confusing otherwise)
	jQuery(".block, .menublock").not('.noclick').css({cursor:"pointer"});

	// call fragmentChange event now in case the document was loaded with a fragment
	hashChange();
});

var animation_speed = 600;
var animation_function = "easeOutQuad";

function installClickHandlers() {
	// attach a click-handler to each block
	jQuery(".block").not(".block.noclick").unbind().click(blockClick).log("install clickhandlers - block");

	// attach a click-handler to each menu item
	jQuery(".block .hidden.menu .sub").unbind().click(menuClick).log("install clickhandlers - menu");
	
	jQuery(".block .list.menu .sub").unbind().click(shortcutMenuClick).log("install clickhandlers - shortcut menu");
}

function hashChange() {
	var hash = window.location.hash.substring(1);

	if (hash.length>0) {
		var link_class = "a.sub." + hash;
		var block = jQuery(link_class).parents(".block").get(0);
		
		click_submenu = function() {
			jQuery(block).addClass("hover").addClass("clicked").trigger("click", [ link_class ]); 
		};
		
		if (!blockIsMenu(block)) {
			blockReset();
			var div = document.createElement("div");
			jQuery(div).animate(
					{opacity:1},
					animation_speed,
					animation_function, 
					click_submenu);
		} else {
			click_submenu();
		}
	}
}

function resetAnimation(i, elem, callback) {
	var jq = jQuery(elem);
	
	// show default text again
	if (jq.hasClass("clicked")) {
		jQuery("div.intro", elem).show('slide', {direction:'down'}, animation_speed); // EA - changed ul:first to div.intro
	} else {
		// unhide these blocks
		jq.css({opacity:0}).show();
	}
	
	jQuery(".corner").hide();
	
	var width = jq.outerWidth();
	width += parseInt(jq.css('marginRight'));
	var newLeft = -i*width;

	// determine what color the header should be at the end of the reset
	var headerColor = jQuery(".inside", elem).css("backgroundColor");
	
	// move all blocks to the leftmost-position, and animate them to their original positions
	jq.css({
		left:newLeft
	});

	// the blue block fades to white
	jQuery(".inside", elem).
		animate({
			backgroundColor:"transparent" 
		}, animation_speed, animation_function, function (x_i, x_elem) {
			jQuery(".block .inside").removeAttr("style");
			jQuery(".block").removeClass('clicked').removeClass('hover');							
		});

	// the text in the blue block fades to black
	jQuery(".inside .body", elem).
		animate({
			color:"black"
		}, animation_speed, animation_function, function() {
			jQuery(".inside .body", elem).removeAttr("style");
		});
	
	if (jq.hasClass("clicked")) {
		// and the header fades to the color of this block
		jQuery(".inside h2", elem).
		animate({
			color:headerColor
		}, animation_speed, animation_function, function() {
			jQuery(".inside h2", elem).removeAttr("style");
		});
	}

	// finally, move all blocks back to their original position and to full visibility
	jq.animate({
		left: 0,
		opacity: 1
	}, animation_speed, animation_function, function() {
		// defeat stupid IE cleartype bug (at least in IE8...)
		// http://blog.bmn.name/2008/03/jquery-fadeinfadeout-ie-cleartype-glitch/
		if (jQuery.browser.msie) {
			jQuery(this).get(0).style.removeAttribute('filter');
		}
		
		jQuery(".corner").show();

		if (jQuery.isFunction(callback)) {
			callback();
		}
	});
}

function allBlocksVisible() {
	var all_visible=true;
	jQuery(".block").each(function(i, elem) {
		if (!blockIsVisible(elem)) {
			all_visible = false;
		}
	});

	return all_visible;
}

function blockReset(callback) {
	if (!allBlocksVisible()) {
		// collapse all content
		jQuery(".content").fadeOut();
		
		installClickHandlers();
		
		jQuery(".block").not(".block.noclick").
			// reinstate 'hand' cursor for each block
			css({cursor:"pointer"});

		// remove menu from each block
		jQuery(".block").each(function(i, elem) {
			var hiddenmenu = jQuery(".hidden.menu", elem);
			
			if (hiddenmenu.size()>0) {
				hiddenmenu.hide('slide', {direction:'down'}, animation_speed, function() { 
					resetAnimation(i, elem, (i==0?callback:null));
				});
			} else {
				jQuery(elem).animate({opacity:0}, animation_speed, animation_function, function() {
					resetAnimation(i, elem, (i==0?callback:null));
				});
			}
		});
		
		// make sure the reset-functionality is not called when it is already in a reset state
		jQuery(".menu .current a").unbind().click(function(){return false;});
		
		// remove the 'current' class from each menu
		jQuery(".block .menu li").removeClass("current");
		
		setHash("");
	}
	
	// prevent 'default' link action
	return false;
}

function blockIsMenu(selector_or_element) {
	var elem = jQuery(selector_or_element).log("blockIsMenu");
	return (jQuery(".hidden.menu", elem).is(":visible"));
}

function blockIsVisible(selector_or_element) {
	var elem = jQuery(selector_or_element).log("blockIsVisible");
	return (elem.is(":visible")>0);
}

function blockClick(event, content_selector) {
	// make clicked element relatively positioned (so zIndex applies), 
	// and make sure it is on top
	jQuery(this).css({
		position: "relative",
		zIndex: 2
	}).removeClass("hover").addClass("clicked").log("click");

	var final_left = 0;
	
	if (!allBlocksVisible()) {
		// one or more blocks are already hidden
		showContent(content_selector);
	} else {
		// move each block to the position of the first block
		jQuery(".block").log("blockClick - move").each(function(i,elem){
			var jq = jQuery(elem);
		
			var width = jq.outerWidth();
			width += parseInt(jq.css('marginRight'));
			
			// determine which submenu should be displayed
			var content_element;
			if (!(content_selector==undefined)) {
				content_element = jQuery(content_selector);
			} else {
				// after the block has moved to the left show the content
				content_element = jQuery(".hidden.menu ul li:first a", elem);
			}
			content_element = content_element.get(0);
			
			if (jq.hasClass('clicked')) {
				final_left = -i*width;
		
				var self=this;
				jq.css({
					zIndex: 2,
					position: "relative"
				}).animate({
					left: -i*width
				}, animation_speed, animation_function, function() {
					// once the block has moved to the leftmost position, 
					// we hide the other blocks and 
					// correct the 'left' position of the clicked block 
					// other ways, the content won't be positioned correctly
					jQuery(".block").not(self).hide();
					jq.css({left: 0});
					
					// which content is shown depends on the CSS class of the block that was clicked:
					// 1. if it was named 'block first', then the content from a div with a CSS class 'content first' will be shown
					// 2. in case of a sub menu, multiple of these DIVs will be available. In that case, the first is shown.
					showContent(content_element);
				});
			} else {
				jq.css({
					zIndex: 1,
					position: "relative"
				}).
				animate({
					left: -i*width,
					opacity:0
				}, animation_speed, animation_function);
			}
		});
		
		if (jQuery(".hidden.menu:visible", self).size()==0) {
			// turn the block into a menu
			var self = this;
			jQuery("div.intro", self).hide('slide', {direction:'down'}, animation_speed, function() { // EA - ul:first changed to div.intro
				jQuery(self).css({cursor:"default"});
				if (jQuery(".hidden.menu", self).is(":hidden")) {
					jQuery(".hidden.menu", self).show('slide', {direction:'down'}, animation_speed);
				}
			});
		}
		
		// finally, turn the current menu item into a 'reset' button 
		jQuery("#menu .current a").click(blockReset);
	}
}

function shortcutMenuClick() {
	jQuery(this).parents(".block:first").addClass("hover").addClass("clicked").trigger("click", [ this ]);
	return false;
}

function menuClick() {
	showContent(this);

	// prevent default 'click' action
	return false;
}

function setHash(fragment) {
	// change the fragment
	window.location.hash = fragment;
}


function showContent(element, callback) {
	var jq = jQuery(element);

	var clicked_class = jq.attr("class");
	jQuery(".hidden.menu ul li").removeClass("current");
	jq.parent("li").addClass('current');

	var block_class = jq.parents(".block").attr("class");
	if (block_class) {
		block_class = jQuery.trim(block_class.replace("block ", "").replace('hover', '').replace('clicked', ''));
	
		// set the appropriate document hash
		var hash_class = clicked_class.replace("sub ", "");
		setHash(hash_class);
		
		var content_class = ".content." + block_class + "." + hash_class;
	
		var visible_content = jQuery(".content:visible").not(content_class);
		
		if (visible_content.size()>0) {
			visible_content.fadeOut("fast", function() {
				jQuery(content_class+":hidden").show('slide', {direction: 'left'}, animation_speed, animation_function);
			});
		} else {
			jQuery(content_class+":hidden").show('slide', {direction: 'left'}, animation_speed, animation_function);
		}

		// jQuery's "effects.slide" plugins doesn't support callbacks - so we do a bogus animation that takes 
		// the same amount of time, and provide the callback to that animation instead
		jQuery("body").animate({opacity:1}, animation_speed, animation_function, callback);

	}
}
