/*

Funtionen zum Ansteuern des Baums:
	createRoot();
	drawRoot();
	addNode(id,content,parent);
	copyNode(from, to);
	deleteNodeFrom(id,from);
	deleteNode(id);
	moveNode(id,from,to);
	updateNode(id,newcontent);
	openPath(id);
Debug Funktion:
	debugNode(id);
*/
// IE oder MOZ?
var IE=false;
if(document.all) IE=true;

// Id für HTML-Nodes...
var elemId=1;
// Array für alle Nodes...
var KKNodes=new Array();
// Array für alle HTML-Elemente (welchen Node sie beherbergen...)
var KKElems=new Array();

// #########################################
// ## Interface-Funktionen die die Klasse ansteuern ##
// #########################################
function createRoot()
{
	
	KKNodes[0] = new dbNode();
	KKNodes[0].TNinit(0,"");
	KKNodes[0].elemAry.push("0");
	KKNodes[0].drawn=true;
}

function addNode(id,TNcontent,parent,openPathToNode)
{
	if(KKNodes[id]!=null)
	{
		//alert("Node "+id+" schon angelegt! Use KKNodes["+id+"].copyTo("+parent+"); instead!");
		KKNodes[id].copyTo(parent);
		return;
	}
	KKNodes[id] = new dbNode();
	KKNodes[id].TNinit(id,TNcontent);
	KKNodes[id].addTo(parent);
	if(KKNodes[parent].drawn==true)
	{
		var Telem = "";
		for(var a in KKNodes[parent].elemAry)
		{
			Telem = KKNodes[parent].elemAry[a];
			if(KKNodes[parent].drawnChilds[Telem]==true)
			{
				KKNodes[id].draw(Telem);
			}
			if(KKNodes[parent].childAry.length==1 && parent != "0")
			{
				//alert(elem);
				document.getElementById(Telem).parentNode.firstChild.src="_img/eztreenodeclosed.gif"; //.innerHTML="4 ";
			}
		}
	}
// 	alert(openPathToNode);
	if(openPathToNode!=undefined)
	{
		openPath(id);
	}
}

function copyNode(from, to)
{
	KKNodes[from].copyTo(to);
}

function deleteNodeFrom(id,from)
{
	KKNodes[id].removeFrom(from);
}

function updateNode(id,newcontent)
{
	KKNodes[id].updateContent(newcontent);
}

function moveNode(id,from,to)
{
	copyNode(from, to);
	deleteNodeFrom(id,from);
}

function drawRoot()
{
	KKNodes[0].drawChilds(0);
}

function debugNode(id)
{
	var i = 0;
	var j = 0;
	var currNode=KKNodes[id];
	var text = "id =>"+currNode.id+"\n";
	text += "parentAry =>Array\n";
	for(i in currNode.parentAry)
		text += "      "+i+"=>"+currNode.parentAry[i].id+"\n";
	text += "childAry =>Array\n";
	for(i in currNode.childAry)
		text += "      "+i+"=>"+currNode.childAry[i].id+"\n";
	text += "elemAry =>Array\n";
	for(i in currNode.elemAry)
		text += "      "+i+"=>"+currNode.elemAry[i]+"\n";
	text += "childElemAry =>Array\n";
	for(i in currNode.childElemAry)
	{
		text += "      "+i+"=>Array\n";
		for(j in currNode.childElemAry[i])
		{
			text+="            "+j+"=>"+currNode.childElemAry[i][j]+"\n";
		}
	}
	text += "drawn =>"+currNode.drawn+"\n";
	text += "drawnChilds =>Array\n";
	for(i in currNode.drawnChilds)
		text += "      "+i+"=>"+currNode.drawnChilds[i]+"\n";
	text += "content =>"+currNode.content+"\n";
	alert(text);
}

function updateNode(id,newcontent)
{
	KKNodes[id].updateContent(newcontent);
}

function deleteNode(id)
{
	var parents = KKNodes[id].parentAry;
	for(var i in parents)
	{
		KKNodes[id].removeFrom(parents[i].id);
	}
}

function getPath(id)
{
	var path=new Array();

	for(var i in id)
	{
		if(KKNodes[id[i]]!=undefined)
		{
			path.push(id[i]);
			var pids=new Array();
			for(var j in KKNodes[id[i]].parentAry)
			{
				pids.push(KKNodes[id[i]].parentAry[j].id);
			}
			path=path.concat(getPath(pids));
		}
	}
	return path;
}

function openPathNode(elemAry,id,pathAry)
{
	for(var i in elemAry)
	{
		toggle(id,elemAry[i],true);
	}
	for(var j in KKNodes[id].childAry)
	{
		if(in_ary(KKNodes[id].childAry[j].id,pathAry))
			openPathNode(KKNodes[id].childAry[j].elemAry,KKNodes[id].childAry[j].id,pathAry);
	}
}

function openPath(id)
{
	var elems = false;
	var val = new Array();
	val.push(id);
	var pathAry = getPath(val);
	pathAry.shift();
	openPathNode(new Array(0),0,pathAry);

	return;
}

// ########################################
// ######## Helfer-Funktionen #############
// ########################################

// Show/Hide-Funktion...
function toggle(nodeId,elem,force)
{
	if(KKNodes[nodeId].childAry.length<1)
		return;
	if(KKNodes[nodeId].drawnChilds[elem]==false)
		KKNodes[nodeId].drawChilds(elem);
	var elem = document.getElementById(elem);
	if(elem.style.display=="" && force==undefined)
	{
		elem.style.display="none";
		//elem.parentNode.firstChild.innerHTML="4 ";
		elem.parentNode.firstChild.src="_img/eztreenodeclosed.gif";
	}
	else
	{
		elem.style.display="";
		//elem.parentNode.firstChild.innerHTML="6 ";
		elem.parentNode.firstChild.src="_img/eztreenodeopen.gif";
	}
}
function setNoChilds(id)
{

}

// Array-Funktionen
function aryKillByKey(ary,key)
{
	var temp = new Array();
	for(var i in ary)
	{
		if(i!=key)
		{
			temp[i]=ary[i];
		}
	}
	return temp;
}
function aryKillByValue(ary,val)
{
	var temp = new Array();
	for(var i in ary)
	{
		if(ary[i]!=val)
		{
			temp[i]=ary[i];
		}
	}
	return temp;
}
function ary_unique(ary)
{
	var fail=false;
	var temp=new Array();
	for(var i in ary)
	{
		for(var j in temp)
		{
			if(ary[i]==temp[j])
			{
				fail=true;
				continue;
			}
		}
		if(fail==false)
			temp.push(ary[i]);
	}
	return temp;
}

function in_ary(needle,haystack)
{
	for(var i in haystack)
	{
		if(needle==haystack[i]) return true;
	}
	return false;
}
// #######################################
// ############# Hauptklasse #############
// #######################################
function dbNode()
{
	this.parentAry = new Array();
	this.childAry = new Array();
	this.elemAry = new Array();
	this.childElemAry = new Array();
	this.drawn = false;
	this.drawnChilds = new Array();

	this.TNinit = TNinit;
	this.addTo = addTo;
	this.addChild = addChild;
	this.addParent = addParent;
	this.draw = draw;
	this.drawChilds = drawChilds;
	this.copyTo = copyTo;
	this.removeFrom = removeFrom;
	this.killBranch = killBranch;
	this.updateContent = updateContent;
}

function TNinit(id,content)
{
	this.id = id;
	this.content = content;
}

function addTo(parent)
{
	if(KKNodes[parent].childAry.length==0 && KKNodes[parent].drawn && parent!=0)
	{
		for(var i in KKNodes[parent].elemAry)
		{
			var e=KKNodes[parent].elemAry[i];
			if(KKNodes[parent].drawnChilds[e]==false)
				document.getElementById(e).parentNode.firstChild.src="_img/eztreenodeclosed.gif"; //.innerHTML="4 ";
		}
	}
	KKNodes[parent].addChild(this);
	this.addParent(KKNodes[parent]);
}

function addChild(obj)
{
	this.childAry.push(obj);
}

function addParent(obj)
{
	this.parentAry.push(obj);
}

function draw(parentElemId)
{
	var pElem = document.getElementById(parentElemId);
	if(parentElemId==0)
		var parentNodeId = 0;
	else
	{
		if(IE)
			var parentNodeId = pElem.parentNode.KKNode;
		else
			var parentNodeId = pElem.parentNode.getAttribute("KKNode");
	}

	var newElem = document.createElement("div");
	newElem.setAttribute("id","elem"+elemId);
	newElem.className="KKlastnode";
	if(this.childAry.length>0)
		var arrow = "eztreenodeclosed.gif";//"4";
	else
		var arrow = "eztreenode.gif";//";";
	if(IE)
	{
		newElem.KKNode=this.id;
		//newElem.innerHTML="<span class=\"arr\" onClick=\"toggle('"+this.id+"','"+elemId+"');\">"+arrow+" </span>"; //OLD:KKNodes["+this.id+"].drawChilds('"+elemId+"');
		newElem.innerHTML="<img onMouseOver=\"toggle('"+this.id+"','"+elemId+"');\" src=\"_img/"+arrow+"\" class=\"KKarr\">";
	}
	else
	{
		newElem.setAttribute("KKNode",this.id);
// 		var clicker = document.createElement("span");
// 		clicker.setAttribute("onClick","toggle('"+this.id+"','"+elemId+"');");
// 		clicker.className="ar";
// 		clicker.onClick="KKNodes["+this.id+"].drawChilds('"+elemId+"');";
// 		clicker.innerHTML=arrow+" ";
		var clicker = document.createElement("img");
		clicker.setAttribute("onMouseOver","toggle('"+this.id+"','"+elemId+"');");
		clicker.src="_img/"+arrow;
		clicker.className="KKarr";
		newElem.appendChild(clicker);
	}

//		var content = document.createTextNode(this.content);
//		newElem.appendChild(content);
	newElem.innerHTML+=this.content;

	var newDiv = document.createElement("div");
	newDiv.setAttribute("id",elemId);
	//newDiv.setAttribute("class","treediv");
	newDiv.className="KKtreediv";
	newDiv.style.display="none";
	newElem.appendChild(newDiv);
	
	pElem.appendChild(newElem);

	this.drawn=true;
	this.drawnChilds[elemId]=false;
	this.elemAry.push(elemId);
	KKElems[elemId]=this.id;
	//alert("KKNodes["+parentNodeId+"].childElemAry["+parentElemId+"]["+this.id+"]="+elemId+";");
	if(KKNodes[parentNodeId].childElemAry[parentElemId]==undefined)
		KKNodes[parentNodeId].childElemAry[parentElemId]=new Array();
	KKNodes[parentNodeId].childElemAry[parentElemId][this.id]=elemId;

	// prevSibling auf className "node" schalten!
	var thisElem = document.getElementById("elem"+elemId);
	if(thisElem.previousSibling!=null)
		thisElem.previousSibling.className="KKnode";
	elemId++;
}

function drawChilds(elem)
{
	if(this.drawn==false)
	{
		alert('Node '+this.id+' noch nicht gezeichnet!');
		return false;
	}
	if(this.drawnChilds[elem]==true)
	{
		alert('Childs von Node '+this.id+'/ Element '+elem+' sind schon gezeichnet!');
		return false;
	}
	for(var j in this.childAry)
	{
		this.childAry[j].draw(elem);
		this.drawnChilds[elem]=true;
	}
}

function copyTo(parent,draw)
{
	// Testen ob das Child bei diesem Parent schon vorhanden ist...
	for(var test in KKNodes[parent].childAry)
	{
		if(KKNodes[parent].childAry[test]==this)
			return;
	}
	KKNodes[parent].addChild(this);
	this.addParent(KKNodes[parent]);
	if(KKNodes[parent].drawn)
	{
		for(var i in KKNodes[parent].elemAry)
		{
			// Wenn die Childs schon gezeichnet sind, den Node gleich anhängen...
			if(KKNodes[parent].drawnChilds[KKNodes[parent].elemAry[i]])
			{
				this.draw(KKNodes[parent].elemAry[i]);
			}
			// Wenn der Node das einzige Child ist, den Ordner auf "ungeöffnet" stellen...
			if(KKNodes[parent].childAry.length==1)
			{
				var pDiv = document.getElementById(KKNodes[parent].elemAry[i]);
				//pDiv.parentNode.firstChild.innerHTML="4 ";
				pDiv.parentNode.firstChild.src="_img/eztreenodeclosed.gif";
			}
		}
	}
}

function removeFrom(parentid)
{
	// ElemAry des Parent holen...
	var temp = KKNodes[parentid].childElemAry;
	// alle Vorkommen des eigenen Nodes herausfiltern...
	for(var temp_elemId in temp)
	{
		for(var temp_KKNodeId in temp[temp_elemId])
		{
			if(temp_KKNodeId==this.id)
			{
				// Die Rekursion für dieses Element starten... killBranch(elemid);
				var kElemId = temp[temp_elemId][temp_KKNodeId];
				KKNodes[temp_KKNodeId].killBranch(kElemId);
				// wenn dieser Node ein "lastChild" ist und ein "previousSibling" hat den vorhergehenden auf className "lastnode" setzen
				var thisDiv = document.getElementById("elem"+kElemId);
				if(thisDiv.className=="KKlastnode" && thisDiv.previousSibling!=null)
				{
					thisDiv.previousSibling.className="KKlastnode";
				}
				// Den HTML-Node löschen
				var parentDiv = thisDiv.parentNode;
				parentDiv.removeChild(thisDiv);
			}
		}
		// Aus dem childElemAry des ParentNodes den eigenen Eintrag löschen...
		KKNodes[parentid].childElemAry[temp_elemId]=aryKillByKey(KKNodes[parentid].childElemAry[temp_elemId],this.id);
	}
	// Die parentAry- und childAry-Informationen updaten...
	KKNodes[parentid].childAry=aryKillByValue(KKNodes[parentid].childAry,this);
	this.parentAry=aryKillByValue(this.parentAry,KKNodes[parentid]);
	// Wenn der parentNode keine weiteren Childs hat, den DIV verstecken und das Klicksymbol updaten...
	if(KKNodes[parentid].childAry.length<1)
	{
		for(var i in KKNodes[parentid].elemAry)
		{
			var div = document.getElementById(KKNodes[parentid].elemAry[i]);
// 			div.parentNode.firstChild.innerHTML="; ";
			div.parentNode.firstChild.src="_img/eztreenode.gif";
			div.style.display="none";
		}
	}
}

function killBranch(kElemId)
{
	var kChildElemAry = this.childElemAry[kElemId];
	if(kChildElemAry != undefined) // Hat gezeichnete Kinder!
	{
		for(var i in kChildElemAry)
		{
			KKNodes[i].killBranch(kChildElemAry[i]);
		}
	}
	this.elemAry=aryKillByValue(this.elemAry,kElemId);
	this.drawnChilds=aryKillByKey(this.drawnChilds,kElemId);
	this.childElemAry=aryKillByKey(this.childElemAry,kElemId);
	document.getElementById("elem"+kElemId).style.color="#"+Math.floor(Math.random()*55+44)+Math.floor(Math.random()*55+44)+Math.floor(Math.random()*55+44);
}

function updateContent(newContent)
{
	var elem = false;
	for(var i in this.elemAry)
	{
		elem = document.getElementById(this.elemAry[i]).previousSibling;
		elem.innerHTML = newContent;
	}
	this.content = newContent;
}
