/*
 *	Javascript C++ Code Highlighter
 *	Version 0.1
 *	Created by Scott Bates
 *	Copyright © 2010 cplusdev
 */

var keywords = ['\\b' + "bool"			+ '\\b',
		'\\b' + "break"			+ '\\b',
		'\\b' + "case"			+ '\\b',
		'\\b' + "char"			+ '\\b',
		'\\b' + "class"			+ '\\b',
		'\\b' + "const"			+ '\\b',
		'\\b' + "delete"		+ '\\b',
		'\\b' + "double"		+ '\\b',
		'\\b' + "do"			+ '\\b',
		'\\b' + "dynamic_cast"		+ '\\b',
		'\\b' + "else"			+ '\\b',
		'\\b' + "enum"			+ '\\b',
		'\\b' + "extern"		+ '\\b',
		'\\b' + "false"			+ '\\b',
		'\\b' + "float"			+ '\\b',
		'\\b' + "for"			+ '\\b',
		'\\b' + "friend"		+ '\\b',
		'\\b' + "if"			+ '\\b',
		'\\b' + "inline"		+ '\\b',
		'\\b' + "int"			+ '\\b',
		'\\b' + "long"			+ '\\b',
		'\\b' + "main"			+ '\\b',
		'\\b' + "namespace"		+ '\\b',
		'\\b' + "new"			+ '\\b',
		'\\b' + "operator"		+ '\\b',
		'\\b' + "private"		+ '\\b',
		'\\b' + "protected"		+ '\\b',
		'\\b' + "public"		+ '\\b',
		'\\b' + "register"		+ '\\b',
		'\\b' + "reinterpret_cast"	+ '\\b',
		'\\b' + "return"		+ '\\b',
		'\\b' + "short"			+ '\\b',
		'\\b' + "signed"		+ '\\b',
		'\\b' + "sizeof"		+ '\\b',
		'\\b' + "static"		+ '\\b',
		'\\b' + "static_cast"		+ '\\b',
		'\\b' + "struct"		+ '\\b',
		'\\b' + "switch"		+ '\\b',
		'\\b' + "template"		+ '\\b',
		'\\b' + "this"			+ '\\b',
		'\\b' + "thread"		+ '\\b',
		'\\b' + "true"			+ '\\b',
		'\\b' + "typedef"		+ '\\b',
		'\\b' + "typeid"		+ '\\b',
		'\\b' + "typename"		+ '\\b',
		'\\b' + "union"			+ '\\b',
		'\\b' + "unsigned"		+ '\\b',
		'\\b' + "void"			+ '\\b',
		'\\b' + "while"			+ '\\b',
		'\\b' + "include"		+ '\\b',
		'\\b' + "define"		+ '\\b',
		'\\b' + "ifndef"		+ '\\b',
		'\\b' + "endif"			+ '\\b',
		"\\#"];

var keywordsColored = [	"\<font color=\"0077FF\"\>bool\</font\>",
			"\<font color=\"0077FF\"\>break\</font\>",
			"\<font color=\"0077FF\"\>case\</font\>",
			"\<font color=\"0077FF\"\>char\</font\>",
			"\<font color=\"0077FF\"\>class\</font\>",
			"\<font color=\"0077FF\"\>const\</font\>",
			"\<font color=\"0077FF\"\>delete\</font\>",
			"\<font color=\"0077FF\"\>double\</font\>",
			"\<font color=\"0077FF\"\>do\</font\>",
			"\<font color=\"0077FF\"\>dynamic_cast\</font\>",
			"\<font color=\"0077FF\"\>else\</font\>",
			"\<font color=\"0077FF\"\>enum\</font\>",
			"\<font color=\"0077FF\"\>extern\</font\>",
			"\<font color=\"0077FF\"\>false\</font\>",
			"\<font color=\"0077FF\"\>float\</font\>",
			"\<font color=\"0077FF\"\>for\</font\>",
			"\<font color=\"0077FF\"\>friend\</font\>",
			"\<font color=\"0077FF\"\>if\</font\>",
			"\<font color=\"0077FF\"\>inline\</font\>",
			"\<font color=\"0077FF\"\>int\</font\>",
			"\<font color=\"0077FF\"\>long\</font\>",
			"\<font color=\"0077FF\"\>main\</font\>",
			"\<font color=\"0077FF\"\>namespace\</font\>",
			"\<font color=\"0077FF\"\>new\</font\>",
			"\<font color=\"0077FF\"\>operator\</font\>",
			"\<font color=\"0077FF\"\>private\</font\>",
			"\<font color=\"0077FF\"\>protected\</font\>",
			"\<font color=\"0077FF\"\>public\</font\>",
			"\<font color=\"0077FF\"\>register\</font\>",
			"\<font color=\"0077FF\"\>reinterpret_cast\</font\>",
			"\<font color=\"0077FF\"\>return\</font\>",
			"\<font color=\"0077FF\"\>short\</font\>",
			"\<font color=\"0077FF\"\>singed\</font\>",
			"\<font color=\"0077FF\"\>sizeof\</font\>",
			"\<font color=\"0077FF\"\>static\</font\>",
			"\<font color=\"0077FF\"\>static_cast\</font\>",
			"\<font color=\"0077FF\"\>struct\</font\>",
			"\<font color=\"0077FF\"\>switch\</font\>",
			"\<font color=\"0077FF\"\>template\</font\>",
			"\<font color=\"0077FF\"\>this\</font\>",
			"\<font color=\"0077FF\"\>thread\</font\>",
			"\<font color=\"0077FF\"\>true\</font\>",
			"\<font color=\"0077FF\"\>typedef\</font\>",
			"\<font color=\"0077FF\"\>typeid\</font\>",
			"\<font color=\"0077FF\"\>typename\</font\>",
			"\<font color=\"0077FF\"\>union\</font\>",
			"\<font color=\"0077FF\"\>unsigned\</font\>",
			"\<font color=\"0077FF\"\>void\</font\>",
			"\<font color=\"0077FF\"\>while\</font\>",
			"\<font color=\"0077FF\"\>include\</font\>",
			"\<font color=\"0077FF\"\>define\</font\>",
			"\<font color=\"0077FF\"\>ifndef\</font\>",
			"\<font color=\"0077FF\"\>endif\</font\>",
			"\<font color=\"0077FF\"\>#\</font\>"];

//===============================================================//
// I'm pretty sure this function is enabled in 'most' browers now//
// but just to be safe.                                          //
//===============================================================//
document.getElementsByClassName = function(className)
{
	// classList is going to be used to hold a list of nodes of className.
	var classList = [];

	// myclass holds the input paramater wraped in '\\b' to make sure we only match "whole words".
	var myclass = new RegExp('\\b'+className+'\\b');
	
	// elem holds a list of every created element tag used in your html file
	var elem = this.getElementsByTagName('*');

	// loop through every element tag inside elem
	for (var i = 0; i < elem.length; i++) 
	{
		// Test each elem/s className against the paramater we wraped in '\\b'
		if (myclass.test(elem[i].className)) 
		{
			//If one of them successfully mated add it to our classList
			classList.push(elem[i]);
		}
	}
	// return all the matches we found.
	return classList;
};

//=========================================//
// Function used to highlight our keywords.//
//=========================================//
function wordhighlight(aSourceObject, sWords, sDescrip)
{
	// sTexts holds our code box in this cases content
	// might change this and strip the tags.
	var sText = aSourceObject.innerHTML;

	// http://www.regular-expressions.info/anchors.html
	// /g enables "global" matching. When using the replace() method. /i makes the regex match case insensitive. /m enables "multi-line mode".
	
	// For the side of our keywords array iterate through it.
	for( var i = 0; i < sWords.length; i++ )
	{
		// If we find any matches with our words - then replace them with the colored version.
		sText = sText.replace( new RegExp(sWords[i], "g"), sDescrip[i]); 
	}

	// Once we are done apply the changes to the original html
	aSourceObject.innerHTML = sText;
};

//=========================================================================================//
// Function to change a character from '+' etc to '\+' - Has a bug adds a \ to the display //
//=========================================================================================//
function replaceChar(dataStr, char)
{
	var replace = '\\' + char;
	return dataStr.replace( new RegExp('\\' + char, "g"), replace);
};
//=====================================================================//
// Function thats called on the windows load - to make all our changes //
//=====================================================================//
window.onload = function () 
{
	// Works for finding comments! - /* */ comments crash it ?
	// '(\\/\\*(\\s*|.*?)*\\*\\/)|(\\/\\/.*)',

	var mHTML = document.getElementsByClassName("code");
	var browser = navigator.userAgent.toLowerCase();

	for( var i = 0; i < mHTML.length; i++ )
	{
		// Extracts the HTML from the code box
		var sText = mHTML[i].innerHTML;

		// Extracts the string from sText and removes tags
		var code = sText.replace(/<[^>]*>/g,"");
		
		// Result holds an array of all the // commented code
		var result = code.match( new RegExp('(\\/\\*(\\s\\*|.\\*?)*\\*\\/)|(\\/\\/.*)', "g") );

		// Create an array to hold our changed changed comments
		var changed = [];
		if( result )
		{
			for( var i = 0; i < result.length; i++ )
			{
				result[i] = replaceChar(result[i], '\+');
				result[i] = replaceChar(result[i], '(');
				result[i] = replaceChar(result[i], ')');
				result[i] = replaceChar(result[i], '*');
				result[i] = replaceChar(result[i], '[');
				result[i] = replaceChar(result[i], ']');

				if (browser.indexOf("firefox") != -1)
				{
					var str1 = '<span style="color: #458B00;">';
					var str2 = result[i];
					var str3 = '</span>';
					var str4 = str1.concat(str2, str3);

					changed[i] = str4;
				}
				else
				{	
					var str1 = '<font color="458B00">';
					var str2 = result[i];
					var str3 = '</font>';
					var str4 = str1.concat(str2, str3);

					changed[i] = str4;
				}
			}
		}

		for( var i = 0; i < mHTML.length; i++ )
		{	
			// Color all the comments green
			if(result)
			{
				wordhighlight(mHTML[i], result, changed);
			}
			// Color all the keywords blue
			wordhighlight(mHTML[i], keywords, keywordsColored);
		}
	}
};