var Utils = new function()
{
	document.getElementsByTagName("html")[0].className = "jsActive";
	var self = this,
		
		EVENTS = 
		{
			BLUR		: "blur",
			CLICK		: "click",
			DBLCLICK	: "dblclick",
			FOCUS		: "focus",
			KEYDOWN		: "keydown",
			KEYUP		: "keyup",
			RESIZE		: "resize",
			MOUSEWHEEL	: "mousewheel",
			MOUSEOVER	: "mouseover",
			MOUSEOUT	: "mouseout",
			MOUSEDOWN	: "mousedown",
			MOUSEUP		: "mouseup",
			SUBMIT		: "submit",
			LOAD		: "load",
			UNLOAD		: "unload"
		},

		KEYS =
		{
			NUM_1: 97, NUM_2: 98, NUM_3: 99, NUM_4: 100, NUM_5: 101, NUM_6: 102, NUM_7: 103, NUM_8: 104, NUM_9: 105, NUM_0: 96, NUM_POINT: 110, ENTER: 13, NUM_PLUS: 107, NUM_MINUS: 109, NUM_TIMES: 106,
			KEY_1: 49, KEY_2: 50, KEY_3: 51, KEY_4: 52, KEY_5: 53, KEY_6: 54, KEY_7: 55, KEY_8: 56, KEY_9: 57, KEY_0: 48, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71, H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79, P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87, X: 88, Y: 89, Z: 90,
			OPEN_BRACKET: 219, CLOSE_BRACKET: 221, HASH: 222, COMMA: 188, FULL_STOP: 190, LEFT_ARROW: 37, UP_ARROW: 38, RIGHT_ARROW: 39, DOWN_ARROW: 40, PAGE_UP: 33, PAGE_DOWN: 34, SPACE: 32, INSERT: 45, DELETE: 46, HOME: 36, END: 35, ESC: 27, BREAK: 19, BACK_SLASH: 220,
	/*		0: 1000, 1: 1001, 2: 1002, 3: 1003, 4: 1004, 5: 1005, 6: 1006, 7: 1007, 8: 1008, 9: 1009, */
			SHIFT: 16, CTRL: 17, ALT: 18
		},

		ON = "on",
		FF_WHEEL = "DOMMouseScroll";
		
	this.EVENTS = EVENTS;
	this.KEYS = KEYS;
	
	function addEvent(element, eventName, handler)
	{
		function _ev(ev)
		{
			var theEvent = ev || window.event;
			theEvent.targetElement = theEvent.target || theEvent.srcElement;

			if(eventName == EVENTS.MOUSEWHEEL)
			{
				var wheelResult = theEvent.detail || theEvent.wheelDelta/-40;
				theEvent.wheelAmount = wheelResult;
				theEvent.wheelDown = (wheelResult > 0);
			}

			var eventResult = handler.call(element, theEvent);

			if(ev.preventDefault && (eventResult === false))
			{
				ev.preventDefault();
				ev.stopPropagation();
			}

			return eventResult;
		}

		if (element.attachEvent)
		{
			element.attachEvent(ON + eventName, _ev);
		}
		else
		{
			element.addEventListener(((eventName == EVENTS.MOUSEWHEEL)?FF_WHEEL:eventName), _ev, false);
		}

		if (element != window) addEvent(window, EVENTS.UNLOAD, function () {element = null});
		
		return _ev;
	}
	this.addEvent = addEvent;

	function removeEvent(element, eventName, handler)
	{
		if (element.detachEvent)
		{
			element.detachEvent(ON + eventName, handler);
		}
		else
		{
			element.removeEventListener(((eventName == EVENTS.MOUSEWHEEL)?FF_WHEEL:eventName), handler, false);
		}
	}
	this.removeEvent = removeEvent;

	function addOnload(handler)
	{
		addEvent(window, EVENTS.LOAD, handler);
	}
	this.addOnload = addOnload;
	
	function _initialiseAccessKeys()
	{
		var menu = document.getElementById("accessMenuHolder");
		var menuHTML = menu.innerHTML;
		menu.innerHTML = "";
		var menuVisible = false;

		(function _clear()
		{
			var allLinks = document.getElementsByTagName("a");
			var ct = allLinks.length;

			while(0 < ct--)
				allLinks.accesskey = "";

		})();

		function _hideMenu()
		{
			menu.style.display = "none";
			menu.innerHTML = "";
			menuVisible = false;
		}
		
		addEvent(window, EVENTS.BLUR, _hideMenu);

		function _keyDown(ev)
		{
			if((!menuVisible) && (ev.keyCode == KEYS.ALT))
			{
				menu.innerHTML = menuHTML;
				menu.style.display = "block";
				menuVisible = true;
			}
		}
		addEvent(document, EVENTS.KEYDOWN, _keyDown);

		function _keyUp(ev)
		{
			if(menuVisible)
			{
				var hideMenu = false;

				switch(ev.keyCode)
				{
					case KEYS.NUM_0:
					case KEYS.KEY_0:
						location = "/help/accessibility/";
						hideMenu = true;
						break;
					case KEYS.NUM_1:
					case KEYS.KEY_1:
						location = "/";
						hideMenu = true;
						break;
					case KEYS.NUM_2:
					case KEYS.KEY_2:
						location = "#structContent";
						hideMenu = true;
						break;
				/*	case KEYS.NUM_3:
					case KEYS.KEY_3:
						location = "/sitemap/";
						hideMenu = true;
						break;
					case KEYS.NUM_4:
					case KEYS.KEY_4:
						location = "/search/";
						hideMenu = true;
						break; */
					case KEYS.NUM_5:
					case KEYS.KEY_5:
						document.getElementById("structNavBar").getElementsByTagName("a")[0].focus();
						hideMenu = true;
						break;
					default:
						hideMenu = true;
						break;
				}

				if(hideMenu)
				{
					_hideMenu();
				}
			}
			return false;
		}
		addEvent(document, EVENTS.KEYUP, _keyUp);
	}

	function _initialiseTrackableClicks(cssClass, external, options)
	{
		function _extClick(ev)
		{
			var extURL = this.href;
			var prefix = options.prefix || '';
			
			if (prefix != '')
			{
				prefix = '/' + prefix + '/';
			}
			
			var i = extURL.indexOf(location.host);
			
			if ((i >= 0) && (i < 9)) // its there, but not immediately after http(s?)://
			{
				extURL = extURL.substring(i + location.host.length);
			}
			
			if((typeof pageTracker) != "undefined")
			{
				pageTracker._trackPageview(prefix + extURL)
			}
			
			if (options.openWindow)
			{
				window.open(extURL);
				return false;
			}
		}
		
		var linkList = document.getElementsByTagName("a");
		var ct = linkList.length;
		var options = options || {};
		
		while(0 < ct--)
		{
			if(linkList[ct].className.indexOf(cssClass) != -1)
			{
				addEvent(linkList[ct], EVENTS.CLICK, _extClick);
			}
		}
	}
	
	function _initialiseExternalClicks()
	{
		_initialiseTrackableClicks('_blank', true, {prefix: 'outbound', openWindow: true});
	}
	
	function _initialiseDownloadClicks()
	{
		_initialiseTrackableClicks('saveLink', false);
	}
	
	function _initialiseTools()
	{
		addEvent(document.getElementById("printTool"), EVENTS.CLICK, function(){window.print();return false;});
	}

	function _focusFirstTextFieldOfForm()
	{
		var forms = document.getElementById('structContent').getElementsByTagName('form');
		
		if (forms.length > 0)
		{
			var elements = forms[0].elements
			,	i = 0
			,	l = elements.length
			,	searching = true;
			
			while (searching && (i < l))
			{
				var tag = elements[i++]
				,	tagName = tag.tagName.toLowerCase();
				
				if ((tagName == 'textarea') || ((tagName == 'input') && (tag.type == 'text') && (tag.name != 'formData')))
				{
					tag.focus();
					searching = false;
				}
			}
		}
		
		var formCt = forms.length;
		
		while(formCt--)
		{
			var inputs = forms[formCt].getElementsByTagName('input')
			,	inputCt = inputs.length
			,	current;
			
			while (inputCt--)
			{
				_disableSubmitButtonOnSuccess(forms[formCt], inputs[inputCt]);
			}
		}
	}
	
	function _disableSubmitButtonOnSuccess(form, input)
	{
		if(input.type == "submit")
		{
			addEvent(form, 'submit', function() {
				input.disabled = true;
				
				setTimeout(function(){
					input.disabled = false;
				}, 500);
			});
		}
	}

	addOnload(_initialiseAccessKeys);
	addOnload(_initialiseExternalClicks);
	addOnload(_initialiseDownloadClicks);
	addOnload(_initialiseTools);
	addOnload(_focusFirstTextFieldOfForm);

	this.googleMap = function (opts)
	{
		if (window.google && google.maps)
		{
			var scripts = document.getElementsByTagName("script")
			,	holder = scripts[scripts.length - 1].parentNode
			,	mapDiv = holder.getElementsByTagName('div')[0]
			,	maxHeight = 999
			,	heading = holder.getElementsByTagName("h2")[0]
			,	address = holder.getElementsByTagName("p")[0];
			
			if (window.innerHeight)
			{
				maxHeight = window.innerHeight - heading.offsetHeight - address.offsetHeight - 20;
			}
			
			if (maxHeight > 180)
			{				
				mapDiv.parentNode.style.width = "100%";
				
				heading.getElementsByTagName("span")[0].innerHTML = "Interactive ";
				
				if (maxHeight < 370)
				{
					mapDiv.style.height = maxHeight + "px";
				}
				
				if (mapDiv.offsetWidth < 500)
				{
					var styleAttribute = 'top: ' + (heading.offsetHeight + 60) + 'px; height: ' + (mapDiv.offsetHeight - 75) + 'px;';
					document.write('<div class="mapGrabZone" style="' + styleAttribute + '"></div><div class="mapGrab" style="' + styleAttribute + '"></div>');
				}
				
				var gMaps = google.maps
				,	gMapTypes = gMaps.MapTypeId
				,	latLng = new gMaps.LatLng(opts.center.lat, opts.center.long)
				,	mapOpts = {
						center: latLng,
						backgroundColor: '777900',
						zoom: opts.zoom,
						mapTypeId: gMapTypes.ROADMAP,
						streetViewControl : ((mapDiv.offsetHeight >= 370) && (mapDiv.offsetWidth > 370))?true:false,
						mapTypeControlOptions : {mapTypeIds: [gMapTypes.ROADMAP, gMapTypes.HYBRID, gMapTypes.SATELLITE]}
					}
				,	resetDiv = document.createElement('p')
					
				,	map = new gMaps.Map(mapDiv, mapOpts)
				
				,	markerLatLng = new gMaps.LatLng(opts.marker.lat, opts.marker.long)
				,	icon = opts.marker.icon
				,	shadow = opts.marker.shadow
				,	marker = new gMaps.Marker({
						position: markerLatLng,
						map: map,
						icon: icon,
						shadow: icon
					});
				
				resetDiv.innerHTML = '[<span>re-centre the map</span>]';
				resetDiv.className = 'resetMap';
				
				holder.appendChild(resetDiv);
				
				addEvent(resetDiv, 'mouseover', function (ev) {resetDiv.className = "resetMap resetMapOver"});
				addEvent(resetDiv, 'mouseout',  function (ev) {resetDiv.className = "resetMap"});
				addEvent(resetDiv, 'click', function (ev) {map.setZoom(opts.zoom); map.panTo(latLng); map.setMapTypeId(gMapTypes.ROADMAP);});
				
				addEvent(window, "resize", function() {gMaps.event.trigger(map, 'resize')});
			}
		}
	}
}


