﻿/*
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:

try
{ var test = (NETJOHNHENRY.name == 'NETJOHNHENRY'); }
catch (e)
{ NETJOHNHENRY = {}; }

What about:

if (typeof NETJOHNHENRY === 'undefined')
{ NETJOHNHENRY = {}; }


*/

var NETJOHNHENRY = {

	name : 'NETJOHNHENRY',
	description : 'Library namespace static object',
	libraryPath : '',
	loadedModules : {},

	require : function ( path, node ) {
		/* Used to include external javascript */
		if (!this.loadedModules[path])
		{
			var destinationNode = ( node ) ? node : document.getElementsByTagName('head')[0];
			var tag = document.createElement('script');
			tag.src = path;
			tag.type = 'text/javascript';
			var coreLibrary = document.getElementById('jhLibrary');

			// insertBefore is effectively the same as appendChild when coreLibrary is null
			destinationNode.insertBefore( tag, coreLibrary );

			this.loadedModules[path] = true;
		}
	},
	
	requireStyles : function ( s, node ) {
		/* Used to include external css */
		var destinationNode = ( node ) ? node : document.getElementsByTagName('head')[0];
		var tag = document.createElement('style');
		tag.type = 'text/css';
		tag.innerHTML = s;
		destinationNode.appendChild(tag);
	},
	
	delegate : function ( 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.
		*/
		context.delegatedFunction = func;
		context.delegatedFunction( parameters );
	},
	
	introspect : function(){	
		//function to inject later on, parameters: the object to compare and the array
		var isObjectAlreadyInspected = function(o,a){				
			for(var i = 0; i<arguments[1].length; i++){
				if(arguments[0] == arguments[1][i]){						
					return true;
				}					
			}
			return false;				
		}		
	    this.objects = this.objects == undefined ? new Array() : this.objects;
	    var obj = arguments[0] == undefined ? window.NETJOHNHENRY : arguments[0];			
        this.objects.push(obj);
		var output = '';
	    for(var i in obj){
			if((typeof(obj[i]) =='object' || typeof(obj[i]) == 'function') && !isObjectAlreadyInspected(obj[i], this.objects) && i !='prototype' && i != 'parameters'){
				output += '<li> + ' + typeof(obj[i]) + ': <h2><code>' + i + '</code></h2></li>';
				try{	
					var parameters = obj[i].parameters;
					if(parameters){		
						poutput = '';										
						if(typeof(parameters) == 'string'){
							poutput +=  'parameters: (<code>string: ' + parameters + '</code>)';							
						}else{
							for (var p in parameters) {
								poutput += typeof(parameters[p]) + ': ' + p + '[default value: ' + parameters[p].toString() + '] ';
							}
							poutput = 'parameters: { <code>' + poutput + '</code>}';
						}
						output += '<li><span class="parameters">'+ poutput +'</span></li>';
					}
					var description = obj[i].description;						
					if(description){
						output +='<li><span class="description">description: ' + description + '</span></li>';
					}
					
				}catch(e){}
				var introspect_output = NETJOHNHENRY.introspect(obj[i]);
				if(introspect_output != ''){
					output +='<li>' + introspect_output+ '</li>';
				}
			}
	    }
		return '<ul>' + output + '</ul>';

	},
	
	introspectAndOutputIntoNode: function(nodeid_or_tagname){
		NETJOHNHENRY.introspectAndOutputIntoNode.parameters = 'nodeid_or_tagname';
		NETJOHNHENRY.introspectAndOutputIntoNode.description ='This function calls the introspect function and place the text result into a dom node or if not passed the html page body ';			
		var nodeid_or_tagname = (nodeid_or_tagname == undefined)? 'body' : nodeid_or_tagname;
		var node = document.getElementById(nodeid_or_tagname);		
		if (node == undefined) { 
			var nodes = document.getElementsByTagName(nodeid_or_tagname);			
			if(nodes != undefined){
				node = nodes[0];
			}
		}
		if(node == undefined){alert('Output error: cannot find node');}
		
		var output = this.introspect();
		output  = output.replace(/\n/g, '<br/>');
		output  = output.replace(/<</g, '<h2>');		
		output  = output.replace(/>>/g, '</h2>');
		output  = output.replace(/<\/h2><br\/>/g, '</h2>');
		//output  = output.replace(/<code>/g, '<b>');
		//output  = output.replace(/<\/code>/g, '</b>');		
		
		node.innerHTML = '<style>code{color:green;}.description{color:#966;}.parameters{color:#c00;}h2{display:inline; font-size:1.3em;}</style><h1><code>NETJOHNHENRY</code></h1>' + output;
	},

	cloneObject : function (o)
	{
		this.cloneObject.description = 'This function duplicates a node.';		
		
		if (typeof o != 'object' || o == null) 
		{
			return o;
		}
	
		var clone = new Object();
	
		for (var i in o)
		{
			clone[i] = NETJOHNHENRY.cloneObject(o[i]);
		}
	
		return clone;
	},	
	getQueryString : function(name)
	{
		//Author: Giuseppe
		//Date: 28/04/2008
		//NOTE: This function initializes the NETJOHNHENRY.queryString object with all querystrings
		//note that NETJOHNHENRY.getQueryString(name) returns always a string
		//while NETJOHNHENRY.queryString[name] returns undefined if the string is not found.

		if (NETJOHNHENRY.queryString == undefined) 
		{
			NETJOHNHENRY.queryString = {};			
			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('=');
					NETJOHNHENRY.queryString[vp[0]] = vp[1];
				}
			}
		}
		return NETJOHNHENRY.queryString[name] || '';
		
	},

	dummy:{}
};

