var CSSRules = "#domNodeList {background: ivory; border: 1px solid silver; } #bigul {padding-left: 2px; } #bigul li { list-style-type: none; line-height: 14px; } span.plus { cursor: pointer; font-weight: bold; color: red; } li code { white-space: pre; }  #bigul li ul { display: none; }";

addEvent(window, "load", analyseAll);

/**
  Initialer Event Handler, ruft goInto auf, sobald das Dokument im Fenster 
  geladen ist
*/

function analyseAll()
{
	goInto(document, -1);
	return false;
}


/**
  tree      globales Array, in dem alle Knoten des Dokuments gespeichert werden
  Node      globales Objekt, in dem die Daten über einen Knoten gespeichert werden
  
  goInto    rekursive Funktion, in der alle Knoten des Dokuments erfasst und in 
            das Array tree gesetzt werden
  
*/
var tree = new Array; 

function Node(level, name, value, obj)
{
	this.level = level;
	this.name = name; 
	this.value = value;
	this.obj = obj;
}

function goInto(obj, level)
{
	if (obj.hasChildNodes) {
		level++;
		var tags = obj.childNodes;
		for (var i=0; i<tags.length; i++) {
			var value = "";
			var name = tags[i].nodeName;
			if (tags[i].nodeValue) {
				if (tags[i].nodeValue.match(/\S/)) {
					value = tags[i].nodeValue;
					if (tags[i].nodeName != "#comment") {
						name = "";
					}
				} 
			}
			var elem = new Node(level, name, value);
			tree.push(elem);
			if (tags[i].hasChildNodes) {
				goInto(tags[i], level);
			}
		}
	}
}


/**
  Aktiviert die Buttons Zeige Baum und Verberge Baum, sobald das Dokument 
  im Fenster geladen wurde
  
  showTree()     wandelt das Array tree in eine strukturierte Liste um
  hideTree()     versteckt die Knotenliste durch einen CSS-Stil
  
*/

addEvent(window, "load", activate);

function activate()
{
	if (!document.getElementsByTagName) {
		return false;
	}

	// CSS-Regeln für die Knotenliste setzen 
	// gestrichen, da das Einfügen eines style-Elements in IE 6 nicht
	// gelingt.
	/** var head = document.getElementsByTagName('head')[0];
	var style = document.createElement('style');
	var styleValue = document.createTextNode(CSSRules);
	style.appendChild(styleValue);
	head.appendChild(style);
	*/

	if (!document.getElementById('hideAnalysis')) {
		return false;
	}
	var hideAnalysis = document.getElementById('hideAnalysis'); 
	hideAnalysis.onclick = function() {
		hideTree();
		return false;
	}

	if (!document.getElementById('listTree')) {
		return false;
	}
	var listTree = document.getElementById('listTree'); 
	listTree.onclick = function() {
		if (document.getElementById('bigul')) {
			var rem = document.getElementById('bigul');
			rem.style.display = "block";
			return false;
		}
		showTree();
		return false;
	}
}

function showTree()
{
	var deep = 0;
	var bigUl = document.createElement('div');
	bigUl.setAttribute('id', 'bigul');

	// Den tiefsten Level feststellen
	for (var i=0; i<tree.length; i++) {
		if (tree[i].level > deep) {
			deep = tree[i].level; 
		}
	}
	
	// Level in Listenelemente komprimieren
	for (j=deep; j>0; j--) {
		for (var i=0; i<tree.length; i++) {
			if (tree[i].level == j) {
				var prev = (i-1);
				var ul = document.createElement('ul');
				while (i<tree.length && tree[i].level == j) {
					var li = document.createElement('li');

					var plus = document.createTextNode (' + ');
					var span = document.createElement('span');
					span.setAttribute('class', 'plus');
					span.setAttribute('className', 'plus');
					span.appendChild(plus);
					li.appendChild(span);
					
					var elem = document.createTextNode(tree[i].name);
					li.appendChild(elem);
					
					if (tree[i].obj) {
						li.appendChild(tree[i].obj);
					}
					if (tree[i].value) {
						var code = document.createElement('code');
						var val = document.createTextNode(" " + tree[i].value);
						code.appendChild(val);
						li.appendChild(code);
					}
					ul.appendChild(li);
					tree.splice(i,1);
				}
				if (prev >= 0) {
					tree[prev].obj = ul;
				}
			}
		}
	}

	for (k=0; k<tree.length; k++) {
		if (tree[k].obj) {
			bigUl.appendChild(tree[k].obj);
			objText = tree[k].obj.innerHTML
		} else {
			objText = " nop ";
		}
	}
	var content = document.getElementById('domNodeList');
	content.appendChild(bigUl);
	
	// entfernt alle Pluszeichen von leeren Knoten und
	// registriert die Pluszeichen beim Event Listener
	var pluss = document.getElementsByTagName('span'); 
	for (var i=0; i<pluss.length; i++) {
      if (/plus/.test(pluss[i].className)) {
      	
      	if (findFirst(pluss[i].parentNode,"UL")) {
         	pluss[i].onclick = showHideLeafs;
         } else {
         	pluss[i].style.color = "white";
         	pluss[i].firstChild.nodeValue = " | |";
         }
      }
   }
}

function hideTree()
{
	if (document.getElementById('bigul')) {
		var rem = document.getElementById('bigul');
		rem.style.display = "none";
	}
}

function findFirst(obj, tag) 
{
	if (obj.hasChildNodes) {
		
		var tags = obj.childNodes;
		for (var i=0; i<tags.length; i++) {
			if (tags[i].nodeName == tag) {
				return tags[i];
			}
		}
	}
	return false;
}


function showHideLeafs(evt)
{
	evt = (evt) ? evt : ((window.event) ? window.event : "");
	var elem = (evt.target) ? evt.target : evt.srcElement;
	// gegen einen Bug in Safari 1.3, in dem das Ereignis dem Inhalt  
	// und nicht dem Knoten des Elements zugeordnet wurde
	if (elem.nodeName === "#text") {
		elem = elem.parentNode;
	}
	var firstUl = findFirst(elem.parentNode, "UL");
	if (firstUl) {
		if (firstUl.style.display == "block") {
				
			elem.firstChild.nodeValue = " + ";
			firstUl.style.display = "none";
		} else {
			
			elem.firstChild.nodeValue = " - ";
			firstUl.style.display = "block";
		}
	}
}