//#####################################
//#|||||||| Global Variables |||||||||#
//#####################################


var treestr = new String();
var detailstr = new String();
var grove = new Array();
var currC = -1;
var iconlib = new Array();
var funclib = new Array();
var func_dir = new Array();
var func_file = new Array();
var loading = -1;
var mbgcolor = "white";
var sbgcolor = "#74a5fd";
var nwrap = new String();
var nwrap_ = new String();
var currsort = new String();
var mask = new Array();
var treebody_ = new String();
var listbody_ = new String();

//#############################################
//#|||||||| Initialization Functions |||||||||#
//#############################################


function process()
{
	grove = parse(window.frames["loadFrame"].document.forms[0].elements[0].value);
	treestr = "";
	for(var i = 0; i < grove.contents.length; i++)
	{
		if(grove.contents[i].name == "typelib")
		{
			processtypes(grove.contents[i]);
		}
		else
		{
			treestr += dotree(grove.contents[i],0);
		}
	}
	window.setTimeout("updatetree();updatedetail();",0);
}

function load()
{
	var newgrove = parse(window.frames["loadFrame"].document.forms[0].elements[0].value);
	Cindex[loading].name = newgrove.contents[0].name;
	Cindex[loading].attributes = newgrove.contents[0].attributes;
	Cindex[loading].contents = newgrove.contents[0].contents;
	dodetail(loading,true);
	loading = -1;
}

function processtypes(types)
{
	for(var i = 0;i < types.contents.length; i++)
	{
		if(types.contents[i].attributes["icon"])
		{
			iconlib[types.contents[i].name] = types.contents[i].attributes["icon"];
		}
		if(types.contents[i].contents.length > 0)
		{
			funclib[types.contents[i].name] =types.contents[i].contents[0].attributes;
		}
	}
}


//####################################################
//#|||||||| Core Display Building Functions |||||||||#
//####################################################


function updatetree()
{
	window.frames["treeFrame"].document.open("text/html");
	window.frames["treeFrame"].document.write(
  '<BODY BGCOLOR="' + mbgcolor + '" ' + treebody_ + ' >'
+ '<TABLE BORDER="0" WIDTH="100%">' + treestr
+ '</TABLE></FONT></BODY>');
	window.frames["treeFrame"].document.close();
}

function updatedetail()
{
	window.frames["detailFrame"].document.open("text/html");
	window.frames["detailFrame"].document.write('<BODY BGCOLOR="' + mbgcolor + '" ' + listbody_ + ' >' + detailstr + '</BODY>');
	window.frames["detailFrame"].document.close();
}

function reprocess()
{
	treestr = "";
	for(var i = 0; i < grove.contents.length; i++)
	{
		if(grove.contents[i].name == "c")
			treestr += dotree(grove.contents[i],0);
	}
	window.setTimeout("updatetree();",0);
}

function dotree(c,indent)
{
	var result = new String();
	var icon = geticon(c);
	var iconH = 22;
	var iconW = 20;
	var bgcolor = mbgcolor;
	var tab = new String();
	var name = c.attributes["name"];
	var children = new String();
	for(var i = 0; i < indent; i++)
	{
		tab += "&nbsp;&nbsp;&nbsp;&nbsp;";
	}
	if(c.show && icon == "folder.gif")
	{
		icon = "folder_open.gif";
		iconW = 27;
	}
	if(currC == c.uid)
	{
		bgcolor = sbgcolor;
		name = '<B>' + name + '</B>';
	}
	for(var i = 0; i < c.contents.length && c.show; i++)
	{
		if(c.contents[i].name == "c")
		{
			children += dotree(c.contents[i],indent + 1);
		}
	}
	icon = printicon(icon,iconH,iconW);
	result +=
  '<TR><TD BGCOLOR="' + bgcolor + '">' + tab
+ '<A HREF="javascript:parent.dodetail(' + c.uid + ');">' + icon
+ nwrap + name + nwrap_ + '</A></TD></TR>' + children;
	return result;
}

function detail()
{
	var result = new String();
	var tag = Cindex[currC];
	var bgcolor = mbgcolor;
	var attr = getattr(tag.contents,"a");
	var eattr = new Array();
	mask = new Array();
	mask["type"] = attr[currsort];
	if(tag.currE == -1)
	{
		var attrs = new String();
		for(key in attr)
		{
			attrs += '<TH><A HREF="javascript:parent.resort(\'' + key + '\');">' + nwrap + key + nwrap_ + '</A></TH>';
		}
		if(countelements(tag) > 0)
		{
			result =
  '<TABLE BORDER="0" CELLSPACING="1" WIDTH="100%">'
+ '<TR BGCOLOR="' + sbgcolor + '"><TH>' + nwrap
+ '<A HREF="javascript:parent.resort(\'\');">Name</A>'
+ nwrap_ + '</TH>' + attrs + '</TR>' 
+ printelements(tag,attr) + '</TABLE><HR>';
		}
		else
		{
			result = "<CENTER><H2><TT>Empty</TT></H2></CENTER>";
		}
		// result += printfunctions(getfunctions(tag));
	}
	else
	{
		result =
  '<TABLE BORDER="0" CELLSPACING="1" WIDTH="100%">'
+ '<TR><TD></TD><TD BGCOLOR="' + sbgcolor + '" WIDTH="100%" ROWSPAN="' 
+ (tag.contents.length + 1) + '"><DIR>' 
// + printfunctions(getfunctions(tag.contents[tag.currE]))
+ '</DIR></TD></TR>' + printelements(tag) + '</TABLE>';
	}
	detailstr = result;
	window.setTimeout("updatedetail();",0);
}


//#######################################################
//#|||||||| Display Building Utility Functions |||||||||#
//#######################################################


function getfunctions(e)
{
	var result = new String();
	var funcs = new Array();
	funcs = getattr(e.contents,"f");
	if(haslen(funcs))
		return funcs;
	if(e.attributes["name"].indexOf(".") != -1)
	{
		var A = e.attributes["name"].split(".");
		if(haslen(funclib[A[A.length - 1]]))
			return funclib[A[A.length - 1]];
	}
	if(e.attributes["type"])
	{
		if(haslen(funclib[e.attributes["type"]]))
			return funclib[e.attributes["type"]];
		if(e.attributes["type"] == "null")
			return new Array();
	}
	if(e.name == "c")
		return func_dir;
	if(e.name == "e")
		return func_file;
}

function printfunctions(array)
{
	var result = new String();
	result += "<FORM>&nbsp;<BR>";
	for(func in array)
	{
		result += 
  '<INPUT TYPE="button" VALUE="' + func
+ '" onClick="top.frames[\'headerFrame\'].' + array[func] + ';"><BR>';
	}
	result += "</FORM>";
	return result;
}

function geticon(e)
{
	if(e.attributes["icon"])
		return e.attributes["icon"];
	if(e.attributes["name"].indexOf(".") != -1)
	{
		var A = e.attributes["name"].split(".");
		if(iconlib[A[A.length - 1]])
			return iconlib[A[A.length - 1]];
	}
	if(e.attributes["type"])
	{
		if(iconlib[e.attributes["type"]])
			return iconlib[e.attributes["type"]];
	}
	if(e.name == "c")
		return "folder.gif";
	if(e.name == "e")
		return "generic.gif";
}

function printicon(name,height,width)
{
	var result = new String();
	result = 
  '<IMG SRC="' + name + '" BORDER="0" '
+ 'ALIGN="absmiddle" HSPACE="2" VSPACE="0" HEIGHT="' + height
+ '" WIDTH="' + width + '">';
	return result;
}

function countelements(c)
{
	var count = 0;
	for(var i = 0; i < c.contents.length; i++)
	{
		if(c.contents[i].name != "e")
		{
			continue;
		}
		count++;
	}
	return count;
}

function dosort(a,b)
{
	var compA = a.attributes["name"];
	var compB = b.attributes["name"];
	if(currsort.length > 0)
	{
		var attrA = getattr(a.contents,"a");
		var attrB = getattr(b.contents,"a");
		if(!haslen(attrA) || !haslen(attrB))
			return 0;
		compA = attrA[currsort];
		compB = attrB[currsort];
		if(mask["type"] == "Date")
		{
			compA = Date.parse(compA);
			compB = Date.parse(compB);
		}
		else if(mask["type"] == "Number" || mask["type"] == "Size")
		{
			compA = Number(compA);
			compB = Number(compB);
		}
	}
	if(compA < compB)
		return -1;
	if(compA > compB)
		return 1;
	return 0;
}


function printelements(c,detail)
{
	var result = new String();
	var bgcolor = new String();
	var details = new String();
	var attr = new Array();
	var icon = new String();
	var name = new String();
	var astr = new String();
	var elems = new Array();
	var elemsI = new Array();
	for(var i = 0; i < c.contents.length; i++)
	{
		if(c.contents[i].name == "e")
		{
			elems[elems.length] = c.contents[i];
			elemsI[elemsI.length] = i;
		}
	}
	elems.sort(dosort);
	for(var i = 0; i < elems.length; i++)
	{
		if(elems[i].name != "e")
			continue;
		bgcolor = mbgcolor;
		details = "";
		name = elems[i].attributes["name"];
		icon = printicon(geticon(elems[i]),22,20);
		if(haslen(detail))
		{
			attr = getattr(elems[i].contents,"a");
			for(key in detail)
			{
				if(detail[key] == "Date")
				{
					astr = new Date(attr[key]);
					details += '<TD>' + astr.toLocaleString() + '</TD>';
				}
				else if(detail[key] == "Size")
				{
					astr = attr[key];
					if(astr > 1000)
						astr = Math.round(astr/1000) + "k";
					else
						astr = astr + " bytes";
					details += '<TD>' + astr + '</TD>';
				}
				else
				{
					details += '<TD>' + attr[key] + '</TD>';
				}
			}
		}
		if(c.currE == elemsI[i])
		{
			bgcolor = sbgcolor;
			name = "<B>" + name + "</B>";
		}
		result +=
  '<TR><TD BGCOLOR="' + bgcolor + '" NOWRAP>'
+ '<A HREF="javascript:parent.doelement(' + currC + ',' + elemsI[i]
+ ');">' + icon + nwrap + name + nwrap_ + '</A></TD>' + details + '</TR>';
	}
	return result;
}

function getattr(ary,nam)
{
	for(var i = 0; i < ary.length; i++)
	{
		if(ary[i].name == nam)
		{
			return ary[i].attributes;
		}
	}
	return new Array();
}

function haslen(ary)
{
	var result = false;
	for(key in ary)
	{
		result = true;
	}
	return result;
}

//################################################
//#|||||||| Externally Called Functions |||||||||#
//################################################


function doelement(id,i)
{
	Cindex[id].currE = i;
	detail();
}

function resort(by)
{
	currsort = by;
	detail();
}

function dodetail(id,noload)
{
	currsort = "";
	if(Cindex[id].attributes["load"] && !noload)
	{
		loading = id;
		window.frames["loadFrame"].document.bgColor = "red";
		detailstr = '<H2 ALIGN="center">Please wait, loading...</H2>';
		updatedetail();
		window.frames["loadFrame"].location = Cindex[id].attributes["loadurl"];
		return;
	}
	if(Cindex[id].show)
	{
		Cindex[id].show = true;
	}
	else
	{
		Cindex[id].show = false;
	}
	Cindex[id].show = Cindex[id].show ^ true;
	currC = id;
	reprocess();
	Cindex[id].currE = -1
	if(Cindex[id].attributes["show"])
	{
		window.frames["detailFrame"].location = Cindex[id].attributes["showurl"];
	}
	else
	{
		detail();
	}
}

function doload(url)
{
	loading = currC;
	window.frames["loadFrame"].document.bgColor = "red";
	detailstr = '<H2 ALIGN="center">Please wait, loading...</H2>';
	updatedetail();
	window.frames["loadFrame"].location = url;
	return;
}




















///////////////////////////////////////////////////
///////////////////////////////////////////////////
////                                           ////
////   Highly specialized XML subset parser    ////
//// (based on Xparse: http://www.jeremie.com) ////
////                                           ////
///////////////////////////////////////////////////
///////////////////////////////////////////////////

var Cindex = new Array();
var Eindex = new Array();

function _element(name)
{
	this.type = "element";
	this.name = name;
	this.attributes = new Array();
	this.contents = new Array();
	if(name == "c")
	{
		this.uid = Cindex.length;
		Cindex[this.uid]=this;
	}
	if(name == "e")
	{
		this.uid = Eindex.length;
		Eindex[this.uid]=this;
	}
}

function _frag()
{
	this.str = new String();
	this.ary = new Array();
	this.end = new String();
}

function parse(src)
{
	var frag = new _frag();

	frag.str = _prolog(src);

	var root = new _element("Workspace");

	frag = _compile(frag);

	root.contents = frag.ary;
	return root;
}

function _compile(frag)
{
	// keep circling and eating the str
	while(1)
	{
		// when the str is empty, return the fragment
		if(frag.str.length == 0)
		{
			return frag;
		}

		var TagStart = frag.str.indexOf("<");

		if(TagStart != 0)
		{
			if(TagStart == -1)
			{
				frag.str = "";
			}
			else
			{
				frag.str = frag.str.substring(TagStart,frag.str.length);
			}
		}
		else
		{
			if(frag.str.substring(1,frag.end.length + 3) == "/" + frag.end + ">")
			{
				frag.str = frag.str.substring(frag.end.length + 3,frag.str.length);
				frag.end = "";
				return frag;
			}
			else
			{
				frag = _tag_element(frag);
			}

		}
	}
	return "";
}

function _tag_element(frag)
{
	var close = frag.str.indexOf(">");
	var empty = (frag.str.substring(close - 1,close) == "/");
	if(empty)
	{
		close -= 1;
	}

	var starttag = frag.str.substring(1,close);
	var nextspace = starttag.indexOf(" ");
	var attribs = new String();
	var name = new String();
	if(nextspace != -1)
	{
		name = starttag.substring(0,nextspace);
		attribs = starttag.substring(nextspace + 1,starttag.length);
	}
	else
	{
		name = starttag;
	}

	var thisary = frag.ary.length;
	frag.ary[thisary] = new _element(name);
	if(attribs.length > 0)
	{
		frag.ary[thisary].attributes = _attribution(attribs);
	}
	if(!empty)
	{
		var contents = new _frag();
		contents.str = frag.str.substring(close + 1,frag.str.length);
		contents.end = name;
		contents = _compile(contents);
		frag.ary[thisary].contents = contents.ary;
		frag.str = contents.str;
	}
	else
	{
		frag.str = frag.str.substring(close + 2,frag.str.length);
	}
	return frag;
}

function _attribution(str)
{
	var all = new Array();
	var A = new Array();
	while(1)
	{
		var eq = str.indexOf("=");
		if(str.length == 0 || eq == -1)
		{
			return all;
		}

		var id = str.indexOf('"');
		var nextid = str.indexOf('"',id + 1);
		var val = str.substring(id + 1,nextid);

		var key = str.substring(0,eq);
		A = key.split(" ");
		key = A.join("");
		all[key] = val;
		str = str.substring(nextid + 1,str.length);
	}
	return "";
}

function _prolog(str)
{
	var A = new Array();

	A = str.split("\n");
	str = A.join("");
	A = str.split("\r");
	str = A.join("");
	A = str.split("\t");
	str = A.join("");

	return str;
}


