// AJAX Support v1.0
// Andrew Pettican (April 2010)
// NB: This is a core script, and is relied upon by other scripts.
//
// Changelog:
// v1.0 - 09/04/2010 - Initial build
//////////////////////////////////////////////////////////////////

// ---------------------------------------------------------------
// Parameters
// ---------------------------------------------------------------

var as_url_ext = ".html"; // The required file extension of all urls loaded via the AJAX in this script
var as_location_hash_changed = false; // Flag indicating if the location hash was changed by this script
var as_trigger_ajax = true; // Flag indicating if ajax should be triggered at the current time
var as_first_initialisation = true; // Flag indicating if the next initialisation will be the first one this script runs
var as_last_location_hash = ""; // The last location hash we polled
var as_current_segments = []; // An array of segments indicating which document we are looking at
var as_init_delay = 50; // We delay initialisation for a fraction of a second to ensure the load_page function can be triggered if needed
var as_init_timer = null; // Initialisation timer

// ---------------------------------------------------------------
// Parameters End
// ---------------------------------------------------------------



// ---------------------------------------------------------------
// JS Events
// ---------------------------------------------------------------

jQuery(document).ready(function()
{
	// Whenever the hash element of the url is changed, trigger a page load
	$(window).bind('hashchange', function(event)
	{
		// What is the new location hash?
		var new_location_hash = this.location.hash;
		
		// Debug
		if(gs_debug_mode) {
			$('#hash').html(new_location_hash);
		}
		
		// If we didnt change the location hash, the user must have directly changed the address bar.
		// Load the relevant page
		if(as_trigger_ajax && !as_location_hash_changed)
		{
			if(load_page(new_location_hash))
			{
				// Initialise the page if the AJAX load fails
				initialise_page();
				
				// Store our current location segments, other scripts (detail_layer_support) rely on this array.
				as_current_segments = current_location.split("/", 8);
			}
		}
		
		// We can now be sure that the current page matches the requested new location hash
		as_last_location_hash = new_location_hash;
		as_location_hash_changed = false;
		as_trigger_ajax = true;
	});
	
	
	// Trigger a hashchange event to initialise the current page based on the hash value in the url
	// If there is no hash, load_page will automatically use the url instead
	$(window).trigger('hashchange');
	
	
	// Load certain links via AJAX
	$('a').live("click", function(event)
	{
		// Load the new page via AJAX?
		if(!$(this).hasClass("no_ajax") && $(this).attr('target') == "" && $(this).attr('rel') == "")
		{
			// NB: This will return true if the url cannot be loaded via AJAX, thereby allowing the browser to reload the page without AJAX
			var load_result = load_page(this.href);
			return load_result;
		}
	});
	
	
	// Does the page need initialising? (Not required - I think!)
	// It will not if a load_page event was triggered
	// We will delay this test for a fraction of a second to ensure the load_page function can be triggered if needed
	// This is necessary to prevent two initialisations from executing if a page like "clients.html#contact" is loaded
	/*
	as_init_timer = setTimeout(function()
	{
		if(as_current_segments.length === 0)
		{
			initialise_page();
			
			// Store our current location segments, other scripts (detail_layer_support) rely on this array.
			as_current_segments = current_location.split("/", 8);
			
			as_init_timer = null;
		}
	}, as_init_delay);
	*/
});

// ---------------------------------------------------------------
// JS Events End
// ---------------------------------------------------------------



// ---------------------------------------------------------------
// Functions
// ---------------------------------------------------------------

/**
 * Loads the requested page via AJAX
 */
function load_page(url_or_hash)
{
	//alert('lp: '+url_or_hash);
	// Are we dealing with a hash or a url?
	// By the end of this, we should know what the requested hash is
	var target_url_hash = "";
	var target_url_ext = "";
	var validated_inputs = false;
	
	if(url_or_hash.length > 1)
	{
		if(url_or_hash.substr(0, 1) == "#")
		{
			// Dealing with a hash
			target_url_hash = url_or_hash.substr(1);
			target_url_ext = as_url_ext;
			validated_inputs = true;
		}
		else
		{
			// Dealing with a url.
			// NB: this will strip out any information after the hash, we focusing on the url address only
			var target_url_full = unescape(url_or_hash);
			var target_url_hash_index = target_url_full.indexOf("#");
			if(target_url_hash_index !== -1)
			{
				target_url_full = target_url_full.substr(0, target_url_hash_index);
			}
			
			// Break up the url and determine if its is valid for use in this AJAX routine
			var target_url_base = target_url_full.substr(0, base_url.length);
			target_url_hash = target_url_full.substr(base_url.length, target_url_full.length-base_url.length-as_url_ext.length);
			target_url_ext = target_url_full.substr(base_url.length+target_url_hash.length);
			//alert(current_location+"\n\n"+target_url_full+"\n\n"+target_url_base+"\n\n"+target_url_hash+"\n\n"+target_url_ext);
			
			// Do not go any further if the target is the same as the current location
			if(target_url_hash == current_location && !as_first_initialisation)
			{
				return false;
			}
			
			// Otherwise validate the url
			else
			{
				validated_inputs = (target_url_base == base_url && target_url_ext == as_url_ext);
			}
		}
	}
	else
	{
		// A blank hash was supplied. Call this function again with the actual url (providing its not blank too)
		if(location.href !== "")
		{
			return load_page(location.href);
		}
		
		return true;
	}
	
	// Only continue if we found a hash to use
	validated_inputs = (validated_inputs && target_url_hash != "");
	if(validated_inputs)
	{
		// Determine the previous and new current (target) segments (up to 8 levels)
		var previous_segments = (as_first_initialisation ? [] : current_location.split("/", 8));
		as_current_segments = target_url_hash.split("/", 8);
		var previous_segments_count = previous_segments.length;
		var current_segments_count = as_current_segments.length;
		
		// Count how many of the current and target url segments match each other?
		// NB: we will stop counting at the first mismatch.
		// e.g. 
		//  - [work] vs [work,inflexion] = 1
		//  - [work,inflexion] vs [work,inflexion,website] = 2
		//  - [work,inflexion,website] vs [work,inflexion,website] = 3
		//  - [work,zelens,website] vs [work,inflexion,website] = 1 (even though 'website' is in both arrays, the 2nd parameter is a mismatch, so we don't consider the 3rd)
		var segment_matching_levels_index = 0; // The number of segment levels which match
		while(previous_segments_count > 0 && current_segments_count > 0)
		{
			if(previous_segments[segment_matching_levels_index] == as_current_segments[segment_matching_levels_index])
			{
				segment_matching_levels_index++;
			}
			else
			{
				break;
			}
			previous_segments_count--;
			current_segments_count--;
		}
		//alert(previous_segments+"\n"+as_current_segments+"\n"+segment_matching_levels_index);
		
		// Update the url hash
		set_location_hash(target_url_hash);
		
		// Based on the segments, decide which elements will be reloaded.
		// By default, all elements will be reloaded. 
		// However, if 1 or more segments are matching, we may not want to reload certain elements.
		// This is decided on a case-by-case basis, add extra rules to the previous_segments[0] 'if' statement below if necessary.
		var reload_nav = true;
		var reload_strip = true;
		var reload_detail = true;
		
		// A callback function which will run after the page data has been loaded
		// We use this to update the page title when the page has reloaded
		reload_callback = function()
		{
			// Update the page title
			// NB: We must use the .text() method here to get the title without any html entity encoding,
			// the browser automatically applies this encoding when document.title is set.
			document.title = gs_title_prefix+$("#breadcrumb_trail").text();
			fleXenv.initByClass("flexcroll");
		};
		
		if(segment_matching_levels_index > 0) 
		{
			// We will decide what to do based on the first segment
			if(previous_segments[0] == "work")
			{
				if(segment_matching_levels_index == 1) 
				{
					// Do not reload the nav or strip
					reload_nav = false;
					reload_strip = false;
				}
				else if(segment_matching_levels_index > 1) 
				{
					// Do not reload anything
					reload_nav = false;
					reload_strip = false;
					reload_detail = false;
				}
				
				// Set a callback after the load has completed
				reload_callback = function()
				{
					// NB: detail_layer_support will update the <title> tag instead of us
					// NB: We must use the .text() method here to get the title without any html entity encoding,
					// the browser automatically applies this encoding when document.title is set.
					//document.title = gs_title_prefix+$("#breadcrumb_trail").text();
					
					// Updates based on the active client
					$("#company_list li").removeClass("active");
					var breadcrumb_trail = "";
					if(as_current_segments.length > 1)
					{
						// Set the active client
						$("#company_list li#company_list-"+as_current_segments[1]).addClass("active");
						
						// Hide the list of companies from print view if we are viewing a company
						$('.strip_text').addClass('screen_only');
						
						// Determine the breadcrumbs (based on active nav links)
						breadcrumb_trail = $("#nav_list-"+as_current_segments[0]+" a:first").html() + " › " + $("#company_list li#company_list-"+as_current_segments[1]+" a:first").html();
					}
					else
					{
						// Show the list of companies in print view if we are not viewing a company
						$('.strip_text').removeClass('screen_only');
						
						// Determine the breadcrumbs (based on active nav links)
						breadcrumb_trail = $("#nav_list-"+as_current_segments[0]+" a:first").html();
					}
					
					// Update the page breadcrumb trail
					$('#breadcrumb_trail').html(breadcrumb_trail);
					
					// Update the page title
					// NB: We must use the .text() method here to get the title without any html entity encoding,
					// the browser automatically applies this encoding when document.title is set.
					document.title = gs_title_prefix+$('#breadcrumb_trail').text();
					
					// Trigger a hover out on all company list elements to ensure they get the correct updated styling
					$('#company_list li a').trigger('mouseout');
					
					// Navigate to the correct slide if:
					// - This is not our first initialisation
					// - There are multiple detail layers to navigate between
					// - The segments in the url are pointing to a specific slide (there must be 2+ segments for this)
					if(!as_first_initialisation && $('#detail_layers .detail_layer').length > 0 && as_current_segments.length > 1)
					{
						var target_slide = build_slide_id_from_segments(as_current_segments);
						if(target_slide != "")
						{
							var target_slide_index = $("#detail_layers .detail_layer").index($("#"+target_slide));
							if(target_slide_index >= 0 && target_slide_index < $("#detail_layers .detail_layer").length)
							{
								$('#detail_layers').cycle(target_slide_index);
								
								// Debug
								if(gs_debug_mode) {
									$('#debug').html($('#debug').html() + ", c"+target_slide_index);
								}
							}
						}
					}
				};
			}
		}
		
		// Do we need to reinitialise the page with AJAX?
		var reload_callback_executed = false;
		if(reload_nav || reload_strip || reload_detail)
		{
			// This is the first page initialisation
			if(as_first_initialisation)
			{
				// Load the correct background image
				$('#bg_image').load(target_url_hash+target_url_ext+' #bg_image img:last');
				
				// Load the page
				load_page_elements(target_url_hash+target_url_ext, reload_nav, reload_strip, reload_detail, reload_callback);
			}
			
			// This is not the first page initialisation, the page must be uninitialised first
			else
			{
				// Uninitialise the page, optionally using a new background image.
				// Determine what the new background will be
				$('#bg_image_tmp').load(target_url_hash+target_url_ext+' #bg_image img:last', function()
				{
					// Is the background image different to the current one?
					var old_bg_id = $('#bg_image img:last').attr('id');
					var new_bg_id = $('#bg_image_tmp img:last').attr('id');
					var new_bg_img = "";
					if(typeof(new_bg_id) == "string" && old_bg_id != new_bg_id && new_bg_id != "")
					{
						new_bg_img = new_bg_id.substr(gs_bg_img_prefix.length);
					}
					
					// Uninitialise the required elements of the page
					uninitialise_page(reload_nav, reload_strip, reload_detail, new_bg_img, function()
					{
						// Reload the required data via AJAX
						load_page_elements(target_url_hash+target_url_ext, reload_nav, reload_strip, reload_detail, reload_callback);
					});
				});
			}
		}
		
		// Do we need to call the reload callback?
		else if(!reload_callback_executed && (typeof(reload_callback) == "function"))
		{
			reload_callback();
			reload_callback_executed = true;
		}
		
		return false;
	}
	
	// Something failed...
	return true;
}


/**
 * Loads the requested page elements from the local url and initalises the page once they are ready
 * NB: callback may be set to execute extra code after all of the elements are loaded.
 */
function load_page_elements(local_url, load_nav, load_strip, load_detail, callback)
{
	// Flag indicating if the callback function needs to be executed
	var execute_callback = (typeof(callback) == "function");
	
	// Reload the nav layer?
	if(load_nav)
	{
		$('#nav').load(local_url+' #nav_ajax', function()
		{
			// Attempt initialisation (if we have loaded all required elements)
			load_nav = false;
			if(!load_nav && !load_strip && !load_detail)
			{
				initialise_page();
				
				// Execute the callback?
				if(execute_callback)
				{
					// Debug
					if(gs_debug_mode) {
						$('#debug').html($('#debug').html() + ", lpcb");
					}
					
					execute_callback=false;
					callback();
				}
			}
		});
	}
	
	// Load the strip layer?
	if(load_strip)
	{
		$('#strip').load(local_url+' #strip_ajax', function()
		{
			// Attempt initialisation (if we have loaded all required elements)
			load_strip = false;
			if(!load_nav && !load_strip && !load_detail)
			{
				initialise_page();
				
				// Execute the callback?
				if(execute_callback)
				{
					// Debug
					if(gs_debug_mode) {
						$('#debug').html($('#debug').html() + ", lpcb");
					}
					
					execute_callback=false;
					callback();
				}
			}
		});
	}
	
	// Load the detail layer?
	if(load_detail)
	{
		$('#detail').load(local_url+' #detail_ajax', function()
		{
			// Attempt initialisation (if we have loaded all required elements)
			load_detail = false;
			if(!load_nav && !load_strip && !load_detail)
			{
				initialise_page();
				
				// Execute the callback?
				if(execute_callback)
				{
					// Debug
					if(gs_debug_mode) {
						$('#debug').html($('#debug').html() + ", lpcb");
					}
					
					execute_callback=false;
					callback();
				}
			}
		});
	}
	
}


/**
 * Sets the location hash in the browsers address bar
 */
function set_location_hash(new_hash, trigger_ajax)
{
	// We must protect against this function being called multiple times with the same hash
	if(current_location != new_hash)
	{
		// Should ajax be triggered to load the updated page represented in the hash? (default: true)
		trigger_ajax = (typeof(trigger_ajax) == "boolean") ? trigger_ajax : true;
		as_trigger_ajax = trigger_ajax;
		
		window.location.hash = new_hash;
		current_location = new_hash;
		as_location_hash_changed = true;
//		alert(current_location);
	}
}


/**
 * Helper function to return the requested segment from the segments array
 */
function get_segment(index, segments)
{
	if(index > 0 && index < segments.length)
	{
		return segments[index];
	}
	return "";
}

// ---------------------------------------------------------------
// Functions End
// ---------------------------------------------------------------
