/*
 * Lipt: List injection for PRE tags
 * Author: Choan C. Galvez <choan(a)alice.0z0ne.com> <http://dizque.lacalabaza.net>
 * Suggested by Ingo Chao <http://www.satzansatz.de/cssd/listinjection.html>
 * Version: 0.2 BETA
 *
 * License: Anyone you like. Provided as is, no warranty, blah blah. Use at your own risk.
 */


function lipt() {
	
	/* change to FALSE if you don't want to proccess comments (boogie buggy) */
	var PROCCESS_COMMENTS = true; 

	if (!document.getElementsByTagName) {
		return;
	}

	// look for pre tags in the doc
	var pres = document.getElementsByTagName('pre');

	if (0 == pres.length) {
		return; // no pre tags, nothing to do
	}

	for (var i = 0; i < pres.length; i++) {
		var pre = pres[i];

		// search ONE code tab inside the pre
		var code = pre.getElementsByTagName('code')[0];
		
		if (null == code) {
			continue; // no one here, try with the next pre tag
		}

		// go for the job
		var inMultiLineComment = false;
		
		var content = getText(code);

		// normalize new lines
		if (!window.opera) { /* Opera seems to have a nice bug with global replacements */
			content = content.replace(/\n|\r|\r\n/g, '\n');
		} else {
			content = content.replace(/\n|\r|\r\n/, '\n');
		}
		content = content.replace(/^\n*/, ''); /* trim empty lines at start */
		content = content.replace(/\n*$/, ''); /* trim empty lines at the end */

		var lines = content.split('\n');

		var ol = document.createElement('ol');
		ol.className = 'code';
		
		for (var j = 0; j < lines.length; j++) {
			var line = lines[j];
			line = line.replace(/\t/g, '    '); // replace tab with four spaces
			
			var cname = 'tab' + (Math.floor(countSpaces(line) / 4) - 1); // className for this line
			var restSpaces = countSpaces(line) % 4;
			line = line.replace(/^ +/, '');
			if (restSpaces) {
				for (var k = 0; k < restSpaces; k++) {
					line = '\u00A0' + line;
				}
			}
			var parts = new Array();

			if (inMultiLineComment) {
				parts = ['', line];
			} else {
				parts = [line];
			}

			if (PROCCESS_COMMENTS) {
				var slashSlashPos = line.indexOf('//');
				var starSlashPos = line.indexOf('/*');
				var slashStarPos = line.indexOf('*/');
				if (slashSlashPos != -1) {
					parts = line.split('//');
					parts[1] = '//' + parts[1];
				} else if (starSlashPos != -1) {
					if (inMultiLineComment) {
						parts = ['', line];
					} else {
						parts = line.split('/*');
						parts[1] = '/*' + parts[1];
					}
					inMultiLineComment = true;
				}

				
				if (slashStarPos != -1) {
					inMultiLineComment = false;
				}
			}

			var li = document.createElement('li');
			li.className = cname; // tab0, tab1, etc.
			var span = document.createElement('code');
			var code = document.createTextNode(parts[0]); 
			span.appendChild(code);

			
			if (parts[1]) {
				var cmt = document.createElement('span');
				cmt.appendChild(document.createTextNode(parts[1]));
				cmt.className = 'cmt';
				span.appendChild(cmt);
			}


			span.appendChild(document.createTextNode('\u00A0')); /* Unicode non-breaking space fix for Firefox */
			
			li.appendChild(span);
			ol.appendChild(li);
		};

		pre.parentNode.replaceChild(ol, pre);
		i--; // if we replace the pre, now there are n - 1 pre elements in the collection we are traversing
	};

	function countSpaces(s) {
		var spaceCount = 0;
		for (var i = 0; i < s.length; i++) {
			if (' ' == s.substr(i,1)) {
				spaceCount++;
			} else {
				break;
			}
		};
		return spaceCount;
	}

	function getText(node) {
		/* from JavaScript The Definitive Guide */
		var s = '';
		var children = node.childNodes;
		for (var i=0; i < children.length; i++) {
			var child = children[i];
			if (child.nodeType == 3 /* Text node */) {
				s += child.data;
			} else {
				s += getText(child);
			}
		}
		return s;
	}
}



// add the handler to the onload event
var oldOnload = window.onload;
if (typeof oldOnload == 'function') {
	window.onload = function() {
		oldOnload();
		lipt();
	}
} else {
	window.onload = lipt;
}