/*
enhance.js
Generic enhancement functions
*/

var W3CDOM = (document.createElement && document.getElementsByTagName);

// Dependant on elements in HTML
//addLoadEvent(replaceTextLoader);
addLoadEvent(replaceEmailAddr);
addLoadEvent(showDecor);
//addLoadEvent(markLinks);
addLoadEvent(initAccesskeys);

// Attach functions to window.onload event
function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	} else {
		window.onload = function() {
			oldonload();
			func();
		}
	}
}

/******************************************************************************
	Add missing DOM functionality
******************************************************************************/

// IE6 does not include a .hasAttribute method

/******************************************************************************
	Generic Cookie functions
******************************************************************************/

function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}

/******************************************************************************
	Accesskeys
******************************************************************************/

var AK_COOKIE = 'disableaccesskeys';
var AK_COOKIE_EXPIRE = 7;	// Days

// Enable - TT/FF
function enableAccesskeys(Enable) {
	
	// If enabling accesskeys, just remove cookie and refresh page!
	if (Enable) {
		eraseCookie(AK_COOKIE);
		window.location.reload();
		return;
	}
	
	// Disabling accesskeys, set cookie and remove attribute from links
	createCookie(AK_COOKIE,'On',AK_COOKIE_EXPIRE);
	var links = document.getElementsByTagName('a');
	var count = 0;
	for (var i=0; i<links.length; i++) {
		if (links[i].getAttribute('accesskey')) {
			count++;
			// Should be safe to call this without checking that the attribute exists as it should not raise an exception (FF)
			// IE is by default case-sensitive (requiring 'accessKey') - 2nd param, 0 turns this off
			// IE returns T/F on success, FF does not 
			links[i].removeAttribute('accesskey',0);
		}
	}
	
	// Shows/hides certain elements based on whether accesskeys are enabled or not
	if (count > 0) {
		checkAccesskeys();
	}
	
	// Returns number of accesskeys disabled
	//alert(count);
	return count;
}

// Checks status of Accesskeys
// (NOT USED) EnabledID - ID of element to display if accesskeys are enabled
// (NOT USED) DisabledID - opp to above
// Returns TT/FF if accesskeys enabled
function checkAccesskeys(EnabledID,DisabledID) {
	var enabled_obj = document.getElementById('disable-accesskeys');
	var disabled_obj = document.getElementById('enable-accesskeys');
	
	var disabled = readCookie(AK_COOKIE);
	disabled = (disabled == 'On');
	if (disabled) {
		// Currently disabled
		if (enabled_obj) {enabled_obj.style.display = 'none';}
		if (disabled_obj) {disabled_obj.style.display = 'block';}
	} else {
		// Currently enabled
		if (enabled_obj) {enabled_obj.style.display = 'block';}
		if (disabled_obj) {disabled_obj.style.display = 'none';}
	}
	
	return !disabled;
}

// Checks cookie, if accesskeys should be disabled then call above function
// Otherwise nothing
function initAccesskeys() {
	var disabled = readCookie(AK_COOKIE);
	if (disabled == 'On') {
		enableAccesskeys(false);
	}
	return checkAccesskeys();
}

// Call from href
function infoDisableAccesskeys() {
	alert('The state of the Accesskeys on this website, if they are disabled, are stored in a cookie on your machine.\n\nThis can cause no harm or infringe personal privacy, it is merely used to determine if Accesskeys are disabled for this site when you move off this page or next visit this website.\n\nThis cookie will expire in ' + AK_COOKIE_EXPIRE + ' days, after which time it will be removed automatically by the browser and this website\'s Accesskeys will be renabled again.');
}

// Step through all links on the page...
// Mark external links with a little graphic and mailto: links with an envelope
// NB: replaceEmailAddr() will need to be called before this function
// Returns the number of links effected
// --
// PROBLEM: Adding inline img negates line-height in IE6
// PROBLEM: IE and Opera always return FQDN (ie. "http://...") as part of href (FF returns as source)
// Use class="external" in html instead
function markLinks() {
	if (!W3CDOM) return;
	var href, orig_title, title, src, alt, count = 0;
	var img_new, img_master = document.createElement('img');
	img_master.className = 'link-marker';
	var links = document.getElementsByTagName('a');
	for (var i=0; i<links.length; i++) {
		title = '';
		href = links[i].getAttribute('href');
		alert(href);
		if (href.indexOf('http') == 0) {
			title = 'Link to an external website - ' + href;
			src = '/img/linkext.gif';
			alt = '[External Link]';
		} else if (href.indexOf('mailto:') == 0) {
			title = 'Opens your default email program and composes a new email addressed to ' + href.substring(7);
			src = '/img/linkemail.gif';
			alt = '[Email Link]';
		}
		
		// Add an image marker...?
		if (title != '') {
			count++;
			
			// Add title to link (append to what is already there), not image marker
			orig_title = links[i].getAttribute('title');
			if (orig_title > ' ') {
				title = orig_title + ' - ' + title;
			}
			links[i].setAttribute('title',title);
			
			// Create image
			img_new = img_master.cloneNode(true);
			img_new.setAttribute('src',src);
			img_new.setAttribute('alt',alt);
			
			// Append image to anchor
			links[i].appendChild(img_new);			
		}
	}
	
	return count;
}

/******************************************************************************
	Anti-SPAM
******************************************************************************/

// Searches doc for anchors with class="email", replaces content and sets href attribute
// To prevent SPAM
function replaceEmailAddr() {
	if (!W3CDOM) return;
	var email, enode, n;
	var links = document.getElementsByTagName('a');
	for (var i=0; i<links.length; i++) {
		// Using getAttribute('class') did not work on IE! 
		if (links[i].className == 'email') {
			// Reconstruct email address
			email = links[i].firstChild.nodeValue;
			email = email.replace(/ -at- /g,'@');
			email = email.replace(/ -dot- /g,'.');			
			//alert(email);
			enode = document.createTextNode(email);
			//links[i].setAttribute('href','mailto:'+email);
			links[i].href = 'mailto:' + email;
			links[i].replaceChild(enode,links[i].firstChild);
		}
	}
}

// Initiates function to replace text headings with images
function replaceTextLoader() {
	if (!W3CDOM) return;
	var test = new Image();
	var tmp = new Date();
	var suffix = tmp.getTime();
	test.src = '/img/test.gif?'+suffix;
	test.onload = replaceTextInit;
}

// Which groups of elements to replace...
function replaceTextInit() {
	replaceText(document.getElementsByTagName('h1'));
	replaceText(document.getElementsByTagName('h2'));
}

// Look for elements with id attribute within group
function replaceText(x) {
  var txtnode;
	var replace = document.createElement('img');
	for (var i=0; i<x.length; i++) {
		if (x[i].id) {
			// Quicker than creating element from scratch each time
			var y = replace.cloneNode(true);
			y.src = '/img/' + x[i].id + '.png';
			y.setAttribute('border','0');
			// Find first textNode, as we might have an anchor within this one!
			txtnode = findTextNode(x[i]);
		  y.alt = txtnode.nodeValue;
			txtnode.parentNode.replaceChild(y,txtnode);
		}
	}
}

// Finds and returns first TEXT_NODE, even if within another ELEMENT_NODE (recursive)
function findTextNode(elem) {
	//alert(elem.nodeType);
	// Works, but is it quite correct in [ALL] situations?
	if (elem.nodeType != 3) {
	  if (elem.hasChildNodes) { 
			return findTextNode(elem.firstChild);
		}
	} else {
		// TEXT_NODE
		return elem;
	}
}


/************************************************************************************
Make decor image fade/move onto screen
NB: hide.css will have been included (with JS) prior to this function being called
************************************************************************************/

// Pass.. Op (opacity) 0..10
// NB: opacity:0..1, alpha(opacity=0..100)
function setDecor(yPos,Op) {
	if (!W3CDOM) {return;}
	obj = document.getElementById('decor');
	if (obj) {
		obj.style.top = Math.floor(yPos) + 'px';
		obj.style.opacity = Op/10;
		obj.style.filter = 'alpha(opacity=' + Op*10 + ')';
		obj.style.visibility = 'visible';
	}	
}

// Start timed anim
function showDecor() {
	if (!W3CDOM) {return;}
	
	var y_pos = -120;	// Needs to match value in stylesheet
	var op = 0;
	var max_steps = 80;	// Whatever steps necessary
	var interval = 10;	// msec between *visual* frames
	var delay = 200;		// Initial delay before anim starts
	
	// Decelerate to 0 (in whatever time)
	// Calc a (px/msec/msec)
	// v^2 = u^2 + 2as;
	//var t = interval * max_steps;	// msec
	var u = 4;	// Initial speed px/msec
	var a = -(u * u) / (2 * Math.abs(y_pos));
	//var a = (-u / t);
	//a *= interval;		
	
	// Linear speed
	//var y_inc = Math.abs(y_pos) / max_steps;
	var op_inc = 10 / max_steps;
	
	obj = document.getElementById('decor');
	if (obj) {
		/*
		for (var i=1; i <= max_steps; i++) {
			//y_pos += y_inc;
			y_pos += u;
			u += a;
			op += op_inc;
			setTimeout('setDecor('+y_pos+','+op+')',i*interval)
		}
		*/
		var i = 1;
		while ((u > 0) || (op < 10)) {
			i++;
			setTimeout('setDecor('+y_pos+','+op+')',(i*interval)+delay);
			y_pos += u;
			if (y_pos > 0) {y_pos = 0; a =0; u = 0;}
			u += a;
			op += op_inc;
			if (op > 10) {op = 10;}
		}
	}
}