﻿/*
 netjohnhenry.js
 2 November 2007
 Global namespace initialisation.
 Objects which live within the NETJOHNHENRY namespace should always check for existence first,
 and if the namespace object does not exists, create it. Code for doing so:
 NETJOHNHENRY = window.NETJOHNHENRY || {};
 */
var NETJOHNHENRY = (function()
{
	var name = 'NETJOHNHENRY';
	var description = 'Library namespace static object';
	var libraryPath = '';
	var loadedModules = {};
	var queryString = {};

	function require(path, node)
	{
		/* Used to include external javascript */
		if (!loadedModules[path])
		{
			var destinationNode = (node) ? node : document.getElementsByTagName('head')[0];
			var tag = document.createElement('script');
			tag.setAttribute('src', path);
			tag.setAttribute('type', 'text/javascript');
			var coreLibrary = document.getElementById('jhLibrary');

			// insertBefore is effectively the same as appendChild when coreLibrary is null
			destinationNode.insertBefore(tag, coreLibrary);

			loadedModules[path] = true;
		}
	}

	function requireStyles(s, node)
	{
		/* Used to include external css */
		var destinationNode = (node) ? node : document.getElementsByTagName('head')[0];
		var tag = document.createElement('style');
		tag.setAttribute('type', 'text/css');
		tag.appendChild(document.createTextNode(s));
		destinationNode.appendChild(tag);
	}

	function delegate(context, func, parameters)
	{
		/*
		Delegate can be used with setTimeout to allow "this" to be set to the correct context
		in the delegated function. Assumes parameters is an object literal.
		*/
		func.call(context, parameters);
	}


	function cloneObject(o)
	{
		var i, clone = {};

		if (typeof o != 'object' || o === null)
		{
			return o;
		}

		for (prop in o)
		{
			if (o.hasOwnProperty(prop))
			{
				clone[prop] = NETJOHNHENRY.cloneObject(o[prop]);
			}
		}
		return clone;
	}

	function getQueryString(name)
	{
		if (name && !queryString[name])
		{
			var q = document.location.search.split('?').join('');

			if (q !== '')
			{
				q = q.split('&');
				for (var i = 0; i < q.length; i++)
				{
					var vp = q[i].split('=');
					queryString[vp[0]] = vp[1];
				}
			}
		}
		if (name)
		{
			return queryString[name];
		}
		else
		{
			return queryString;
		}
	}

	function trimString(s)
	{ return s.replace(/^\s+|\s+$/g,''); }

	function normaliseEvent(e)
	{
		return e || window.event;
	}
	
	function normaliseEventTarget(e)
	{
		e = normaliseEvent(e);
		var targ = e.target || e.srcElement;
		if (targ.nodeType == 3) // defeat Safari bug
		{ targ = targ.parentNode; }
		return targ;
	}

	return {
		name: name,
		description: description,
		libraryPath: libraryPath,
		loadedModules: loadedModules,
		require: require,
		requireStyles: requireStyles,
		delegate: delegate,
		cloneObject: cloneObject,
		getQueryString: getQueryString,
		trimString: trimString,
		normaliseEvent: normaliseEvent,
		normaliseEventTarget: normaliseEventTarget
	};

})();


