/*
 * Reads a HTML file with hierarchical structure and generates a collapsable menu from it
 * Provide source to the makeMenu(iFrameElement) menthode like following:
 * <iframe onload="makeMenu(this);" id="menusource" src="menu.htm" frameborder="0" width="0" scrolling="no" height="0"></iframe>
 *
 * ZoomBIM 4-8-2009
 */

function makeMenu(iFrameElement){
	var sourceDoc = getIframeDoc(iFrameElement);
	var menuMain = sourceDoc.getElementById("menu");
	var elmTbody = menuMain.getElementsByTagName("tbody");
	var sourceElement = elmTbody[0];
	
	var reader = new MenuReader();
	var menu = reader.read(sourceElement);
	
	var targetElement = document.getElementById(iFrameElement.attributes.targetid.value);
	targetElement.innerHTML = "";

	var generator = new MenuGenerator();
	generator.generate(menu, targetElement);
}

function getIframeDoc(iFrameElement){
	return iFrameElement.contentWindow.document;
}

function getFilename(uri){
	var lastSlash = uri.lastIndexOf("/");
	var queryStringStart = uri.lastIndexOf("?");
	var anchor = uri.lastIndexOf("#");
	if (queryStringStart > -1 && queryStringStart < anchor) return uri.substring(lastSlash+1,queryStringStart);
	if (anchor > -1 && anchor < queryStringStart) return uri.substring(lastSlash+1,anchor);
	else return uri.substring(lastSlash+1);
}


///
/// A MenuItem represents a node in the navigation structure.
///
function MenuItem(name, url)
{
	this.name = name;
	this.url = url;
	this.children = [];
	this.parent = null;
	this.selected = false;
	this.visible = false;
	this.level = 0;
};

MenuItem.prototype.appendChild = function(child)
{
	this.children.push(child);
	
	if(child.visible == true)
		this.makeVisible();
	
	child.parent = this;
	child.updateLevels();
};

MenuItem.prototype.select = function()
{
	this.selected = true;
	this.makeVisible();
};

MenuItem.prototype.makeVisible = function()
{
	this.visible = true;
	
	if(this.parent)
		this.parent.makeVisible();
};

MenuItem.prototype.updateLevels = function()
{
	this.level = (this.parent == null) ? 0 : this.parent.level + 1;

	for(var i=0; i<this.children.length; i++)
		this.children[i].updateLevels();
}

///
/// The MenuReader class reads the html of the original menu and creates a tree of MenuItems.
///
function MenuReader() { };

MenuReader.prototype.read = function(element)
{
	var item = new MenuItem("root", "");

	for(var j=0; j<element.rows.length; j++)
	{
		var row = element.rows[j];

		for(var i=0; i<row.childNodes.length; i++)
		{
			var childNode = row.childNodes[i];
			var child = this.readItem(childNode);

			if(child != null)
				item.appendChild(child);
		}
	}

	return item;
}

MenuReader.prototype.readItem = function(element)
{
	if(element.nodeType != 1)
		return null;
 
	var className = element.className;
 
	if(element.nodeName.toLowerCase() == "span")
		return;
 
	if(element.className == null || element.className.indexOf("level") == -1)
		return null;
  
	var link = element.getElementsByTagName("a")[0];
	
	if(link == null)
		return null;
 
	var item = new MenuItem(link.innerHTML, link.href); 
	
	// Check if this menuitem links to the current page.	
	if(getFilename(item.url).toUpperCase() == getFilename(document.location.href).toUpperCase())
		item.select();
	
	for(var i=0; i<element.childNodes.length; i++)
	{
		var childNode = element.childNodes[i];
		var child = this.readItem(childNode);
  
		if(child != null)
			item.appendChild(child);
	}
 
	return item;
};

///
/// The MenuGenerator class generates a menu based on the given MenuItem tree.
///
function MenuGenerator(element) { };

MenuGenerator.prototype.generate = function(menuItem, element)
{
	element = typeof(element) == "string" ? document.getElementById(element) : element;

	switch(menuItem.level)
	{
		case 0 : 
			for(var i=0; i<menuItem.children.length; i++)
				this.generate(menuItem.children[i], element);
			break;
		default :		
			var div = document.createElement("div");
			div.className = "level" + menuItem.level;

			if(menuItem.selected)
				div.className += "_visible";
			else if(menuItem.visible)
				div.className += "_visible";

			element.appendChild(div);
			
			var textItem = document.createElement("div");
			textItem.className = "level" + menuItem.level + "_text";
			if(menuItem.selected){
				textItem.className += "_active";
			}
			div.appendChild(textItem);

			var link = document.createElement("a");
			link.href = menuItem.url;
			link.appendChild(document.createTextNode(menuItem.name));
			textItem.appendChild(link);

			if(menuItem.visible)
			{
				for(var i=0; i<menuItem.children.length; i++)
					this.generate(menuItem.children[i], div);
			}

		break;
	}
};

