/**
* Global JavaScript Definitions
*
* @author				Matt Gifford
* @copyright			2009 Timeshifting Interactive Limited
* @version			2.0
*/

var viewHandler = WebPage;
var onloadHandler = function()
	{
	if (viewHandler !== WebPage)
		{
		// Extend the base page class and create the xhtml object
		viewHandler.inheritsFrom( WebPage );
		xhtml = new viewHandler();
		}
	else
		{
		// Create a generic page xhtml object
		xhtml = new WebPage();
		}

	// Main page initialization
	xhtml.init();
	}

// Queue onload handler
if (typeof(dojo) != 'undefined') dojo.addOnLoad(onloadHandler);
else if (typeof(YAHOO) != 'undefined') YAHOO.util.Event.onDOMReady(onloadHandler);
else if (typeof(window.jQuery) != 'undefined') $(document).ready(onloadHandler);
else window.onload = onloadHandler;



/**
* Creates a new WebPage object with methods used by all pages, can be extended to add page specific methods.
*
* @author				Matt Gifford
* @copyright			2009 Timeshifting Interactive Limited
*/
function WebPage()
	{
	// Step 1. Define Properties

	var _instance = this;
	this.log = function(msg) { if (typeof(console) != 'undefined') { console.log(msg); } };



	// Step 2. Define Public Methods

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

		// Inject email address
		var spans = document.getElementsByTagName('span');
		for (var x = 0; x < spans.length; x++)
			{
			if (spans[x].className == 'emailAddress')
				{
				var str1 = 'moc\u002Eaidemlatigidgnikiv\u0040sdiar';
				var str2 = '\u003Aotliam';
				spans[x].innerHTML = '<a href="' + str2.split('').reverse().join('') + str1.split('').reverse().join('') + '">' + str1.split('').reverse().join('') + '</a>';
				}
			}

		// Set class as initialized
		this.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. Set the active class on links to the current page
			if ((links[x].href == window.location.href || links[x].href == window.location.href + 'index.html') && links[x].href.indexOf('#') == -1)
				{
				if (links[x].className.indexOf('active') == -1)
					{
					links[x].className += ' active';
					}
				}
			}
		}



	/**
	* Adds rollover support to input[type=image] elements
	*/
	this.initInputButtons = function()
		{
		var rolloverCache = [];
		var inputs = document.getElementsByTagName('input');
		for (var x = 0; x < inputs.length; x++)
			{
			// Check if it's an image button with a roll over
			if (inputs[x].type == 'image' && inputs[x].className.indexOf('hasRollover') != -1)
				{
				// 1. Add event handlers to swap the images
				inputs[x].onmouseover = function()
					{
					this.src = this.src.replace(/\.(gif|jpg|png)/, '-over.$1');
					}
				inputs[x].onmouseout = function()
					{
					this.src = this.src.replace(/-over\.(gif|jpg|png)/, '.$1');
					}

				// 2. Pre-cache the rollover image
				var newImage = new Image();
				newImage.src = inputs[x].src.replace(/\.(gif|jpg|png)/i, '-over.$1');
				rolloverCache[rolloverCache.length] = newImage;
				}
			}
		}	
	}



/**
* Parses the supplied twitter feed and injects it into the document
* Looks for a document node with an id of "%twittername%TwitterContent" and failing that "twitterContent"
*
* @param		twitters			The twitter feed object
*/
function __parseTwitterFeed(twitters, containerId)
	{
	var statusHTML = [];
	var username = '';

	// Build the html for each tweet
	for (var i=0; i<twitters.length; i++)
		{
		// Parse the data
		username = twitters[i].user.screen_name;
		var status = twitters[i].text.replace(/((https?|s?ftp|ssh)\:\/\/[^"\s\<\>]*[^.,;'">\:\s\<\>\)\]\!])/g, function(url){return '<a class="link" href="'+url+'">'+url+'</a>';}).replace(/\B@([_a-z0-9]+)/ig, function(reply) {return  reply.charAt(0)+'<a class="reply" href="http://twitter.com/'+reply.substring(1)+'">'+reply.substring(1)+'</a>';});

		// Get the relative time
		var relativeTime = '';
		var timeValue = twitters[i].created_at;
		var values = timeValue.split(" ");
		timeValue = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
		var parsedDate = Date.parse(timeValue);
		var relativeTo = (arguments.length > 1) ? arguments[1] : new Date();
		var delta = parseInt((relativeTo.getTime() - parsedDate) / 1000);
		delta = delta + (relativeTo.getTimezoneOffset() * 60);
		if (delta < 60) relativeTime = 'less than a minute ago';
		else if(delta < 120) relativeTime = 'about a minute ago';
		else if(delta < (60*60)) relativeTime = (parseInt(delta / 60)).toString() + ' minutes ago';
		else if(delta < (120*60)) relativeTime = 'about an hour ago';
		else if(delta < (24*60*60)) relativeTime = 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
		else if(delta < (48*60*60)) relativeTime = '1 day ago';
		else relativeTime = (parseInt(delta / 86400)).toString() + ' days ago';

		// Add the tweet
		statusHTML.push('<li' + ((i+1)==twitters.length ? ' class="lastChild"' : '') + '><span>'+status+'</span> <a class="timestamp" href="http://twitter.com/'+username+'/statuses/'+twitters[i].id+'">'+relativeTime+'</a></li>');
		}

	// Inject the html into the document
	if (document.getElementById(username + 'TwitterContent')) document.getElementById(username + 'TwitterContent').innerHTML = statusHTML.join('\n');
	else if (document.getElementById('twitterContent')) document.getElementById('twitterContent').innerHTML = statusHTML.join('\n');
	}


/**
* Inherts a prototype from the specified class, updates the constructor reference
*
* @param		parent		The parent class or object
* @return		The inherted object
*/
Function.prototype.inheritsFrom = function( baseClass )
	{
	// Inherit the base class
	this.prototype = new baseClass;
	this.prototype.constructor = this;

	// Add access to the base's methods
	this.prototype.base = {};
	for (method in this.prototype)
		{
		// hasOwnProperty test is a workaround for "for..in" bug, see: http://yuiblog.com/blog/2006/09/26/for-in-intrigue/
		if (typeof this.prototype[method] === 'function' && this.prototype.hasOwnProperty(method) && this.prototype[method] !== this.prototype.constructor)
			{
			this.prototype.base[method] = this.prototype[method];
			}
		}
	return this;
	}