/*
 * Content-seperated javascript tree widget
 * Copyright (C) 2005 SilverStripe Limited
 * Feel free to use this on your websites, but please leave this message in the fies
 * http://www.silverstripe.com/blog
*/

/*
 * Initialise all trees identified by <ul class="tree">
 */
function autoInit_trees() {
	var candidates = document.getElementsByTagName('ul');
	for(var i=0;i<candidates.length;i++) {
		if(candidates[i].className && candidates[i].className.indexOf('tree') != -1) {
			initTree(candidates[i]);
			candidates[i].className = candidates[i].className.replace(/ ?unformatted ?/, ' ');
		}
	}
	
//	document.write(document.cookie);
}
 
/*
 * Initialise a tree node, converting all its LIs appropriately
 */
function initTree(el) {
	var i,j;
	var spanA, spanB, spanC;
	var startingPoint, stoppingPoint, childUL;
	
	// Find all LIs to process
	for(i=0;i<el.childNodes.length;i++) {
		if(el.childNodes[i].tagName && el.childNodes[i].tagName.toLowerCase() == 'li') {
			var li = el.childNodes[i];

			// Create our extra spans
			spanA = document.createElement('span');
			spanB = document.createElement('span');
			spanC = document.createElement('span');
			spanA.appendChild(spanB);
			spanB.appendChild(spanC);
			spanA.className = 'a ' + li.className.replace('closed','spanClosed');
			spanA.onMouseOver = function() {}
			spanB.className = 'b';
			spanB.onclick = treeToggle;
			spanC.className = 'c';
			
			
			// Find the UL within the LI, if it exists
			stoppingPoint = li.childNodes.length;
			startingPoint = 0;
			childUL = null;
			for(j=0;j<li.childNodes.length;j++) {
				if(li.childNodes[j].tagName && li.childNodes[j].tagName.toLowerCase() == 'div') {
					startingPoint = j + 1;
					continue;
				}

				if(li.childNodes[j].tagName && li.childNodes[j].tagName.toLowerCase() == 'ul') {
					childUL = li.childNodes[j];
					stoppingPoint = j;
					break;					
				}
			}
				
			// Move all the nodes up until that point into spanC
			for(j=startingPoint;j<stoppingPoint;j++) {
				spanC.appendChild(li.childNodes[startingPoint]);
			}
			
			// Insert the outermost extra span into the tree
			if(li.childNodes.length > startingPoint) li.insertBefore(spanA, li.childNodes[startingPoint]);
			else li.appendChild(spanA);
			
			// Process the children
			if(childUL != null) {
				if(initTree(childUL)) {
					addClass(li, 'children', 'closed');
					addClass(spanA, 'children', 'spanClosed');
				}
			}
		}
	}
	
	if(li) {
		// li and spanA will still be set to the last item

		addClass(li, 'last', 'closed');
		addClass(spanA, 'last', 'spanClosed');
		return true;
	} else {
		return false;
	}
		
}
 
function RebuildStateCookie(el)
{
	var treeName = "tree";
	var cs = "";
	//Goto up to ul with tree class
	while(el != null && (!el.tagName || !((el.tagName.toLowerCase() == "ul") && (el.className.indexOf("tree") != -1)))) el = el.parentNode;
	try
	{
		treeName = el.attributes["name"].nodeValue;
	}
	catch(e)
	{
	}
	
	log("Tree name:"+treeName);
	
	for(var x=0;x<el.childNodes.length;x++) {
	if(el.childNodes[x].tagName && el.childNodes[x].tagName.toLowerCase() == "li") {
		cs += AppendToCookie(el.childNodes[x],treeName,0);
		}
	}	
	setCookie(treeName, cs);
} 

function AppendToCookie(li,treeName,depth)
{
	var childSet = findChildWithTag(li, "ul");
	var nodeId = "";
	var nodeCnt = 0;
	var cs = "";
	var startpos = 0;
	var endpos = 0;
	
	if (depth > 20)
		return "";
	
	try
	{
		endpos = li.outerHTML.indexOf(">");
		startpos = li.outerHTML.indexOf("value=");
		log("start:" + startpos,depth);
		log("end:" + endpos,depth);
		
		if ((endpos > 0) && (startpos > 0) && (endpos > startpos))
		{
			nodeId = li.outerHTML.substring(startpos+6, endpos);
		}
		
	}
	catch(e)
	{
		try
		{
			nodeId = li.attributes["value"].nodeValue;
		}
		catch(e2)
		{
		}
	}

	log("AppendToCookie:" + nodeId,depth);
	//log("nodehtml:" + li.outerHTML,depth);
	
	if (nodeId != "")
	{
	
		if(!li.className.match(/(^| )closed($| )/))
		{
			//setCookie(treeName + nodeId, "open");
			cs += nodeId + "=open,";
		}
		else
		{
			cs += nodeId + "=closed,";
			//setCookie(treeName + nodeId, "closed");
		}
	}

//		window.alert(nodeId);
//		return cs;
	if (childSet) 
	{
		for(var i=0;i<childSet.childNodes.length;i++) 
		{
			if (nodeCnt > 500)
				return nodeCnt;

			nodeCnt++;
		log("nodecnt:"+nodeCnt,depth);

			if(childSet.childNodes[i].tagName && childSet.childNodes[i].tagName.toLowerCase() == "li") 
			{
		log("going in :"+nodeId+" "+i,depth);
				//if (nodeId != "3")
				cs+=AppendToCookie(childSet.childNodes[i],treeName,depth+1);
		log("back on :"+nodeId+" "+i,depth);
			}
		}
	}
	return cs;
}
function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function setCookie(name, value, days) {
	days = 365;
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

/*
 * +/- toggle the tree, where el is the <span class="b"> node
 * force, will force it to "open" or "close"
 */
function treeToggle(el, force) {
	el = this;
	
	while(el != null && (!el.tagName || el.tagName.toLowerCase() != "li")) el = el.parentNode;
	
	// Get UL within the LI
	var childSet = findChildWithTag(el, 'ul');
	var topSpan = findChildWithTag(el, 'span');

	if( force != null ){
		
		if( force == "open"){
			treeOpen( topSpan, el )
		}
		else if( force == "close" ){
			treeClose( topSpan, el )
		}
		
	}
	
	else if( childSet != null) {
		// Is open, close it
		if(!el.className.match(/(^| )closed($| )/)) {		
			treeClose( topSpan, el )
		// Is closed, open it
		} else {			
			treeOpen( topSpan, el )
		}
	}
	log("tree click",0);
	//window.alert(readCookie("user"));
	
	if (readCookie("user") != null)
		setCookie("user",readCookie("user"));
	//RebuildStateCookie(el);
}


function treeOpen( a, b ){
	removeClass(a,'spanClosed');
	removeClass(b,'closed');
}
	
	
function treeClose( a, b ){
	addClass(a,'spanClosed');
	addClass(b,'closed');
}

/*
 * Find the a child of el of type tag
 */
function findChildWithTag(el, tag) {
	for(var i=0;i<el.childNodes.length;i++) {
		if(el.childNodes[i].tagName != null && el.childNodes[i].tagName.toLowerCase() == tag) return el.childNodes[i];
	}
	return null;
}

/*
 * Functions to add and remove class names
 * Mac IE hates unnecessary spaces
 */
function addClass(el, cls, forceBefore) {
	if(forceBefore != null && el.className.match(new RegExp('(^| )' + forceBefore))) {
		el.className = el.className.replace(new RegExp("( |^)" + forceBefore), '$1' + cls + ' ' + forceBefore);

	} else if(!el.className.match(new RegExp('(^| )' + cls + '($| )'))) {
		el.className += ' ' + cls;
		el.className = el.className.replace(/(^ +)|( +$)/g, '');
	}
}
function removeClass(el, cls) {
	var old = el.className;
	var newCls = ' ' + el.className + ' ';
	newCls = newCls.replace(new RegExp(' (' + cls + ' +)+','g'), ' ');
	el.className = newCls.replace(/(^ +)|( +$)/g, '');
} 

/*
 * Handlers for automated loading
 */ 
 _LOADERS = Array();

function callAllLoaders() {
	var i, loaderFunc;
	for(i=0;i<_LOADERS.length;i++) {
		loaderFunc = _LOADERS[i];
		if(loaderFunc != callAllLoaders) loaderFunc();
	}
}

function appendLoader(loaderFunc) {
	if(window.onload && window.onload != callAllLoaders)
		_LOADERS[_LOADERS.length] = window.onload;

	window.onload = callAllLoaders;

	_LOADERS[_LOADERS.length] = loaderFunc;
}



function log(msg,depth) {
 return;
 try {
     var filename = 'c:\\test.txt';
     var fso = new ActiveXObject('Scripting.FileSystemObject');
     if (fso.FileExists(filename)) {
          var a, ForAppending, file;
          ForAppending = 8;
          file = fso.OpenTextFile(filename, ForAppending, false);
			if (depth > 0)
			{
				for (var x = 0; x < depth; x++)
					file.Write('\t');
			}
          file.WriteLine(msg);
          }
     else {
          var file = fso.CreateTextFile(filename, true);
          file.WriteLine(msg);
          }
     file.Close();
    }
catch(err){
  var strErr = 'Error:' + err.toString();
  strErr += '\nNumber:' + err.number;
  strErr += '\nDescription:' + err.description;
  document.write(strErr);
 }
}

appendLoader(autoInit_trees);
