/**
*Javascript
*/


window.onload = function()
	{
	xhtml = new WebPage();
	xhtml.init();
	}


/**
* Creates a new WebPage object with methods used by all pages, can be extended to add page specific methods.

*/
function WebPage()
	{
	// Step 1. Define Properties

	var _initialized = false;
	var _debug = false;

	var _clientLoginDisplayed = false;
	var _clientLoginTimeout = null;
	var _CLIENT_LOGIN_MAX_HEIGHT = 90;


	// Step 2. Define Public Methods

	/**
	* Sets up the initial page state and event handlers
	*/
	this.init = function()
		{
		this.initAnchors();

		// Set class as initialized
		_initialized = true;
		}


	/**
	* Adds standard event handlers to process in-page links and offsite links
	*/
	this.initAnchors = function()
		{
		var links = document.getElementsByTagName('a');
		for (var x = 0; x < links.length; x++)
			{
			// 1. Make offsite links and pdfs open in a new tab/window
			if (/\b(offsite|pdf)\b/.exec(links[x].className))
				{
				links[x].onclick = function()
					{
					window.open(this.href,'_blank');
					return false;
					}
				}

			// 2. Make inpage links smooth scroll
			if (/\binpage\b/.exec(links[x].className))
				{
				var url = links[x].href;
				var startPos = url.indexOf('#')+1;
				var endPos = (url.indexOf('?') != -1 ? url.indexOf('?')+1 : url.length);
				var target = url.substring(startPos, endPos);
				links[x].onclick = new Function('xhtml.smoothScroll("' + target + '");');
				links[x].href = 'javascript:javascript:void(1);';
				}

			// 3. Disable links to the current page (improves user experience)
			if (links[x].href == window.location.toString() || links[x].href == window.location.toString() + '#')
				{
				links[x].style.cursor = 'default';
				links[x].style.textDecoration = 'none';
				}
			}
		}


	/**
	* Set the font size for the document and save setting to a cookie
	*
	* @param		int		fontsize		A value of either 1 or 2 indicating normal or large fonts
	*/
	this.fontSize = function(newSize)
		{
		// Build the cookie expiry
		var date = new Date();
		date.setTime(date.getTime()+(365*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();

		// Update the font size
		switch (newSize)
			{
			case 1:
				document.getElementById('page').style.fontSize = '78%';
				document.cookie = "fontsize=1"+expires+"; path=/";
				break;
			case 2:
				document.getElementById('page').style.fontSize = '95%';
				document.cookie = "fontsize=2"+expires+"; path=/";
				break;
			}
		}


	/**
	* Scrolls the page to the specified element
	*
	* @param			elementId			The ID of the element to scroll to
	* @param			elementY			The Y position of element (optional, will be calculated if not specified)
	*/
	this.smoothScroll = function(elementId, elementY)
		{
		// If the elements vertical location hasn't been specificed, calculate it
		if (arguments.length != 2)
			{
			// Get it's offset
			obj = document.getElementById(elementId);
			obj.style.display = 'block';	// Make sure it's visible, otherwise we can't get it's location

			elementY = obj.offsetTop;

			// If its parent is relative or absolutely positioned, find it's offset and add it to the total
			while (obj.offsetParent)
				{
				obj = obj.offsetParent;
				elementY += obj.offsetTop;
				}

			// Make the scroll stop just above the target (looks nicer)
			elementY -= 15;
			if (elementY < 0)
				{
				elementY = 0;
				}

			// Check to see we're not trying to scroll off the end of the page
			var contentHeight = document.getElementById('page').offsetHeight;
			var windowHeight = (window.innerHeight ? window.innerHeight : (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight));
			if ( (contentHeight - windowHeight) < elementY)
				{
				elementY = (contentHeight - windowHeight);
				}
			}

		// Get the current window scroll position
		var yPos = window.scrollY ? window.scrollY : (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);

		// Calculate the pixels remaining to scroll and the scroll step size
		var distanceLeft = Math.abs(yPos - elementY);
		var stepSize = 100;
		if (distanceLeft < 400)
			{
			stepSize = 60;
			}
		if (distanceLeft < 200)
			{
			stepSize = 20;
			}
		if (distanceLeft < 50)
			{
			stepSize = 10;
			}

		// Calculate the scroll
		if (yPos < elementY)
			{
			// Scroll down
			yPos += stepSize;

			// Check if we're scrolled past the target
			if (elementY < yPos)
				{
				yPos = elementY;
				}
			}
		else if (elementY < yPos)
			{
			// Scroll Up
			yPos -= stepSize;

			// Check if we're scrolled past the target
			if (yPos < elementY)
				{
				yPos = elementY;
				}
			}

		// Check for less than zero
		if (yPos < 0)
			{
			yPos = 0;
			}
		if (elementY < 0)
			{
			elementY = 0;
			}

		// Scroll window
		window.scrollTo(0, yPos);

		// If we haven't reached the target, run the another scroll step
		if (yPos != elementY)
			{
			setTimeout("xhtml.smoothScroll('" + elementId + "', " + elementY + ");", 10);
			}
		}


	/**
	* Scrolls the Client Login box in and out of view
	*/
	this.clientLogin = function()
		{

		// Check if a toggle parameter has been passed
		if (arguments.length == 1)
			{
			if(_clientLoginDisplayed == true)
				{
				clearTimeout(_clientLoginTimeout);
				_clientLoginDisplayed = false;
				document.getElementById('globalHeaderClientlogin').style.height = '0px';
				document.getElementById('globalHeaderClientlogin').style.visibility = 'hidden';
				document.getElementById('globalHeaderClientlogin').getElementsByTagName('input')[0].blur();
				}
			else
				{
				_clientLoginDisplayed = true;
				document.getElementById('globalHeaderClientlogin').style.height = '0px';
				document.getElementById('globalHeaderClientlogin').style.visibility = 'visible';
				}
			}
		
		// Calculate the scroll
		var newPos = parseInt(document.getElementById('globalHeaderClientlogin').style.height) + 10;

		// Check if the dialog has been fully displayed
		if (_CLIENT_LOGIN_MAX_HEIGHT < newPos)
			{
			newPos = _CLIENT_LOGIN_MAX_HEIGHT;
			}
		
		// Scroll dialog
		document.getElementById('globalHeaderClientlogin').style.height = newPos + 'px';
		

		// If we haven't reached the target, run the another scroll step
		if (newPos != _CLIENT_LOGIN_MAX_HEIGHT)
			{
			_clientLoginTimeout = setTimeout("xhtml.clientLogin();", 10);
			}
		else
			{
			// Focus the first form field
			try
				{
				document.getElementById('globalHeaderClientlogin').getElementsByTagName('input')[0].focus();
				}
			catch (e) {} // If it can't be focused do nothing.
			}
		}
	

	/**
	* Sets the current view in a XHTML document
	*
	* Displays and Hides elements and once complete, can optionally scroll to specified element.
	*
	* @param		toDisplay			An array of element ID's to display
	* @param		toHide				An array of element ID's to hide
	* @param		scrollTo			The element ID to scroll to once the view has been set (optional)
	*/
	this.setView = function(toDisplay, toHide, scrollTo)
		{
		// 1. Check if we've been passed an arrays or a strings for display param
		if (typeof(toDisplay) != 'array' && typeof(toDisplay) != 'object')
			{
			var toDisplay = new Array(typeof(toDisplay) != 'undefined' ? toDisplay : '');
			}

		// 2. Check if we've been passed an arrays or a strings for hide param
		if (typeof(toHide) != 'array' && typeof(toHide) != 'object')
			{
			var toHide = new Array(typeof(toHide) != 'undefined' ? toHide : '');
			}

		// 3. Display elements
		for (var x = 0; x < toDisplay.length; x++)
			{
			if (document.getElementById(toDisplay[x]))
				{
				document.getElementById(toDisplay[x]).style.display = 'block';
				}
			}
		
		// 4. Hide elements
		for (var x = 0; x < toHide.length; x++)
			{
			if (document.getElementById(toHide[x]))
				{
				document.getElementById(toHide[x]).style.display = 'none';
				}
			}
		
		// 5. Scroll to specified element, if supplied
		if (arguments.length == 3)
			{
			if (document.getElementById(scrollTo))
				{
				xhtml.smoothScroll(scrollTo);
				}
			}
		}



	// Step 3. Define Private Methods

	/**
	* Finds the parent of the element with a node type of parentTagName
	*
	* @param		element					The element object to find the parent of
	* @param		parentTagName		The type of parent element to find
	*
	* @return		The element's parent object of the specified type, or null if no parent of that type could be found
	*/
	function findParent(element, parentTagName)
		{
		if (element == null)
			{
			return null;
			}
		else
			{
			if ( element.nodeType == 1 && element.tagName.toLowerCase() == parentTagName.toLowerCase() )
				{
				return element;
				}
			else
				{
				return findParent(element.parentNode, parentTagName);
				}
			}
		}
	}

