/*
 * colorCode function by Paul Klinkenberg
 * http://www.coldfusiondeveloper.nl/
 *
 * Date: 2009-04-17 17:30:00 +0100
 * Revision: 1
 *
 * Copyright (c) 2009 Paul Klinkenberg, Ongevraagd Advies
 * Licensed under the GPL license.
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *    ALWAYS LEAVE THIS COPYRIGHT NOTICE IN PLACE!
 
 *    June 13, 2010, Paul Klinkenberg, www.coldfusiondeveloper.nl
 *    Version 1.0.1
 *    - Changed the tagPlaceholderString, so it won't get added up with urls anymore
 *
 */

var preHTMLTags = new Array();
var tagPlaceholderString = "	HTmltAG	";
var pretags = new Array();

function colorcode()
{
	// old browsers? get out of here
	if (!document.getElementsByTagName)
		return;
	
	// get all pre-elements from the document
	pretags = $("pre:not('.colored')");
	
	// loop throught the pre elements
	for (var arrIndex=0; arrIndex<pretags.length; arrIndex++)
	{
		/* get the pre-tag's contents.
		 * Unfortunately, the stupid IE browser does not return the html that was in the document,
		 * but instead returns an ugly html-parsed string. Luckily, the html entities are not color-coded :-)
		 */
		var preContent = pretags.get(arrIndex).innerHTML;
		
		/* temporarily remove (and remember) all bare html tags inside the pre content */
		// remember the tags
		preHTMLTags[arrIndex] = preContent.match(/<.*?>/g);
		// remove the tags
		preContent = preContent.replace(/<.*?>/g, tagPlaceholderString);
		
		/* now replace all html entities (like &lt; and &quot;) back to their original characters */
		preContent = replaceHtmlEntities(preContent);

		/* now call the server-side function to replace the pre-text */
		$.ajax({
			url: '/colorcode-js/doColorcoding.cfm',
			type: 'POST',
			data: {text:preContent, ref:arrIndex},
			dataType: 'xml',
			timeout: 5000,
			error: loadError,
			success: replacePreText
		});
	}
	
	function loadError(){
		/* too bad, but nothing breaks because of this, so never mind */
	}
	
	function replacePreText(xml)
	{
		var colorText = xml.getElementsByTagName("text")[0].firstChild.data;
		var ref = parseInt(xml.getElementsByTagName("ref")[0].firstChild.data);
	
		/* the component wraps the color-text in <pre> tags; remove them. */
		colorText = colorText.replace(/<\/?pre>/gi, "");
		
		/* re-add the html tags, if any */
		if (preHTMLTags[ref])
		{
			for (var tagArrIndex=0; tagArrIndex < preHTMLTags[ref].length; tagArrIndex++)
			{
				colorText = colorText.replace(tagPlaceholderString, preHTMLTags[ref][tagArrIndex]);
			}
		}

		/* now change the pre-text in the document */
		/* Workaround is necessary for IE's innerHTMl.
		 * The browser is being stupid again, see http://www.quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
		 */
		if ("outerHTML" in pretags.get(ref))
		{
			pretags.get(ref).outerHTML = "<pre>" + colorText + "</pre>";
		} else
		{
			pretags.get(ref).innerHTML = colorText;
		}
	}
}

/* this function is based on the code at http://www.irt.org/script/243.htm
 */
function replaceHtmlEntities(text) {
    text = text.replace(/&Agrave;/g, unescape("%C0"));
    text = text.replace(/&Aacute;/g, unescape("%C1"));
    text = text.replace(/&Acirc;/g, unescape("%C2"));
    text = text.replace(/&Atilde;/g, unescape("%C3"));
    text = text.replace(/&Auml;/g, unescape("%C4"));
    text = text.replace(/&Aring;/g, unescape("%C5"));
    text = text.replace(/&AElig;/g, unescape("%C6"));
    text = text.replace(/&Ccedil;/g, unescape("%C7"));
    text = text.replace(/&Egrave;/g, unescape("%C8"));
    text = text.replace(/&Eacute;/g, unescape("%C9"));
    text = text.replace(/&Ecirc;/g, unescape("%CA"));
    text = text.replace(/&Euml;/g, unescape("%CB"));
    text = text.replace(/&Igrave;/g, unescape("%CC"));
    text = text.replace(/&Iacute;/g, unescape("%CD"));
    text = text.replace(/&Icirc;/g, unescape("%CE"));
    text = text.replace(/&Iuml;/g, unescape("%CF"));
    text = text.replace(/&ETH;/g, unescape("%D0"));
    text = text.replace(/&Ntilde;/g, unescape("%D1"));
    text = text.replace(/&Ograve;/g, unescape("%D2"));
    text = text.replace(/&Oacute;/g, unescape("%D3"));
    text = text.replace(/&Ocirc;/g, unescape("%D4"));
    text = text.replace(/&Otilde;/g, unescape("%D5"));
    text = text.replace(/&Ouml;/g, unescape("%D6"));
    text = text.replace(/&Oslash;/g, unescape("%D8"));
    text = text.replace(/&Ugrave;/g, unescape("%D9"));
    text = text.replace(/&Uacute;/g, unescape("%DA"));
    text = text.replace(/&Ucirc;/g, unescape("%DB"));
    text = text.replace(/&Uuml;/g, unescape("%DC"));
    text = text.replace(/&Yacute;/g, unescape("%DD"));
    text = text.replace(/&THORN;/g, unescape("%DE"));
	// next lines are case-insensitive
	text = text.replace(/&quot;/gi, unescape("%22"));
    text = text.replace(/&lt;/gi, unescape("%3C"));
    text = text.replace(/&gt;/gi, unescape("%3E"));
    text = text.replace(/&nbsp;/gi, unescape("%A0"));
    text = text.replace(/&iexcl;/gi, unescape("%A1"));
    text = text.replace(/&cent;/gi, unescape("%A2"));
    text = text.replace(/&pound;/gi, unescape("%A3"));
    text = text.replace(/&yen;/gi, unescape("%A5"));
    text = text.replace(/&brvbar;/gi, unescape("%A6"));
    text = text.replace(/&sect;/gi, unescape("%A7"));
    text = text.replace(/&uml;/gi, unescape("%A8"));
    text = text.replace(/&copy;/gi, unescape("%A9"));
    text = text.replace(/&ordf;/gi, unescape("%AA"));
    text = text.replace(/&laquo;/gi, unescape("%AB"));
    text = text.replace(/&not;/gi, unescape("%AC"));
    text = text.replace(/&shy;/gi, unescape("%AD"));
    text = text.replace(/&reg;/gi, unescape("%AE"));
    text = text.replace(/&macr;/gi, unescape("%AF"));
    text = text.replace(/&deg;/gi, unescape("%B0"));
    text = text.replace(/&plusmn;/gi, unescape("%B1"));
    text = text.replace(/&sup2;/gi, unescape("%B2"));
    text = text.replace(/&sup3;/gi, unescape("%B3"));
    text = text.replace(/&acute;/gi, unescape("%B4"));
    text = text.replace(/&micro;/gi, unescape("%B5"));
    text = text.replace(/&para;/gi, unescape("%B6"));
    text = text.replace(/&middot;/gi, unescape("%B7"));
    text = text.replace(/&cedil;/gi, unescape("%B8"));
    text = text.replace(/&sup1;/gi, unescape("%B9"));
    text = text.replace(/&ordm;/gi, unescape("%BA"));
    text = text.replace(/&raquo;/gi, unescape("%BB"));
    text = text.replace(/&frac14;/gi, unescape("%BC"));
    text = text.replace(/&frac12;/gi, unescape("%BD"));
    text = text.replace(/&frac34;/gi, unescape("%BE"));
    text = text.replace(/&iquest;/gi, unescape("%BF"));
    text = text.replace(/&times;/gi, unescape("%D7"));
    text = text.replace(/&szlig;/gi, unescape("%DF"));
    text = text.replace(/&agrave;/gi, unescape("%E0"));
    text = text.replace(/&aacute;/gi, unescape("%E1"));
    text = text.replace(/&acirc;/gi, unescape("%E2"));
    text = text.replace(/&atilde;/gi, unescape("%E3"));
    text = text.replace(/&auml;/gi, unescape("%E4"));
    text = text.replace(/&aring;/gi, unescape("%E5"));
    text = text.replace(/&aelig;/gi, unescape("%E6"));
    text = text.replace(/&ccedil;/gi, unescape("%E7"));
    text = text.replace(/&egrave;/gi, unescape("%E8"));
    text = text.replace(/&eacute;/gi, unescape("%E9"));
    text = text.replace(/&ecirc;/gi, unescape("%EA"));
    text = text.replace(/&euml;/gi, unescape("%EB"));
    text = text.replace(/&igrave;/gi, unescape("%EC"));
    text = text.replace(/&iacute;/gi, unescape("%ED"));
    text = text.replace(/&icirc;/gi, unescape("%EE"));
    text = text.replace(/&iuml;/gi, unescape("%EF"));
    text = text.replace(/&eth;/gi, unescape("%F0"));
    text = text.replace(/&ntilde;/gi, unescape("%F1"));
    text = text.replace(/&ograve;/gi, unescape("%F2"));
    text = text.replace(/&oacute;/gi, unescape("%F3"));
    text = text.replace(/&ocirc;/gi, unescape("%F4"));
    text = text.replace(/&otilde;/gi, unescape("%F5"));
    text = text.replace(/&ouml;/gi, unescape("%F6"));
    text = text.replace(/&divide;/gi, unescape("%F7"));
    text = text.replace(/&oslash;/gi, unescape("%F8"));
    text = text.replace(/&ugrave;/gi, unescape("%F9"));
    text = text.replace(/&uacute;/gi, unescape("%FA"));
    text = text.replace(/&ucirc;/gi, unescape("%FB"));
    text = text.replace(/&uuml;/gi, unescape("%FC"));
    text = text.replace(/&yacute;/gi, unescape("%FD"));
    text = text.replace(/&thorn;/gi, unescape("%FE"));
    text = text.replace(/&yuml;/gi, unescape("%FF"));
	
	/* the &amp; must go last, because it otherwise may replace other entities,
	 * i.e. '&amp;lt;' must become '&lt;', not '<'.
	 */
    text = text.replace(/&amp;/gi, unescape("%26"));

   return text;
}

/* make sure the function is run when the page has loaded */
$(colorcode);
