// TSPTree
// Date Started: 10/01/2004

function TSPNode(aParent, aCaption, aIndex)
{
	this.Initialised = false;
	this.Index = aIndex;
	this.Parent = aParent;
	this.Caption = aCaption;
	this.Expanded = false;
	this.HasChild = false;
	this.IsLastNode = true;
	this.ActiveNode = null;
	this.ChildCount = 0;
	this.Icon = "TSPTree/images/1x1.gif";
	this.NodeData = null;
	this.PageLink = "";
	this.Target = "";
}

function TSPTree(aName)
{
	this.Root = new TSPNode(null, "Root", -1);
	this.AutoAddNode = true;
	this.Name = aName;
	this.NodeCount = 0;
	this.Node = new Array;
	this.ActiveNodeBG = null;
	this.ShowRoot = false;
	this.SelectedNode = null;
	this.NodeFocusColor = "#CCCCCC";
	this.NodeInactiveColor = "#FFFFFF";
	this.LinkClass = "TreeLink";
	this.NodeExpandOnly = false;
	// Private Method
	this.GetNodeImg = TSPTree_GetNodeImg; 
	this.AddNode = TSPTree_AddNode;
	// Public Method
	this.AddChild = TSPTree_AddChild;
	this.ChildFirstNode = TSPTree_ChildFirstNode;
	this.ChildLastNode = TSPTree_ChildLastNode;
	this.NextSibling = TSPTree_NextSibling;
	this.Initialise = TSPTree_Initialise; 
	this.Refresh = TSPTree_Refresh;
	this.Clear = TSPTree_Clear;
	this.OnExpand = "";
	this.OnClick = "";
	this.OnDblClick = "";
	this.OnIconClick = "";
	this.OnNodeClick = TSPTree_OnNodeClick;
	this.OnNodeDblClick = TSPTree_OnNodeDblClick;
	this.ExpandNode = TSPTree_ExpandNode;
	this.CollapseNode = TSPTree_CollapseNode;
	this.ExpandAll = TSPTree_ExpandAll; 
	this.CollapseAll = TSPTree_CollapseAll; 
	this.SetSelectedNode = TSPTree_SetSelectedNode;
	this.InternalNodeClick = TSPTree_InternalNodeClick;
	this.GetNode = TSPTree_GetNode;
}

function TSPTree_AddChild(aParent, aCaption, aHasChild)
{
	var nodeIcon = "";

	if(aParent == null)
	{
		this.Root.HasChild = true;
		this.Root.ChildCount++;
	}
	else
	{
		aParent.HasChild = true;
		aParent.ChildCount++;
	}
	
	if(TSPTree_AddChild.arguments.length >= 4)
	{
		nodeIcon = TSPTree_AddChild.arguments[3];
	}

	var LNode = this.ChildLastNode(aParent);
	if(LNode != null)
	{
		LNode.IsLastNode = false;
		// Update Node Level
		if(LNode.Initialised)
		{
			var ObjImg = eval("document." + this.Name + "NodeImg" + LNode.Index);
			ObjImg.src = "TSPTree/images/Tree" + this.GetNodeImg(LNode) + ".gif";
		}
	}

	this.Node[this.NodeCount] = new TSPNode(aParent, aCaption, this.NodeCount);
	this.Node[this.NodeCount].HasChild = aHasChild;
	if(nodeIcon != "")
	{
		this.Node[this.NodeCount].Icon = nodeIcon;		
	}

	if(this.AutoAddNode)
	{
		if(aParent == null)
		{
			if(this.Root.Initialised)
			{
				this.AddNode(this.Node[this.NodeCount], -1);
			}
		}
		else
		{
			if(aParent.Initialised)
			{
				this.AddNode(this.Node[this.NodeCount], aParent.Index);	
			}
		}
	}
	this.NodeCount++;

	return this.Node[this.NodeCount - 1];
}

function TSPTree_ChildFirstNode(aParent)
{
	LParent = null;
	if(aParent != null)
	{
		if(aParent.Index != -1)
		{
			LParent = aParent;
		}
	}

	for(i = 0; i < this.NodeCount; i++)
	{
		if(this.Node[i].Parent == LParent)
		{
			if(LParent == null)
			{
				this.Root.ActiveNode = this.Node[i];
			}
			else
			{
				aParent.ActiveNode = this.Node[i];
			}
			return this.Node[i];
		}
	}
	return null;
}

function TSPTree_ChildLastNode(aParent)
{
	LParent = null;
	if(aParent != null)
	{
		if(aParent.Index != -1)
		{
			LParent = aParent;
		}
	}

	for(i = this.NodeCount - 1; i >= 0; i--)
	{
		if(this.Node[i].Parent == LParent)
		{
			if(LParent == null)
			{
				this.Root.ActiveNode = this.Node[i];
			}
			else
			{
				aParent.ActiveNode = this.Node[i];
			}
			return this.Node[i];
		}
	}

	return null;
}

function TSPTree_NextSibling(aParent)
{
	
	var LNode = null;
	if(aParent == null)
	{
		LNode = this.Root.ActiveNode;
	}
	else
	{
		if(aParent.Index != -1)
		{
			LNode = aParent.ActiveNode; 
		}
		else
		{
			LNode = this.Root.ActiveNode;
		}
	}

	var LFoundCurrentNode = false;
	for(i = 0; i < this.NodeCount; i++)
	{
		if(this.Node[i] == LNode)
		{
			LFoundCurrentNode = true;
		}

		if(LFoundCurrentNode)
		{
			if((this.Node[i] != LNode) && (this.Node[i].Parent == LNode.Parent))
			{
				if (aParent == null)
				{
					this.Root.ActiveNode = this.Node[i];
				}
				else
				{
					aParent.ActiveNode = this.Node[i]; 
				}
				return this.Node[i];
			}
		}
	}

	return null;
}

function TSPTree_SetSelectedNode(aNode)
{
	if(aNode != null)
	{
		this.SelectedNode = aNode;
		var LNodeBG = null;
		if (aNode.Index == -1)
		{
			LNodeBG = eval(this.Name + "NodeBGRoot");
		}
		else
		{
			LNodeBG = eval(this.Name + "NodeBG" + aNode.Index); 
		}

		if(this.ActiveNodeBG != LNodeBG)
		{
			LNodeBG.bgColor = this.NodeFocusColor;
			if(this.ActiveNodeBG != null)
			{
				this.ActiveNodeBG.bgColor = this.NodeInactiveColor;
			}
		}
		this.ActiveNodeBG = LNodeBG;
	}
}

function TSPTree_GetNodeImg(aNode)
{
	var LNodeType = "Node";
	if(aNode.HasChild)
	{
		if(aNode.IsLastNode)
		{
			LNodeType = "PosNodeLast";
		}
		else
		{
			LNodeType = "PosNode";
		}
	}
	else
	{
		if (aNode.IsLastNode)
		{
			LNodeType = "NodeLast";
		}
		else
		{
			LNodeType = "Node";
		}
	}
	return LNodeType;
}

function TSPTree_AddNode(aNode, aParentIndex)
{
	var LNodeType = this.GetNodeImg(aNode);
	var ClickEvent = ""
	if (this.OnDblClick != "")
	{
		ClickEvent = "onDblClick='" + this.Name + ".OnNodeDblClick(" + aNode.Index + ", false);'";
	}

	IconClickEvent = "#";
	if(this.OnIconClick != "")
	{
			IconClickEvent = "javascript:" + this.OnIconClick + "(" + aNode.Index + ")";
	}

	var div = document.createElement('div');
	div.innerHTML = "<table cellpadding=0 cellspacing=0 border=0 width='100%'>"
								+ "<tr>"
								+ "	<td width=23><a href='javascript:" + this.Name + ".OnNodeClick(" + aNode.Index + ", false);' " + ClickEvent + "><img src='TSPTree/images/Tree" + LNodeType + ".gif' name='" + this.Name + "NodeImg" + aNode.Index + "' width=23 border=0 style='display: block'></a></td>"
								+ "	<td width=16><a href='" + IconClickEvent + "'><img src='" + aNode.Icon + "' width=16 border=0></a></td>"
								+ "	<td id='" + this.Name + "NodeBG" + aNode.Index + "'><nobr><a class='" + this.LinkClass + "' href='javascript:" + this.Name + ".OnNodeClick(" + aNode.Index + ", true);' " + ClickEvent + ">&nbsp;" + aNode.Caption + "</a></nobr></td>"
								+ "</tr>"
								+ "<tr>"
								+ "	<td id='" + this.Name + "VLine" + aNode.Index + "'></td>"
								+ "	<td colspan=2>"
								+ "		<div id='" + this.Name + "Node" + aNode.Index + "' style='display:none;'>"
								+ "		</div>"
								+ "	</td>"
								+ "</tr>"
								+ "</table>";

	if(aNode.Parent == null)
	{
		if(this.ShowRoot)
		{
			eval(this.Name + "NodeRoot.appendChild(div);");
		}
		else
		{
			eval(this.Name + "Main.appendChild(div);");
		}
	}
	else
	{
		eval(this.Name + "Node" + aParentIndex + ".appendChild(div);");
	}
	aNode.Initialised = true;
}

function TSPTree_ExpandNode(aNode)
{
	if(aNode == null)
	{
		if(!this.Root.Expanded && this.Root.ChildCount > 0)
		{
			this.InternalNodeClick(-1, false);
		}
	}
	else
	{
		if(!aNode.Expanded && aNode.ChildCount > 0)
		{
			this.InternalNodeClick(aNode.Index, false);
		}
	}
}

function TSPTree_ExpandAll()
{
	for(var i = 0; i < this.NodeCount; i++)
	{
		this.ExpandNode(this.Node[i]);
	}
}

function TSPTree_CollapseNode(aNode)
{
	if(aNode == null)
	{
		if(this.Root.Expanded && this.Root.ChildCount > 0)
		{
			this.InternalNodeClick(-1, false);
		}
	}
	else
	{
		if(aNode.Expanded && aNode.ChildCount > 0)
		{
			this.InternalNodeClick(aNode.Index, false);
		}
	}
}

function TSPTree_CollapseAll()
{
	for(var i = 0; i < this.NodeCount; i++)
	{
		this.CollapseNode(this.Node[i]);
	}
}

function TSPTree_OnNodeClick(aIndex, aLink)
{
	this.InternalNodeClick(aIndex, aLink);
	// Execute custom onClick event
	if(this.OnClick != "")
	{
		if(!this.NodeExpandOnly || (this.NodeExpandOnly && aLink))
		{
			eval(this.OnClick + "(this.SelectedNode);");
		}
	}
}

function TSPTree_OnNodeDblClick(aIndex, aLink)
{
	// Execute custom onDblClick event
	if(this.OnDblClick != "")
	{
		eval(this.OnDblClick + "(this.SelectedNode);");
	}
}

function TSPTree_InternalNodeClick(aIndex, aLink)
{
	if(aIndex == -1)
	{
		this.SetSelectedNode(this.Root);
	}
	else
	{
		this.SetSelectedNode(this.Node[aIndex]);
	}

	if(!this.NodeExpandOnly || (this.NodeExpandOnly && !aLink))
	{
		if(!this.SelectedNode.Expanded && this.SelectedNode.HasChild)
		{
			// Execute custom onExpand event
			if(this.OnExpand != "")
			{
				eval(this.OnExpand + "(this.SelectedNode);");
			}

			if(aIndex != -1)
			{
				if(!this.SelectedNode.IsLastNode)
				{
					var ObjVLine = eval(this.Name + "VLine" + aIndex);
					ObjVLine.style.backgroundImage = "url(TSPTree/images/TreeVLine.gif)";
				}
			}

			// Initialise child node
			var LNode = this.ChildFirstNode(this.SelectedNode);
			while(LNode != null)
			{
				if(!LNode.Initialised)
				{
					this.AddNode(LNode, aIndex);
				}
				LNode = this.NextSibling(this.SelectedNode);
			}
		}

		// Expand or Collapse Tree
		if(aIndex == -1)
		{
			var Obj = eval(this.Name + "NodeRoot");
			var ObjImg = eval("document." + this.Name + "NodeImgRoot");
		}
		else
		{
			var Obj = eval(this.Name + "Node" + aIndex);
			var ObjImg = eval("document." + this.Name + "NodeImg" + aIndex);
		}

		if(this.SelectedNode.ChildCount > 0)
		{
			if(this.SelectedNode.Expanded)
			{
				Obj.style.display = "none";
				if (this.SelectedNode.IsLastNode)
				{
					ObjImg.src = "TSPTree/images/TreePosNodeLast.gif";
				}
				else
				{
					ObjImg.src = "TSPTree/images/TreePosNode.gif";
				}
			}
			else
			{
				Obj.style.display = "block";
				if (this.SelectedNode.IsLastNode)
				{
					ObjImg.src = "TSPTree/images/TreeNegNodeLast.gif";
				}
				else
				{
					ObjImg.src = "TSPTree/images/TreeNegNode.gif";
				}
			}
			this.SelectedNode.Expanded = !this.SelectedNode.Expanded;
		}
		else
		{
			if (this.SelectedNode.IsLastNode)
				{
					ObjImg.src = "TSPTree/images/TreeNodeLast.gif";
				}
				else
				{
					ObjImg.src = "TSPTree/images/TreeNode.gif";
				}
		}

		// Scroll to show expanded details
		if(Obj != null)
		{
			var mainObj = eval(this.Name + "Main");
			var topValue = 0;
			var calObj = Obj;
			while(calObj)
			{
				topValue += calObj.offsetTop;
				calObj = calObj.offsetParent;
			}

			if((topValue + Obj.offsetHeight) > mainObj.scrollTop + mainObj.offsetHeight)
			{
				Obj.scrollIntoView(true);
			}

			if((mainObj.scrollTop >= topValue - 2) && (mainObj.scrollTop <= topValue + 2) && mainObj.scrollTop > 0)
			{
				var scrollTop = mainObj.scrollTop;
				mainObj.scrollTop = scrollTop - 20;
			}
		}
	}

	// Execute Link
	if(aLink)
	{
		if(this.SelectedNode.PageLink != "")
		{
			if(this.SelectedNode.Target != "")
			{
				var Win = eval("window.parent." + this.SelectedNode.Target);
				Win.location.href = this.SelectedNode.PageLink;
			}
			else
			{
				location.href = this.SelectedNode.PageLink;
			}
		}
	}
}

function TSPTree_Initialise(aWidth, aHeight, aBorder)
{
	var LBorder = "";
	var LNodeType = "";

	if(aBorder) LBorder = "border: solid black 1px;";

	if(navigator.platform == "iPad" || navigator.platform == "Linux armv7l")
	{
		document.write("<div id='" + this.Name + "Main' style='width: " + aWidth + "; " + LBorder + "'>");
	}
	else
	{
		document.write("<div id='" + this.Name + "Main' style='width: " + aWidth + "; height: " + aHeight + "; overflow: auto;" + LBorder + "'>");
	}

	if(this.ShowRoot)
	{
		var ClickEvent = ""
		if (this.OnDblClick != "")
		{
			ClickEvent = "onDblClick='" + this.Name + ".OnNodeDblClick(" + this.Root.Index + ", false);'";
		}

		IconClickEvent = "#";
		if(this.OnIconClick != "")
		{
				IconClickEvent = "javascript:" + this.OnIconClick + "(" + this.Root.Index + ")";
		}

		document.write("<div>");
		document.write("<table cellpadding=0 cellspacing=0 border=0 width='100%'>");
		document.write("<tr>");
		document.write("	<td width=23><a href='javascript:" + this.Name + ".OnNodeClick(" + this.Root.Index + ", false);' " + ClickEvent + "><img src='TSPTree/images/TreePosNodeLast.gif' name='" + this.Name + "NodeImgRoot' width=23 border=0></a></td>");
		document.write("	<td width=16><a href='" + IconClickEvent + "'><img src='" + this.Root.Icon + "' width=16 border=0></a></td>");
		document.write("	<td id='" + this.Name + "NodeBGRoot'><nobr><a class='" + this.LinkClass + "' href='javascript:" + this.Name + ".OnNodeClick(" + this.Root.Index + ", true);' " + ClickEvent + ">&nbsp;" + this.Root.Caption + "</a></nobr></td>");
		document.write("</tr>");
		document.write("<tr>");
		document.write("	<td id='" + this.Name + "VLineRoot'></td>");
		document.write("	<td colspan=2>");
		document.write("		<div id='" + this.Name + "NodeRoot' style='display:none;'>");
	}


	var LNode = this.ChildFirstNode(null);
	while(LNode != null)
	{
		LNodeType = this.GetNodeImg(LNode);

		var ClickEvent = ""
		if (this.OnDblClick != "")
		{
			ClickEvent = "onDblClick='" + this.Name + ".OnNodeDblClick(" + LNode.Index + ", false);'";
		}

		IconClickEvent = "#";
		if(this.OnIconClick != "")
		{
				IconClickEvent = "javascript:" + this.OnIconClick + "(" + LNode.Index + ")";
		}

		document.write("<div>");
		document.write("<table cellpadding=0 cellspacing=0 border=0 width='100%'>");
		document.write("<tr>");
		document.write("	<td width=23><a href='javascript:" + this.Name + ".OnNodeClick(" + LNode.Index + ", false);' " + ClickEvent + "><img src='TSPTree/images/Tree" + LNodeType + ".gif' name='" + this.Name + "NodeImg" + LNode.Index + "' width=23 border=0></a></td>");
		document.write("	<td width=16><a href='" + IconClickEvent + "'><img src='" + LNode.Icon + "' width=16 border=0></a></td>");
		document.write("	<td id='" + this.Name + "NodeBG" + LNode.Index + "'><nobr><a class='" + this.LinkClass + "' href='javascript:" + this.Name + ".OnNodeClick(" + LNode.Index + ", true);' " + ClickEvent + ">&nbsp;" + LNode.Caption + "</a></nobr></td>");
		document.write("</tr>");
		document.write("<tr>");
		document.write("	<td id='" + this.Name + "VLine" + LNode.Index + "'></td>");
		document.write("	<td colspan=2>");
		document.write("		<div id='" + this.Name + "Node" + LNode.Index + "' style='display:none;'>");
		document.write("		</div>");
		document.write("	</td>");
		document.write("</tr>");
		document.write("</table>");
		document.write("</div>");

		LNode.Initialised = true;
		LNode = this.NextSibling(null);
	}

	if(this.ShowRoot)
	{
		document.write("		</div>");
		document.write("	</td>");
		document.write("</tr>");
		document.write("</table>");
		document.write("</div>");
	}

	this.Root.Initialised = true;
	document.write("</div>");
}

function TSPTree_Refresh()
{
	var MainDiv = document.getElementById(this.Name + "Main");
	MainDiv.innerHTML = "";

	if(this.ShowRoot)
	{
		this.Root.Expanded = false;
		var div = document.createElement('div');
	
		var ClickEvent = ""
		if (this.OnDblClick != "")
		{
			ClickEvent = "onDblClick='" + this.Name + ".OnNodeDblClick(" + this.Root.Index + ", false);'";
		}

		IconClickEvent = "#";
		if(this.OnIconClick != "")
		{
				IconClickEvent = "javascript:" + this.OnIconClick + "(" + this.Root.Index + ")";
		}

		div.innerHTML = "<table cellpadding=0 cellspacing=0 border=0 width='100%'>"
										+ "<tr>"
										+ "	<td width=23><a href='javascript:" + this.Name + ".OnNodeClick(" + this.Root.Index + ", false);' " + ClickEvent + "><img src='TSPTree/images/TreePosNodeLast.gif' name='" + this.Name + "NodeImgRoot' width=23 border=0></a></td>"
										+ "	<td width=16><a href='" + IconClickEvent + "'><img src='" + this.Root.Icon + "' width=16 border=0></a></td>"
										+ "	<td id='" + this.Name + "NodeBGRoot'><nobr><a href='javascript:" + this.Name + ".OnNodeClick(" + this.Root.Index + ", true);' " + ClickEvent + ">&nbsp;" + this.Root.Caption + "</a></nobr></td>"
										+ "</tr>"
										+ "<tr>"
										+ "	<td id='" + this.Name + "VLineRoot'></td>"
										+ "	<td colspan=2>"
										+ "		<div id='" + this.Name + "NodeRoot' style='display:none;'>"
										+ "		</div>"
										+	"	</td>"
										+ "</tr>"
										+ "</table>";

		eval(this.Name + "Main.appendChild(div);");
	}

	for(var i = 0; i < this.NodeCount; i++)
	{
			this.Node[i].Expanded = false;
			this.Node[i].Initialised = false;
	}

	var LNode = this.ChildFirstNode(null);
	while(LNode != null)
	{
		this.AddNode(LNode, -1);
		LNode = this.NextSibling(null);
	}
}

function TSPTree_Clear()
{
	this.NodeCount = 0;
	this.Node = new Array;
	this.SelectedNode = null;
	this.Refresh();
}

function TSPTree_GetNode(aIndex)
{
	var LNode = null;

	if(aIndex < this.Node.length)
	{
		LNode = this.Node[aIndex];
	}

	return LNode;
}