var dom =
{
	onload : function(strFunction)
	{
		if (document.getElementsByTagName && document.getElementById)
		{
			// set our counter variable to 0, otherwise increment it
			intCounter = (typeof intCounter == 'undefined') ? 1 : intCounter + 1;
	
			// for compliant browsers, check if the body tag exists yet and if the first (and only) body tag isn't null
			if (typeof document.getElementsByTagName != 'undefined' && document.getElementsByTagName('body')[0] != null)
			{
				// functions to be loaded when DOM is ready
				strFunction();
			}
		
			// otherwise, wait a little while then run the startDOM function again (stops after 15 seconds)
			else if(intCounter <= 60)
			{
				setTimeout(function() { dom.onload(strFunction) }, 250);
			};
		};
	}
};

var cookie =
{
	/*
		cookie.save("Surname", "Rotherham", 60);
		cookie.load("Surname");
		cookie.clear("Surname");
	
		alert(cookie.load("Surname", true));
	*/

	value : function(strReturnName, strQueryString, strSeparator)
	{
		// an array of each name/value pair
		var strVariables = strQueryString.split(strSeparator);
	
		// loop through each name/value pair
		for (var i = 0; i < strVariables.length; i++)
		{
			// split apart the name and value
			var strPair = strVariables[i].split("=");
			var strName = strPair[0];
			var strValue = strPair[1];
	
			// return the value if it's name matches strReturnName
			if (strName == strReturnName)
			{
				return strValue;
			}
		}
	},

	save : function(strCookieName, strCookieValue, intExpirySeconds)
	{
		// create date object
		var strDate = new Date();

		// set seconds to -1 if seconds are in the past
		intExpirySeconds = (intExpirySeconds <= 0)? -1 : intExpirySeconds;

		// convert to a cookie friendly format
		strDate.setTime(strDate.getTime() + (intExpirySeconds * 1000));

		// append expiry onto cookie name/value pair
		var strExpires = "; expires=" + strDate.toGMTString();
		document.cookie = strCookieName + "=" + strCookieValue + strExpires;
	},

	load : function(strCookieName)
	{
		// read existing cookie
		var strDocumentCookie = document.cookie;

		// extract value from cookie string
		var strCookieValue = unescape(this.value(strCookieName, strDocumentCookie, "; "));

		return strCookieValue;
	},

	clear : function(strCookieName)
	{
		// use the existing save function but force it to expire instantly
		this.save(strCookieName, "", 0);
	}
};

var query =
{
	extract : function(strType, strQueryString, strSeparator, strReturnName)
	{
		// an array of each name/value pair
		this.array = strQueryString.split(strSeparator);

		if (strType == "array") return this.array;

		// loop through each name/value pair
		for (var i = 0; i < this.array.length; i++)
		{
			// split apart the name and value
			var strPair = this.array[i].split("=");
			var strName = strPair[0];
			var strValue = strPair[1];
	
			// return the value if it's name matches strReturnName
			if (strName == strReturnName)
			{
				return strValue;
			}
		}
	}
};

var node =
{
	setup : function()
	{
		this.id = query.extract("value", this.attributes, "&", "id");
		this.node = document.createElement(this.tag);
		if (this.attributes != "") this.attributes = query.extract("array", this.attributes, "&");

		for (var i = 0; i < this.attributes.length; i++)
		{
			arrAttributes = this.attributes[i].split("=");
			strAttribute = arrAttributes[0];
			strValue = unescape(arrAttributes[1]);
			this.node.setAttribute(strAttribute, strValue);
		}

		return this.node;
	},

	write : function()
	{
		this.textnode = document.createTextNode(this.text);
		this.node.appendChild(this.textnode);
	},

	create : function(strTagName, strAttributes, strText)
	{
		this.tag = strTagName;
		this.text = strText;
		this.attributes = strAttributes;

		this.setup();
		if (this.text != "") this.write();

		return this.node
	},

	place : function(objNode, objLocation)
	{
		objLocation.appendChild(objNode);
	},

	loop : function(strTagName, objParent, objFunction)
	{
		if (parseInt(strTagName) > 0)
		{
			intLength = parseInt(strTagName);
		}
		else
		{
			this.array = objParent.getElementsByTagName(strTagName);
			intLength = this.array.length;
		}

		for (var i = 0; i < intLength; i++)
		{
			objFunction(intLength[i], objParent, i);
		}
	}
};

var event =
{
	add : function(strEvent, objNode, strFunction)
	{
		if (objNode.addEventListener)
		{
			this.W3C = true;
			objNode.addEventListener(strEvent, strFunction, false);
			objNode.addEventListener(strEvent, event.reset, false);
		}
		else if (objNode.attachEvent)
		{
			this.W3C = false;
			strEvent = "on" + strEvent;
			objNode.attachEvent(strEvent, strFunction);
			objNode.attachEvent(strEvent, event.reset);
		}
	},

	reset : function(e)
	{
		if (event.W3C == true) e.preventDefault();
		return false;
	}
};

var mouse =
{
	location : function(event)
	{
		// start with some defaults
		this.posX = 0;
		this.posY = 0;

		// if we're using a new browser we can grab the event - otherwise use the global
		if (!event) var event = window.event;

		// choices for two types of browser below
		if (event.pageX || event.pageY)
		{
			this.posX = event.pageX;
			this.posY = event.pageY;
		}
		else if (event.clientX || event.clientY)
		{
			this.posX = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
			this.posY = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
		}
	}
};

var display =
{
	dimensions : function()
	{
		this.adjustY = 0;

		// total scrollable area
		if (window.innerHeight && window.scrollMaxY)
		{	
			this.scrollableX = document.body.scrollWidth;
			this.scrollableY = window.innerHeight + window.scrollMaxY;
			this.adjustY = (this.width - document.body.scrollWidth);
		}
		else if (document.body.scrollHeight > document.body.offsetHeight)
		{
			this.scrollableX = document.body.scrollWidth;
			this.scrollableY = document.body.scrollHeight;
		}
		else
		{
			this.scrollableX = document.body.offsetWidth;
			this.scrollableY = document.body.offsetHeight;
		}

		// try and grab the window's inner width supporting various browsers
		if (self.innerHeight)
		{
			this.width = self.innerWidth;
			this.height = self.innerHeight;
		}
		else if (document.documentElement && document.documentElement.clientHeight)
		{
			this.width = document.documentElement.clientWidth;
			this.height = document.documentElement.clientHeight;
		}
		else if (document.body)
		{
			this.width = document.body.clientWidth;
			this.height = document.body.clientHeight;
		}

		this.pageX = this.width - this.scrollbar;
		this.pageY = this.height;

		// additional scroll area
		if (self.pageYOffset)
		{
			this.scrollX = pageXOffset;
			this.scrollY = pageYOffset;
		}
		else if (document.documentElement && document.documentElement.scrollTop)
		{
			this.scrollX = document.documentElement.scrollLeft;
			this.scrollY = document.documentElement.scrollTop;
		}
		else if (document.body)
		{
			this.scrollX = document.body.scrollLeft;
			this.scrollY = document.body.scrollTop;
		}

		this.pageX = (this.width > this.scrollableX + this.adjust)? this.width : this.scrollableX;
		this.pageY = (this.height > this.scrollableY)? this.height : this.scrollableY;
	}
};