$(document).ready(function() {
	
	// Try to prevent flashing of initial HTML before the new content loads, we don't want to hide via CSS as it will be hidden if JS is disabled
	$('.display').hide();
	
	/**
		Deep linking via jQuery Address - jquery.address-1.0.min.js
		http://www.asual.com/jquery/address/
	*/
	
	initialLoad = true;
	directions = Array('up', 'down', 'left', 'right');
	currentDirection = "random"; // if changing this default, it's defined again down in the test for a valid rel direction
	
	$.address.change(function(event) {
		var targetAjaxURL = ajaxURL(event.value); // convert the target URL to the AJAX path
		
		if (initialLoad === true) { // arrived directly at this page
			$.event.trigger('slide_start', targetAjaxURL);
			
			$.get(targetAjaxURL, {}, function(data) {
				var displayDiv = $('.display');
				
				displayDiv.html(data);
				
				$.event.trigger('slide_loaded', targetAjaxURL);
				
				displayDiv.show();
					
				$.event.trigger('slide_complete', targetAjaxURL);
			});
			
			initialLoad = false;
		} else {
			slideContent(targetAjaxURL, currentDirection); // trigger the fancy sliding content effect
		}
	});
	
	$("#navigation li a, a[rel~='slide']").live('click', function() {  
		var targetAddress = stripURL($(this).attr('href')); // make sure ie7/6 reports the correct URL
		
		if (targetAddress !== $.address.path()) {
			var slideDir = getValidDirection($(this).attr('rel'));
			
			if (slideDir !== "") { // we have a new valid direction in the link rel
				currentDirection = slideDir;
			} else {
				currentDirection = "random";
			}
			
			$.address.value(targetAddress);			
		}
		
		return false;
	});
	
	// use the slider event hooks to start/stop the activity indicator
	$('#loader').bind('slide_start', function() {
		$(this).show();
	}).bind('slide_loaded', function() {
		$(this).hide();
	});
	
});

function slideContent(link, dir)
{
	var wrapper = $('#container');
	var slider = $('#slider');
	
	var wrapperHeight = wrapper.css('height');
	var wrapperWidth = wrapper.css('width');
	
	var displayContent = $('.display');
	
	if (dir === 'random') {
		dir = directions[Math.floor(Math.random() * directions.length)];
	}
	
	$.event.trigger('slide_start', [link]); // define custom event hook
	
	// figure out the new position of the sliding window
	if (dir === 'left') {
		var sliderTop = stripPx(slider.css('top'));
		var sliderLeft = subtractDimension(slider.css('left'), wrapperWidth);
	} else if (dir === 'right') {
		var sliderTop = stripPx(slider.css('top'));
		var sliderLeft = addDimension(slider.css('left'), wrapperWidth);
	} else if (dir === 'up') {
		var sliderTop = subtractDimension(slider.css('top'), wrapperHeight);
		var sliderLeft = stripPx(slider.css('left'));
	} else if (dir === 'down') {
		var sliderTop = addDimension(slider.css('top'), wrapperHeight);
		var sliderLeft = stripPx(slider.css('left'));
	}
	
	// figure out the new position of the loaded content div
	if (dir === 'left') {
		var loadTop = stripPx(displayContent.css('top'));
		var loadLeft = addDimension(displayContent.css('left'), wrapperWidth);
	} else if (dir === 'right') {
		var loadTop = stripPx(displayContent.css('top'));
		var loadLeft = subtractDimension(displayContent.css('left'), wrapperWidth);
	} else if (dir === 'up') {
		var loadTop = addDimension(displayContent.css('top'), wrapperHeight);
		var loadLeft = stripPx(displayContent.css('left'));
	} else if (dir === 'down') {
		var loadTop = subtractDimension(displayContent.css('top'), wrapperHeight);
		var loadLeft = stripPx(displayContent.css('left'));
	}
	
	// the new div is constructed in this ugly way to please IEs perverted tastes
	var newDiv = $('<div class="display" style="top: '+ loadTop +'px; left: '+ loadLeft +'px; height: '+ wrapperHeight +'px;"></div>').appendTo(slider);
	$.get(link, {}, function(data) {
		newDiv.html(data);
		
		$.event.trigger('slide_loaded', [link]);
		
		slider.animate({ top: sliderTop +"px", left: sliderLeft +"px" }, 1000, 'swing',  function() {
			displayContent.remove(); // delete the old content
			
			$.event.trigger('slide_complete', [link]); // define custom event hook
		});
	});
}

function subtractDimension(current, dimension)
{
	current = stripPx(current);
	dimension = stripPx(dimension);
	
	var newPos = current - dimension;
	
	return parseInt(newPos);
}

function addDimension(current, dimension)
{
	current = stripPx(current);
	dimension = stripPx(dimension);
	
	var newPos = current + dimension;
	
	return parseInt(newPos);
}

/**
	Is this value an integer?
	
*/
function isInt(x) {
	var y = parseInt(x);
	if (isNaN(y)) return false;
	return x == y && x.toString() == y.toString();
}

/**
	Remove 'px' from CSS values, also default 'auto' to '0' for IE
*/
function stripPx(val)
{
	if (val === 'auto') {
		val = 0;
	} if (!isInt(val)) {
		var pxpos = val.indexOf('px');
		if (pxpos > 0) {
			val = parseInt(val.substr(0, pxpos));
		} else {
			val = parseInt(val);	
		}
	}
	
	return val;
}

/**
 * stripURL
 * Remove all protocol and hostname information from the URL for IE7/6
 * @param {Object} targetURL
 */
function stripURL(targetURL)
{
	if (targetURL.indexOf('http') > -1) { // we've got a full URL
		targetURL = targetURL.substr(targetURL.indexOf('/', 8), targetURL.length);
	}
	
	return targetURL;
}

/**
 * ajaxURL
 * Prepend the 'ajax' path to the start of the URL
 * @param {Object} targetURL
 */
function ajaxURL(targetURL)
{
	return '/ajax'+ targetURL;
}

function getValidDirection(linkRel)
{	
	if (linkRel != "") {		
		linkRel = linkRel.split(' ');
		for (var i = 0; i < linkRel.length; i++) {
			for (var j = 0; j < directions.length; j++) {
				if (linkRel[i] === directions[j]) {
					return linkRel[i];
				}
			}
		}
	}
	
	return "";
}

/**
 * Determines if target navigation item exists, hides all others then shows target
 * @param {Object} targetLink
 */
function showNavigationItem(targetItem)
{
	if (targetItem.length > 0 && targetItem.filter(':visible').length == 0) { // exists and isn't already visible?
		targetItem.siblings().filter(':visible').fadeOut(function() {
			targetItem.fadeIn();
		});
	}
}