//=============================================
/*
				StringFuncs
		An object created to allow easy string
		manipulation.  It is made up of quasi-static
		functions... meaning the functions within
		are meant to be used as if this were a
		DOM object, like Math or Number.
		
			usage example:
		var oldString = "This\nIs\n\tMy\nLife.";
		var strFunc = new StringFuncs();
		var newString = strFunc.toHTML(oldString);
		
		newString == "This<br />\nIs<br />\n&nbsp; \tMy<br />\nLife."
*/
//=============================================
function StringFuncs()
{
	// -- Checks to make sure the incoming string is really a string --	
	this.isString = function( iStr ){
		return (typeof(iStr) == "string");
	}
	
	// -- nl2br: changes Newlines to <br /> --
	this.nl2br = function( iStr, iKeepNewlines ){
		if( this.isString(iStr) )
		{
			var re_Newline = new RegExp("\n", "g");
			return iStr.replace(re_Newline, (iKeepNewlines?'<br />\n':'<br />'));
		}
		else
			return iStr; // return whatever they sent in if it's not a string.
	}
	
	// -- tab2Spaces: changes Tabs to [&nbsp; ] (brackets here to show the extra space) --
	this.tab2Spaces = function( iStr, iKeepTabs ){
		if( this.isString(iStr) )
		{
			var re_tab = new RegExp("\t", "g");
			return iStr.replace(re_tab, (iKeepTabs?'&nbsp; \t':'&nbsp; '));
		}
		else
			return iStr; // return whatever they sent in if it's not a string.
	}
	
	// -- escapeHtmlTags: converts <> to &lt; &gt; respectively --
	this.escapeHtmlTags = function( iStr ){
		if( this.isString(iStr) )
		{
			var temp = iStr;
			var re_tagOpen = /[<]/g;
			var re_tagClose = /[>]/g;
			temp = temp.replace(re_tagOpen, "&lt;");
			temp = temp.replace(re_tagClose, "&gt;");
			return temp;
		}
		else
			return iStr;
	}
	
	this.lineComments2Html = function( iStr ){
		if( this.isString(iStr) )
		{
			var re_lineComment = /(\/\/(.*))$/g;
			var temp = iStr.replace(re_lineComment, '<span class="code-lineComment">$1</span>');
//alert(temp);
			return temp;
		}
		else
			return iStr;
	}
	
	this.toHTML = function( iStr, iPreserveWhitespace )
	{
		var temp = iStr;
		temp = this.escapeHtmlTags(temp);
//		temp = this.nl2br(temp, iPreserveWhitespace);
		temp = this.tab2Spaces(temp, iPreserveWhitespace);
		temp = this.lineComments2Html(temp);
		return temp;
	}
}

function PrepStringForHTML( iString )
{
/*
	var re_tab = new RegExp("\t", "g");
	var re_tagOpen = /[<]/g;
	var re_tagClose = /[>]/g;
	var re_lineComment = /(\/\/(.*))/g;
	var temp = iString;
	temp = temp.replace(re_tab, "&nbsp;  ");
	temp = temp.replace(re_tagOpen, "&lt;");
	temp = temp.replace(re_tagClose, "&gt;");
	return temp;
*/
	var strFunc = new StringFuncs();
	return strFunc.toHTML(iString);
}

//------------------------------------------------------------------------------
//=============================================
/*
			FunctionToString()
		Attach this to a function's toString
		property by calling:
		AssignFunctionToString( <functionName> );
		
		By default, it will just call the function's
		basic toString() functionality.
		
		However, if you explicitly call:
		<functionName>.toString(true[, true])
		it will return the HTML version.
		
		iPreserveWhitespace is an optional parameter as well.
		Setting it to true will cause the HTML converter to
		not only convert the whitespace to it's HTML counterpart,
		but will keep the original whitespace as part of the 
		returned string.
*/
//=============================================
function FunctionToString( iAsHTML, iPreserveWhitespace )
{
	var temp = '';
	if( typeof(this) == "function" )
	{
		try
		{
			var strFunc = new StringFuncs();
			if( iAsHTML )
				return strFunc.toHTML(this.oldToString(), iPreserveWhitespace);
			else
				return this.oldToString();
		}
		catch( e )
		{
			throw new Error("FunctionToString Error: " + e.message);
		}
	}
	
	return temp;
}


function AssignFunctionToString( iFunctionObj )
{
	if( typeof(iFunctionObj) == "function" )
	{
		// assign native code to oldToString property.
		iFunctionObj.oldToString = iFunctionObj.toString;
		// assign toString property to new function.
		iFunctionObj.toString = FunctionToString;
	}
}

//------------------------------------------------------------------------------
//				AddCodeToNode
//------------------------------------------------------------------------------
function AddCodeToNode( iDisplayNode, iFunction )
{
	if( iDisplayNode && typeof(iFunction) == "function" )
	{
		var fCode = "";
		fCode += "<pre>\n" + PrepStringForHTML(iFunction.toString()) + "</pre>\n";
		iDisplayNode.innerHTML += fCode;
	}
}
