//<! OmenTree Dynamic Hierarchial Menu System (C) 1998 Colin Tucker/OmenSoft >
//<! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >
//<! This script may be distributed freely, however the author would like    >
//<! potential users to send him a message stating the URL of your site, so  >
//<! a link can be added for your site to the OmenSoft home page. Thank you. >
//<! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >
//<! e-mail: omensoft@poboxes.com          web: http://omensoft.home.ml.org/ >

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// start() - GENERAL FUNCTION - called by the HTML document once loaded - starts OmenTree by
//					  first loading the user data, and then drawing the tree.

function start() {
	loadData();
	drawTree();
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// drawTree() - GENERAL FUNCTION - starts the recursive tree drawing process by first writing
//					     the root node, and then all subordinate branches.

function drawTree() {
	outputFrame = top.treeFrame.window.document;	// If you really must, you can change the name of the treeFrame here to match your new name defined at the bottom.
	outputFrame.open("text/html");
	outputFrame.write("<! HTML Generated Dynamically by OmenTree - (C) 1998 Colin Tucker / OmenSoft >\n");
	outputFrame.write("<! http://omensoft.home.ml.org/                   e-mail: semi@earthcorp.com >\n");
	outputFrame.write("<HTML>\n<BODY BGCOLOR='" + backgroundColor + "' BACKGROUND='" + backgroundImage + "' LINK='" + linkColor + "' ALINK='" + aLinkColor + "' VLINK='" + vLinkColor + "'>\n");
	outputFrame.write("<FONT FACE='" + omenTreeFont + "' SIZE=" + omenTreeFontSize + " COLOR='" + textColor + "'>\n");
	outputFrame.write(prefixHTML + "\n<NOBR>\n");
	if (treeData[1].target == "") {var targetFrame = defaultTargetFrame} else {var targetFrame = treeData[1].target}
	if (treeData[1].icon == "") {var imageString = defaultImageURL + 'img-globe-' + structureStyle + '.gif'} else {imageString = defaultImageURL + treeData[1].icon}
	outputFrame.write("<A HREF='" + treeData[1].url + "' TARGET='" + targetFrame + "' onMouseOver=\"window.status='" + treeData[1].url + "'; return true\"><IMG SRC='" + imageString + "' WIDTH=16 HEIGHT=16 ALIGN=TEXTTOP BORDER=0 ALT='" + treeData[1].url + "'></A>&nbsp;<B>" + treeData[1].name + "</B><BR>\n");
	drawBranch("root","");
	outputFrame.write("</NOBR>\n" + suffixHTML + "\n");
	outputFrame.write("</FONT>\n</BODY>\n</HTML>");
	outputFrame.close();
	window.status="OmenTree v1.0 - (C) 1998 Colin Tucker/OmenSoft - http://omensoft.home.ml.org";
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// drawBranch() - GENERAL FUNCTION - used by the drawTree() function to recursively draw all
//						 visable nodes in the tree structure.

function drawBranch(startNode,structureString) {
	var children = extractChildrenOf(startNode);
	var currentIndex = 1;
	while (currentIndex <= children.length) {
		outputFrame.write(structureString);
		if (children[currentIndex].type == 'link') {
			if (children[currentIndex].icon == "") {
				var imageString = defaultImageURL + defaultLinkIcon;
			}
			else {var imageString = defaultImageURL + children[currentIndex].icon}
			if (children[currentIndex].target == "") {
				var targetFrame = defaultTargetFrame;
			}
			else {var targetFrame = children[currentIndex].target}
			if (currentIndex != children.length) {
				outputFrame.write("<IMG SRC='" + defaultImageURL + "img-branch-cont-" + structureStyle + ".gif' WIDTH=19 HEIGHT=16 ALIGN=TEXTTOP>")
			}
			else {
				outputFrame.write("<IMG SRC='" + defaultImageURL + "img-branch-end-" + structureStyle + ".gif' WIDTH=19 HEIGHT=16 ALIGN=TEXTTOP>")
			}
			outputFrame.write("<A HREF='" + children[currentIndex].url + "' TARGET='" + targetFrame + "' onMouseOver=\"window.status='" + children[currentIndex].url + "'; return true\"><IMG SRC='" + imageString + "' WIDTH=16 HEIGHT=16 ALIGN=TEXTTOP BORDER=0 ALT='" + children[currentIndex].url + "'></A>&nbsp;" + children[currentIndex].name + "<BR>\n")	
		}
		else {
			var newStructure = structureString;
			if (children[currentIndex].iconClosed == "") {var iconClosed = "img-folder-closed-" + structureStyle + ".gif"} else {var iconClosed = children[currentIndex].iconClosed}
			if (children[currentIndex].iconOpen == "") {var iconOpen = "img-folder-open-" + structureStyle + ".gif"} else {var iconOpen = children[currentIndex].iconOpen}
			if (currentIndex != children.length) {
				if (children[currentIndex].open == 0) {
					outputFrame.write("<A HREF=\"javascript:top.toggleFolder('" + children[currentIndex].id + "',1)\" onMouseOver=\"window.status='Click to open this folder'; return true\"><IMG SRC='" + defaultImageURL + "img-plus-cont-" + structureStyle + ".gif' WIDTH=19 HEIGHT=16 ALT='Click to open this folder' ALIGN=TEXTTOP BORDER=0>")
					outputFrame.write("<IMG SRC='" + defaultImageURL + iconClosed + "' WIDTH=16 HEIGHT=16 ALT='Click to open this folder' ALIGN=TEXTTOP BORDER=0></A>&nbsp;" + children[currentIndex].name + "<BR>\n")
				}
				else {
					outputFrame.write("<A HREF=\"javascript:top.toggleFolder('" + children[currentIndex].id + "',0)\" onMouseOver=\"window.status='Click to close this folder'; return true\"><IMG SRC='" + defaultImageURL + "img-minus-cont-" + structureStyle + ".gif' WIDTH=19 HEIGHT=16 ALT='Click to close this folder' ALIGN=TEXTTOP BORDER=0>");
					outputFrame.write("<IMG SRC='" + defaultImageURL + iconOpen + "' WIDTH=16 HEIGHT=16 ALT='Click to close this folder' ALIGN=TEXTTOP BORDER=0></A>&nbsp;" + children[currentIndex].name + "<BR>\n");
					newStructure = newStructure + "<IMG SRC='" + defaultImageURL + "img-vert-line-" + structureStyle + ".gif' WIDTH=19 HEIGHT=16 ALIGN=TEXTTOP>";
					drawBranch(children[currentIndex].id,newStructure); 
				}
			}
			else {
				if (children[currentIndex].open == 0) {
					outputFrame.write("<A HREF=\"javascript:top.toggleFolder('" + children[currentIndex].id + "',1)\" onMouseOver=\"window.status='Click to open this folder'; return true\"><IMG SRC='" + defaultImageURL + "img-plus-end-" + structureStyle + ".gif' WIDTH=19 HEIGHT=16 ALT='Click to open this folder' ALIGN=TEXTTOP BORDER=0>")
					outputFrame.write("<IMG SRC='" + defaultImageURL + iconClosed + "' WIDTH=16 HEIGHT=16 ALT='Click to open this folder' ALIGN=TEXTTOP BORDER=0></A>&nbsp;" + children[currentIndex].name + "<BR>\n")
				}
				else {
					outputFrame.write("<A HREF=\"javascript:top.toggleFolder('" + children[currentIndex].id + "',0)\" onMouseOver=\"window.status='Click to close this folder'; return true\"><IMG SRC='" + defaultImageURL + "img-minus-end-" + structureStyle + ".gif' WIDTH=19 HEIGHT=16 ALT='Click to close this folder' ALIGN=TEXTTOP BORDER=0>");
					outputFrame.write("<IMG SRC='" + defaultImageURL + iconOpen + "' WIDTH=16 HEIGHT=16 ALT='Click to close this folder' ALIGN=TEXTTOP BORDER=0></A>&nbsp;" + children[currentIndex].name + "<BR>\n");
					newStructure = newStructure + "<IMG SRC='" + defaultImageURL + "img-blank.gif' WIDTH=19 HEIGHT=16 ALIGN=TEXTTOP>";
					drawBranch(children[currentIndex].id,newStructure); 
				}
			}
		}
		currentIndex++;
	}
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// toggleFolder() - GENERAL FUNCTION - opens/closes folder nodes.

function toggleFolder(id,status) {
	var nodeIndex = indexOfNode(id); 
	treeData[nodeIndex].open = status; 
	timeOutId = setTimeout("drawTree()",100)}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// indexOfNode() - GENERAL FUNCTION - finds the index in the treeData Collection of the node
//						  with the given id.

function indexOfNode(id) {
	var currentIndex = 1;
	while (currentIndex <= treeData.length) {
		if ((treeData[currentIndex].type == 'root') || (treeData[currentIndex].type == 'folder')) {
			if (treeData[currentIndex].id == id) {return currentIndex}} 
		currentIndex++} 
	return -1}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// extractChildrenOf() - GENERAL FUNCTION - extracts and returns a Collection containing all
//							  of the node's immediate children nodes.

function extractChildrenOf(node) {
	var children = new Collection();
	var currentIndex = 1; 
	while (currentIndex <= treeData.length) {
		if ((treeData[currentIndex].type == 'folder') || (treeData[currentIndex].type == 'link')) {
			if (treeData[currentIndex].parent == node) {
				children.add(treeData[currentIndex])}}
		currentIndex++} 
	return children}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Collection() - OBJECT - a dynamic storage structure similar to an Array.

function Collection() {
	this.length = 0; 
	this.add = add; 
	return this}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// add() - METHOD of Collection - adds an object to a Collection.

function add(object) {
	this.length++; 
	this[this.length] = object}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// RootNode() - OBJECT - represents the top-most node of the hierarchial tree.

function RootNode(id,name,url,target,icon) {
	this.id = id;
	this.name = name;
	this.url = url;
	this.target = target;
	this.icon = icon;
	this.type = 'root';
	return this}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// FolderNode() - OBJECT - represents a node which branches to contain other nodes.

function FolderNode(id,parent,name,iconClosed,iconOpen) {
	this.id = id;
	this.parent = parent;
	this.name = name;
	this.iconClosed = iconClosed;
	this.iconOpen = iconOpen;
	this.type = 'folder';
	this.open = 0;
	return this}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LinkNode() - OBJECT - a node that represents a link using a URL.

function LinkNode(parent,name,url,target,icon) {
	this.parent = parent;
	this.name = name;
	this.url = url;
	this.target = target;
	this.icon = icon;
	this.type = 'link';
	return this}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// loadData() - GENERAL FUNCTION - user defined data and variables exist in this function.

function loadData() {

      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      // Tree structure definitions:

      // Syntax:

      // ROOT NODE:
      // treeData.add(new RootNode("<ID>","<NAME>","<URL>","<TARGET>","<ALT ICON>")); 
      // NOTE: There must be only ONE root node, and it MUST be the FIRST node.
      //       <TARGET> and <ALT ICON> can be left null - defaults will be used.

      // FOLDER NODE:
      // treeData.add(new FolderNode("<ID>","<PARENT ID>","<NAME>","<ALT ICON CLOSED>","<ALT ICON OPEN>"));
      // NOTE: Folder nodes MUST have a valid parent node, and they SHOULD have children nodes.
      //       <ALT ICON CLOSED> and <ALT ICON OPEN> can be left null - OmenTree will use the
      //       default images.

      // LINK NODE:
      // treeData.add(new LinkNode("<PARENT ID>","<NAME>","<URL>","<TARGET>","<ALT ICON>"));
      // NOTE: <TARGET> and <ALT ICON> may be left null - defaults specified in the user 
      //       defined variables section will be used.

      // Consult the OmenTree documentation for further assistance.

	treeData = new Collection();
	
	treeData.add(new RootNode('root','Ole Links!','links.html','_top',''));      // Root Node MUST be first!
	
	treeData.add(new FolderNode('home', 'root', 'Oles Kingdom','', ''));
		treeData.add(new LinkNode('home','Home','index.html', '_top', 'img-page.gif'));
		treeData.add(new LinkNode('home','Me','me.html', '_top', 'img-page.gif'));
		treeData.add(new LinkNode('home','Images','images.html', '_top', 'img-page.gif'));
		treeData.add(new LinkNode('home','Humor','humor.html', '_top', 'img-page.gif'));
		treeData.add(new LinkNode('home','Thought','philosophy.html', '_top', 'img-page.gif'));
		treeData.add(new LinkNode('home','Shrines','shrines.html', '_top', 'img-page.gif'));
		treeData.add(new LinkNode('home','Computers','computers.html', '_top', 'img-page.gif'));
		treeData.add(new LinkNode('home','Links','linkstxt.html', '_top', 'img-page.gif'));

	treeData.add(new FolderNode('pers', 'root',  'Personal Pages', '', ''));
		treeData.add(new LinkNode('pers', 'Jodie!', 'http://www.angelfire.com/mi/genastorhotz/', '_top', ''));
		treeData.add(new LinkNode('pers', 'Scott the Roomate', 'http://nav.to/Zoogz', '_top', ''));
		treeData.add(new LinkNode('pers', 'Dan Thurston', 'http://www.angelfire.com/scifi/thurston', '_top', ''));
		treeData.add(new LinkNode('pers', 'Dave Huhn', '????', '', ''));
		treeData.add(new LinkNode('pers', 'Jim Tomlinson', 'http://www2.gvsu.edu/~tomlinsj/index.htm', '_top', ''));
		treeData.add(new LinkNode('pers', 'Jeremy Padlo', 'http://www.angelfire.com/anime/vampirecowboy/', '_top', ''));

	treeData.add(new FolderNode('comp', 'root', 'Computers', '', ''));
		treeData.add(new FolderNode('ai', 'comp', 'AI', '',''));
			treeData.add(new LinkNode('ai', 'Demo of AI Search', 'http://www.cs.rmit.edu.au/AI-Search/', '_top', ''));	
			treeData.add(new LinkNode('ai', 'AR Index', 'http://www.cs.uiowa.edu/~hzhang/ar.html', '_top', ''));
			treeData.add(new LinkNode('ai', 'AR @ Argonne', 'http://www-unix.mcs.anl.gov/AR/', '_top', ''));

		treeData.add(new FolderNode('linux', 'comp', 'Linux', '',''));
			treeData.add(new LinkNode('linux', 'Free Linux Software', 'http://usol.linux.tucows.com/index.html', '_top', ''));
			treeData.add(new LinkNode('linux', 'Quake for Linux', 'http://www.linuxquake.com/', '_top', ''));

		treeData.add(new LinkNode('comp', 'WWW Consortium', 'http://www.w3.org/', '_top', ''));
		treeData.add(new LinkNode('comp', 'SodaConstructor (cool)', 'http://sodaplay.com/constructor/index.htm', '_top', ''));
		treeData.add(new LinkNode('comp', '3-D engines on-line', 'http://cg.cs.tu-berlin.de/~ki/engines.html', '_top', ''));
		treeData.add(new LinkNode('comp', 'MPI/LAM', 'http://www.lam-mpi.org/tutorials/lam/running.php', '_top',''));
		treeData.add(new LinkNode('comp', 'TCL FAQ', 'http://www.tclfaq.wservice.com/tcl-faq/', '_top',''));
		treeData.add(new LinkNode('comp', 'Cascading Style Sheets', 'http://www.htmlhelp.com/reference/css/', '_top',''));
		treeData.add(new LinkNode('comp', 'XML tutorial', 'http://msxml.com/xml_tutorial/toc.html', '_top',''));

	treeData.add(new FolderNode('anime', 'root', 'Anime', '', ''));
		treeData.add(new LinkNode('anime', 'Otaku No Anime', 'http://www2.gvsu.edu/~anime/', '_top', ''));
		treeData.add(new LinkNode('anime', 'Anipike', 'http://www.anipike.com', '_top', ''));

	treeData.add(new FolderNode('gvsu', 'root', 'GVSU', '', ''));
		treeData.add(new LinkNode('gvsu', 'GVSU Main Site', 'http://www.gvsu.edu', '_top', ''));
		treeData.add(new LinkNode('gvsu', 'GVSU Card Catalog', 'http://www.gvsu.edu/library/voyager/index.htm', '_top', ''));
		treeData.add(new LinkNode('gvsu', 'Computer Science Dept.', 'http://www.csis.gvsu.edu/', '_top', ''));
		treeData.add(new LinkNode('gvsu', 'Philosophy Dept.', 'http://www.gvsu.edu/acad/phi/Phi-appr.html', '_top', ''));
		treeData.add(new LinkNode('gvsu', 'The Student Voice', 'http://www2.gvsu.edu/~tsvoice/', '_top', ''));

	treeData.add(new FolderNode('int', 'root', 'Interesting', '',''));
		treeData.add(new FolderNode('comics', 'int', 'On-line Comics', '',''));
			treeData.add(new LinkNode('comics', 'Userfriendly', 'http://www.userfriendly.org', '_top', ''));
			treeData.add(new LinkNode('comics', 'Dilbert', 'http://www.dilbert.com', '_top', ''));
			treeData.add(new LinkNode('comics', 'Adventurers!', 'http://www.adventurerscomic.com', '_top', ''));
			treeData.add(new LinkNode('comics', 'RPG World', 'http://rpgworld.keenspace.com', '_top', ''));

		treeData.add(new LinkNode('int', 'Urban Legends', 'http://www.snopes.com', '_top', ''));
		treeData.add(new LinkNode('int', 'MST3K!', 'http://www.mst3k.com/', '_top', ''));
		treeData.add(new LinkNode('int', 'Final Fantasy', 'http://www.ffonline.com/', '_top', ''));


	treeData.add(new FolderNode('use', 'root', 'Useful', '', ''));
		treeData.add(new LinkNode('use', 'Internet Tracing', 'http://www.samspade.org/', '_top', ''));
		treeData.add(new LinkNode('use', 'Airtouch Paging', 'http://webmsg.airtouch.com/textmsg_body.html', '_top' , ''));

	treeData.add(new FolderNode('gr', 'root', 'Local', '', ''));
		treeData.add(new LinkNode('gr', 'GR Library', 'http://www.grapids.lib.mi.us/', '_top',''));
		treeData.add(new LinkNode('gr', 'GR Card Catalog', 'http://www.grpl.org/perl/webpac.pl', '_top', ''));
		treeData.add(new LinkNode('gr', 'Yahoo GR', 'http://dir.yahoo.com/Regional/U_S__States/Michigan/Cities/Grand_Rapids/', '_top',''));
		treeData.add(new LinkNode('gr', 'GRATA Buses', 'http://www.grata.org/', '_top' , ''));
		treeData.add(new LinkNode('gr', 'Star Alpine Showtimes', 'http://www.startheatres.com/showtimes/index_grshow.html' , '_top', ''));
		treeData.add(new LinkNode('gr', 'St. Anthony of Padua', 'http://www.saparish.com' , '_top', ''));


      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      // User defined variables:	

       structureStyle = 0;                   // 0 for light background, 1 for dark background

      backgroundColor = '#FFFFFF';           // sets the bgColor of the menu
            textColor = '#000000';           // sets the color of the text used in the menu
            linkColor = '#0066ff';           // sets the color of any text links (usually defined in additional HTML sources)
           aLinkColor = '#ff0000';           // sets the active link color (when you click on the link)
           vLinkColor = '#ff66ff';           // sets the visited link color

      backgroundImage = 'images/yellroc.jpg';// give the complete path to a gif or jpeg to use as a background image

      defaultTargetFrame = 'pageFrame';      // the name of the frame that links will load into by default 
         defaultImageURL = 'images/';        // the URL or path where the OmenTree images are located

       defaultLinkIcon = 'img-page-globe.gif';  // the default icon image used for links

          omenTreeFont = 'MS Sans Serif,Arial,Helvetica';  // the font used for the menu
      omenTreeFontSize = 1;                                // its size - don't make it too big!

      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      // Additional HTML sources:

      prefixHTML = "<hr>";
      suffixHTML = "<hr>This Links tree created using JavaScript from <b>OmenSoft</b><p>";
}
