/*
 * Copy used to append to the end of a link's title attribute if it's to be opened in a new window
 */
var newwindow_copy = "opens in a new window";



/*
 * This symbol is used to identify a JavaScript generated (AJAX) bookmark
 * - This is incorporated with a hash symbol (anchor)
 */
var anchor_hash_addition_for_bookmarks = "";



/*
 * Generic "Find" used for mouse events
 */
function find_target(e) {
	var target;
	if(window.event  &&  window.event.srcElement) {
		target = window.event.srcElement;
	} else if(e  &&  e.target) {
		target = e.target;
	}
	if(!target) {
		return null;
	}
	return target;
}



/*
 * Retrieve the host from a URL
 * - If we had a proper 'location' object we could use built-in JS functions
 */
function retrieve_host_from_url(url) {
	if(url == "") {
		return "";
	}
	var protocol = "";
	if(url.substr(0, 7) == "http://") {
		protocol = "http://";
	} else if(url.substr(0, 8) == "https://") {
		protocol = "https://";
	} else if(url.substr(0, 6) == "ftp://") {
		protocol = "ftp://";
	}
	if(protocol == "") {
		return "";
	}
	var host = url.substr(protocol.length);
	host = host.substr(0, host.indexOf("/"));
	return host;
}
function supplied_host_different_to_website(url) {
	url = retrieve_host_from_url(url);
	return (url != window.location.hostname);
}



/*
 * Common AJAX code
 * - Registered / Used for all AJAX calls
 */
function show_loader() {
	Element.update("loader", "Loading...");
	Element.setStyle("loader", {display:'block'} );
}
function hide_loader() {
	Element.setStyle("loader", {display:'none'} );
	Element.update("loader", "");
}



/*
 * Mouseover / Out listener
 * - update status bar when mouseover / off
 * - add an 'onclick' event if the item has a 'target' defined (new window)
 */
function monitor_all_links() {
  // Get all of the links & inputs within the selected page
	var all_mouseovers = $$("a", "input");
  // Assign a listener to each link
	all_mouseovers.each(
		function(val) {
		  // If we have an input make sure it is a submit / reset / button or image
			if(val.type  &&  val.type != "submit"  &&  val.type != "reset"  &&  val.type != "button"  &&  val.type != "image") {
			  // This is not a required input type
				return;
			}
			Event.observe(val, "mouseover", title_in_status_bar_over);
			Event.observe(val, "mouseout", title_in_status_bar_out);
			if(val.className.indexOf("toplevel") != -1) {
				Event.observe(val, "mouseover", nav_over);
				Event.observe(val, "mouseout", nav_off);
			}
		  // If this is a link, should it open in a new popup window ('target' is defined)?
			if(val.className.indexOf("iwantatarget") == -1) {
				return;
			}
		  // As this item is going to open in a new window, we need to update the title text as well
			Event.observe(val, "click", new_popup_window);
			if($(val).title.indexOf(newwindow_copy) == -1) {
				if($(val).title.replace(" ", "") == "") {
					$(val).title = newwindow_copy;
				} else {
					$(val).title = $(val).title + " (" + newwindow_copy + ")";
				}
			}
		}
	);
}
var actually_overwrite_title_value = false;
function fake_and_return_title(obj) {
  // Update the status bar of the window, after checking we have a 'title' to display
  // - If no 'title' was found we will try to create one
	if(obj.title) {
		return obj.title;
	} else if(obj.parentElement  &&  obj.parentElement.title) {
		return obj.parentElement.title;
	} else if(obj.parentNode  &&  obj.parentNode.title) {
		return obj.parentNode.title;
	} else if(obj.innerHTML) {
	  // Make sure we strip out any HTML content
		var new_title = obj.innerHTML.replace(/<[\/\!]*?[^<>]*?>/ig, '');
		if(actually_overwrite_title_value) {
			obj.title = new_title;
		}
		return new_title;
	} else if(obj.type  &&  (obj.type == "submit"  ||  obj.type == "reset"  ||  obj.type == "button")  &&  obj.value) {
		var new_title = obj.value;
		if(actually_overwrite_title_value) {
			obj.title = new_title;
		}
		return new_title;
	} else if(obj.type  &&  obj.type == "image") {
		var new_title = obj.alt;
		if(actually_overwrite_title_value) {
			obj.title = new_title;
		}
		return new_title;
	} else if(obj.alt) {
		return obj.alt;
	}
	return "";
}
function wS(txt) {
	window.status = ((txt)?txt:'');
	return true;
}
function title_in_status_bar_over(e) {
  // I want to make sure everything is fully loaded before this code is run
  // - Firefox sometimes reports errors with missing functions - not sure why at the moment
	if(typeof find_target == "undefined") {
		return;
	}
	var target = find_target(e);
	if(!target) {
		return;
	}
	var title_attribute = fake_and_return_title(target);
	return wS(title_attribute);
}
function title_in_status_bar_out(e) {
  // I want to make sure everything is fully loaded before this code is run
  // - Firefox sometimes reports errors with missing functions - not sure why at the moment
	if(typeof find_target == "undefined") {
		return;
	}
	return wS();
}
function new_popup_window(e) {
	var target = find_target(e);
	if(!target  ||  !target.href  ||  target.href.indexOf(".gif") != -1  ||  target.href.indexOf(".jpg") != -1  ||  target.href.indexOf(".png") != -1) {

	  // Check to see if this is returning an image so a HREF does not exist
		if(target  &&  (target.tagName.toLowerCase() == "img"  ||  target.href.indexOf(".gif") != -1  ||  target.href.indexOf(".jpg") != -1  ||  target.href.indexOf(".png") != -1)  &&  target.parentNode) {
		  // Double-check this is not the MacUser popup article
			if(!(target.href  &&  target.href.indexOf("/img/scans/macuser-tommie.jpg") != -1)) {
			  // As an image was found, the link should be the parent element
				target = target.parentNode;
			}
		}

	  // Double-check before running the non-JavaScript version
		if(!target  ||  !target.href) {
		  // No 'target' or URL was found
			return;
		}
	}
	if(!target.href  &&  target.parentNode) {
	  // We've probably got an image reference here (child)!
		target = target.parentNode;
	}
	if(target.href) {
		var popup_width = 1000;
		var popup_height = 700;
		var params = 
			"width=" + popup_width +
			",height=" + popup_height +
			",left=" + ((screen.width)?(screen.width-popup_width)/2:0) +
			",top=" + ((screen.height)?((screen.height-popup_height)/2)-30:0) +
			",scrollbars=yes" +
			",toolbar=yes" +
			",resizable=yes" +
			",status=yes" +
			",menubar=yes" +
			",location=yes";
		var popupName = window.open(target.href, "_blank", params);
		if(popupName) {
			popupName.focus();
			Event.stop(e);
		}
	}
}
function return_child_image_object(link_object) {
	if(!link_object.firstChild  ||  !link_object.firstChild.tagName  ||  link_object.firstChild.tagName.toLowerCase() != "img") {
		return null;
	}
	return link_object.firstChild;
}
function nav_over(e) {
	var target = find_target(e);
	if(!target) {
		return;
	}
	if(!target.src) {
	  // The target has come back as the link <a> and not the image within it
		var image_object = return_child_image_object(target);
	} else {
		var image_object = target;
	}
	if(image_object == null  ||  !image_object.src) {
		return;
	}
	image_object.src = image_object.src.replace("-off.", "-over.");
}
function nav_off(e) {
	var target = find_target(e);
	if(!target) {
		return;
	}
	if(!target.src) {
	  // The target has come back as the link <a> and not the image within it
		var image_object = return_child_image_object(target);
	} else {
		var image_object = target;
	}
	if(image_object == null  ||  !image_object.src) {
		return;
	}
	image_object.src = image_object.src.replace("-over.", "-off.");
}



/*
 * AJAX copy change
 * - Update the copy on the page using AJAX when the left-hand navigation is clicked
 */
function monitor_left_navigation_links() {
  // Get all of the links in the left-hand navigation container
	var navigation_links = $$("#subnavigation1 a");
  // Assign a listener to each link
	navigation_links.each(
		function(val) {
		  // Make sure the link is internal, so AJAX can be used
			if((val.target  &&  val.target != "")  ||  (val.className  &&  val.className.indexOf("iwantatarget") != -1)  ||  (val.href  &&  (val.href == ""  ||  val.href.substr(-1, 1) == "#"))) {
			  // This is not an internal link
				return;
			}
			Event.observe(val, "click", update_copy_using_ajax);
		}
	);
}
var last_url_selected = "";
function update_copy_using_ajax(e, copyonly) {
  // Make sure we do not have an old page being read
	document.getElementById("speech").src = "/iframe_blank.html";

  // AJAX is not supported by Safari
	if(is_safari) {
		return;
	}

  // Only update the middle content?
	if(!copyonly) {
		copyonly = false;
	}

  // Duration of the effects
	var effect_duration_in_seconds = 1;

  // Check to make sure an AJAX call or copy effect is not already running
	var loader_visible = Element.getStyle("loader", "display");
	if(loader_visible == "block") {
	  // The current transition has not finished yet
		Event.stop(e);
		return;
	}

  // Get the 'href' from the link
  // - Internet Explorer 6 returns the 'over' image URL as the href whereas Firefox is simply non-existant
	var target = find_target(e);
	if(!target  ||  !target.href  ||  target.href.indexOf(".gif") != -1) {

	  // Check to see if this is returning an image so a HREF does not exist
		if(target  &&  target.parentNode) {
			if((target.tagName  &&  target.tagName.toLowerCase() == "img")  ||  (target.tagName  &&  target.tagName.toLowerCase() == "strong")  ||  (target.href  &&  target.href.indexOf(".gif") != -1)) {
			  // As an image / strong element was found, the link should be the parent element
				target = target.parentNode;
			}
		}

	  // Double-check before running the non-JavaScript version
		if(!target  ||  !target.href) {
		  // No 'target' or URL was found
			return;
		}
	}
	var url = target.href;

  // Scroll to the top of the window so the user can see the change
	Element.scrollTo("container");

  // Check to see if the URL is already selected
	if(last_url_selected == url) {
		Event.stop(e);
		return;
	} else if(last_url_selected == ""  &&  (url == "http://" + window.location.hostname + window.location.pathname  ||  url == "https://" + window.location.hostname + window.location.pathname)) {
	  // This page was navigated to manually
		last_url_selected = url;
		Event.stop(e);
		return;
	}
	last_url_selected = url;

  // Hide the main content & related items (right column) before updating them
	var content_obj = $("copy");
	var navigation_obj = $("subnavigation2_list");

  // Display the loader message (this is done manually at present when 'Ajax.Responders.register' could be used)
	show_loader();

  // Remove any listners we might have setup for the main copy
	monitor_middle_links("off");

  // Update the copy making sure all the effects run only after the previous one has finished
	new Effect.BlindUp(
		content_obj,
		{
			duration : effect_duration_in_seconds,
			afterFinish : function(effect) {
				new Ajax.Updater(
					"copy",
					"/ajax/return_page_copy.php",
					{
						evalScripts : true,
						parameters : "url=" + escape(url),
						onFailure : function() {
						  // Make sure the copy from the error is not shown on screen by navigating to the page directly
							top.location.href = url;
						},
						onComplete : function() {
						  // Update the window title
							update_window_title(url);
							if(!copyonly) {
							  // Highlight the selected navigation link
								update_subnavigation_link(target);
							}
						  // Update the URL so that the browser's back/forward buttons work and the correct page is bookmarked
						  // - The 'bookmark' is checked when the user comes back again (from their bookmark)
							update_hashed_browser_url(url);
						  // Add listners for the main copy
							monitor_middle_links("on");
						  // Now the copy has been updated run the effect to show it
							new Effect.BlindDown(
								content_obj,
								{
									duration : effect_duration_in_seconds
								}
							);
						}
					}
				);
			}
		}
	);

  // Update the right-hand navigation?
	if(!copyonly) {

	  // Remove any listners we might have setup for the right-hand navigation
		monitor_right_navigation_links("off");

	  // Update the related items (right column) making sure all the effects run only after the previous one has finished
		new Effect.BlindUp(
			navigation_obj,
			{
				duration : effect_duration_in_seconds,
				afterFinish : function(effect) {
					new Ajax.Updater(
						"subnavigation2_list",
						"/ajax/return_related_items.php",
						{
							parameters : "url=" + escape(url),
							onFailure : function() {
							  // Make sure the copy from the error is not shown on screen by navigating to the page directly
								top.location.href = url;
							},
							onComplete : function() {
							  // Now the copy has been updated run the effect to show it
								new Effect.BlindDown(
									navigation_obj,
									{
										duration : effect_duration_in_seconds,
										afterFinish : function() {
										  // Add listners for the right-hand navigation
											monitor_right_navigation_links("on");
										}
									}
								);
							}
						}
					);
				}
			}
		);
	}

  // Hide the loader message (this is done manually at present when 'Ajax.Responders.register' could be used)
  // - The timer is set to the same duration as the above effects and doubled, because each copy element has 2 effects (the 0.5 seconds is a buffer)
	setTimeout("hide_loader();", ((effect_duration_in_seconds * 1000 * 2) + 500));

  // Remove the focus from the link
  // - Is this a DDA issue?
	target.blur();

  // Stop the browser from using the 'href' (same as returning 'false' from an 'onclick')
  // - (Abort the default behavior of the event and suspend its propagation)
	Event.stop(e);
}
function update_window_title(url) {
  // Fetch the window title for the updated copy
	new Ajax.Request("/ajax/return_window_title.php",
		{
			onSuccess : function(resp) {
			  // Update the window title
				window.document.title = resp.responseText;
			},
			onFailure : function(resp) {
			  // If there is an error retrieving the window title we will navigate to the page directly
				top.location.href = url;
			},
			parameters : "url=" + url
		}
	);
}
function update_subnavigation_link_using_url(new_url) {
	update_subnavigation_link(null, new_url);
}
function update_subnavigation_link(target, url) {
  // Get all of the highlighted links in the left-hand navigation container
  // - Done this way so there is no JavaScript on the main HTML page (and incase pages are navigated to directly and the item highlighted)
	var highlighted_navigation_links = $$("#subnavigation1 a");
	var highlighted_navigation_images = $$("#subnavigation1 img");

  // Check to see if we have to find our target object
	if((!target  ||  target == null)  &&  (!url  ||  url == "")) {
	  // We have nothing!
		return;
	}
	var find_object_using_url = (!target  ||  target == null);

  // Check to see if any of the text links are actually highlighted
	highlighted_navigation_links.each(
		function(val) {
			val.className = "";
			if(!find_object_using_url  ||  val.pathname != url) {
				return;
			}
		  // We've found our target!
			target = val;
			find_object_using_url = false;
		}
	);

  // Check to see if any of the images are using the 'on' version
	highlighted_navigation_images.each(
		function(val) {
			val.src = val.src.replace("-on.", "-off.");
			if(!find_object_using_url  ||  val.parentNode.pathname != url) {
				return;
			}
		  // We've found our target!
			target = val;
			find_object_using_url = false;
		}
	);

  // Highlight the selected navigation item and unhighlight the previous one (if applicable)
	if(target.tagName.toLowerCase() == "img") {
		target.src = target.src.replace("-off.", "-on.");
	} else if(target.tagName.toLowerCase() == "a"  &&  target.firstChild  &&  target.firstChild.tagName  &&  target.firstChild.tagName.toLowerCase() == "img") {
		target.firstChild.src = target.firstChild.src.replace("-over.", "-on.");
		target.firstChild.src = target.firstChild.src.replace("-off.", "-on.");
	} else {
		target.className = "sel";
	}
}
var currently_selected_url = "";
function update_hashed_browser_url(url) {
  // AJAX is not supported by Safari so we do not need to do this
	if(is_safari) {
		return;
	}
	var do_we_have_a_hash = url.indexOf("#");
	if(do_we_have_a_hash != -1) {
		url = url.substr(0, do_we_have_a_hash);
	}
  // Remove 'http://' and the hostname
	var stripped_url = url.replace(window.location.hostname, '');
	stripped_url = stripped_url.replace('http:///', '/').replace('https:///', '/');
  // Update the internal URL variable with the new anchor
	currently_selected_url = stripped_url;
  // Check to see if we're viewing the home page
	if(stripped_url != ""  &&  stripped_url != "/") {
//		top.location.href = window.location.pathname + "#" + anchor_hash_addition_for_bookmarks + stripped_url;
		top.location.hash = anchor_hash_addition_for_bookmarks + stripped_url;
	}
}
function check_for_bookmarked_anchor() {
	var anchor_details = window.location.hash;
	var bookmark_identifier_length = anchor_hash_addition_for_bookmarks.length;
	if(anchor_details == "") {
	  // Nothing to do here (no anchor)
		return false;
	}
	if(anchor_details.substr(1, bookmark_identifier_length) != anchor_hash_addition_for_bookmarks) {
	  // Nothing to do here (the beginning of the anchor is not correct for bookmarking)
		return false;
	}
  // Redirect the user to their bookmarked page
	anchor_details = anchor_details.substr(bookmark_identifier_length + 1);
	top.location.href = anchor_details;
}
function regularly_check_hashed_browser_url() {
	var anchor_details = window.location.hash;
	var bookmark_identifier_length = anchor_hash_addition_for_bookmarks.length;
	if(anchor_details == "") {
	  // Nothing to do here (no anchor)
		return false;
	}
	if(anchor_details.substr(bookmark_identifier_length + 1) == currently_selected_url  ||  anchor_details.substr(1, bookmark_identifier_length) != anchor_hash_addition_for_bookmarks) {
	  // Nothing to do here (the beginning of the anchor is either not correct for bookmarking or we're viewing the correct page)
		return false;
	}
  // Looks like we have a problem as the 2 URLs do not match!
  // - The user has used either a back or forward browser button
  // - Using AJAX, so the history stack is not affected, update the page's content immediately (without any effects)
	var new_url = anchor_details.substr(bookmark_identifier_length + 1);
	new Ajax.Updater(
		"copy",
		"/ajax/return_page_copy.php",
		{
			evalScripts : true,
			parameters : "url=" + escape(new_url),
			onFailure : function() {
			  // Make sure the copy from the error is not shown on screen by navigating to the page directly
				top.location.href = new_url;
			},
			onComplete : function() {
			  // Update the internal URL variable with the new location
				currently_selected_url = new_url;
			  // Update the window title
				update_window_title(new_url);
			  // Highlight the selected navigation link
				update_subnavigation_link_using_url(new_url);
			  // Update the right-hand navigation
				new Ajax.Updater(
					"subnavigation2_list",
					"/ajax/return_related_items.php",
					{
						parameters : "url=" + escape(new_url),
						onFailure : function() {
						  // Make sure the copy from the error is not shown on screen by navigating to the page directly
							top.location.href = new_url;
						}
					}
				);
			}
		}
	);

  // Scroll to the top of the window so the user can see the change
	Element.scrollTo("container");
}



/*
 * AJAX copy change
 * - Monitor the right-hand navigation each time it is updated so we are able to use our AJAX effect
 * - Monitor the centre column each time it is updated so we are able to use our AJAX effect
 */
function monitor_links_for_main_copy_and_right_nav(on_or_off, links_to_search_for) {
  // Make sure we have 1 of a possible 2 values
	if(!on_or_off  ||  on_or_off != "on") {
		on_or_off = "off";
	}

  // Get all of the links in the container
	var the_links = $$(links_to_search_for);

  // Are we assigning or removing listners on each link?
	if(on_or_off == "on") {

	  // Assign a listener to each link
		the_links.each(
			function(val) {
			  // Make sure the link is internal and not a placeholder, so AJAX can be used
			  // - The long-winded 'substr' function call is because IE7 wants to be different and not work with minus numbers
				if((val.href  &&  (val.href == ""  ||  val.href.substr((val.href.length-1), 1) == "#"))) {
				  // This is not an internal link
					return;
				}
			  // Make sure the link is not a download
				if(val.href  &&  val.href.indexOf(".zip") != -1) {
				  // This is not an internal link
					return;
				}
			  // Check to see if this is an external link
				var different_website = supplied_host_different_to_website(val.href);
				if(different_website) {
					return;
				}
			  // If this is a link, should it open in a new popup window ('target' is defined)?
				if((val.target  &&  val.target != "")  ||  (val.className  &&  val.className.indexOf("iwantatarget") != -1)) {
				  // As this item is going to open in a new window, we need to update the title text as well
					Event.observe(val, "click", new_popup_window);
					if($(val).title.indexOf(newwindow_copy) == -1) {
						if($(val).title.replace(" ", "") == "") {
							$(val).title = newwindow_copy;
						} else {
							$(val).title = $(val).title + " (" + newwindow_copy + ")";
						}
					}
					return;
				}
				Event.observe(val, "click", update_copy_using_ajax_copyonly);
			}
		);

	} else {
	  // Remove any listeners originally assgined to each link
		the_links.each(
			function(val) {
			  // Make sure the link is internal, so AJAX can be used
				if((val.href  &&  (val.href == ""  ||  val.href.substr(-1, 1) == "#"))) {
				  // This is not an internal link
					return;
				}
				if((val.target  &&  val.target != "")  ||  (val.className  &&  val.className.indexOf("iwantatarget") != -1)) {
					Event.stopObserving(val, "click", new_popup_window);
				}
				Event.stopObserving(val, "click", update_copy_using_ajax_copyonly);
			}
		);
	}
}
function monitor_right_navigation_links(on_or_off) {
  // Make sure we have 1 of a possible 2 values
	if(!on_or_off  ||  on_or_off != "on") {
		on_or_off = "off";
	}
	monitor_links_for_main_copy_and_right_nav(on_or_off, "#subnavigation2 a");
}
function monitor_middle_links(on_or_off) {
  // Make sure we have 1 of a possible 2 values
	if(!on_or_off  ||  on_or_off != "on") {
		on_or_off = "off";
	}
	monitor_links_for_main_copy_and_right_nav(on_or_off, "#copy a");
}
function update_copy_using_ajax_copyonly(e) {
	update_copy_using_ajax(e, true);
}



/*
 * Run these functions immediately
 * - Check to see if the user bookmarked an 'anchored' page
 * - Check to see if the user has used the back or forward browser buttons
 */
// AJAX is not supported by Safari so we do not need to do this
if(!is_safari) {
	check_for_bookmarked_anchor();
	setInterval("regularly_check_hashed_browser_url()", 250);
}
// This needs to be run before the page finishes loading so we do not get a continuous loading message/icon
if(!is_ie) {
  // To keep our CSS "valid" we will create 2 new items here ;-)
	Element.setStyle('tweakcss', {overflowY: 'scroll'} );
	Element.setStyle('tweakcss', {overflow: '-moz-scrollbars-vertical'} );
	Element.setStyle('tweakcss', {overflowX: 'auto'} );
}



/*
 * Run this function when the page loads
 * It encompasses all of the functions required to make this page 'dynamic'
 */
function onload_container() {
  // Update general listeners
	monitor_all_links();
  // If this is the "Site Map" page we want to make sure the whole page is refreshed if a 'middle' link is clicked
  // - This is because we will end up missing top-nav highlighting and left & right navigation links if the AJAX updates the copy
	if(document.location.pathname != "/site-map.html") {
		monitor_left_navigation_links();
		monitor_right_navigation_links("on");
		monitor_middle_links("on");
	}
  // For the Back & Forward buttons to work we must always have a hash/anchor value in the URL
	update_hashed_browser_url(top.location.href);
}
Event.observe(window, "load", onload_container);