function TreeConfig()
{
	this.dir_img = "images/";
	this.icon_width = 32;
	this.icon_height = 32;
	this.linkformat = "";

	this.img_collapse = this.dir_img + "collapse.gif";
	this.img_expand = this.dir_img + "expand.gif";
	this.img_nochilds1 = this.dir_img + "nochilds1.gif";
	this.img_nochilds = this.dir_img + "nochilds.gif";
	this.img_empty = this.dir_img + "empty.gif";
	this.img_vertical = this.dir_img + "vertical.gif";
	this.img_verhor1 = this.dir_img + "verhor1.gif";
	this.img_verhor = this.dir_img + "verhor.gif";

	this.SetConfig = function(dir, width, height, format, restoreimages)
	{
		this.dir_img = dir;
		this.icon_width = width;
		this.icon_height = height;
		this.linkformat = format;
		if(restoreimages)
		{
			this.img_collapse = this.dir_img + "collapse.gif";
			this.img_expand = this.dir_img + "expand.gif";
			this.img_nochilds1 = this.dir_img + "nochilds1.gif";
			this.img_nochilds = this.dir_img + "nochilds.gif";
			this.img_empty = this.dir_img + "empty.gif";
			this.img_vertical = this.dir_img + "vertical.gif";
			this.img_verhor1 = this.dir_img + "verhor1.gif";
			this.img_verhor = this.dir_img + "verhor.gif";
		}
	};
	this.SetImages = function(collapse, expand, nochilds1, nochilds, empty, vertical, verhor1, verhor)
	{
		this.img_collapse = collapse;
		this.img_expand = expand;
		this.img_nochilds1 = nochilds1;
		this.img_nochilds = nochilds;
		this.img_empty = empty;
		this.img_vertical = vertical;
		this.img_verhor1 = verhor1;
		this.img_verhor = verhor;
	}
}

function TreeView(varname, div_id)
{
	this.varname = varname == null ? "TreeObj" : varname;
	this.div_id = div_id == null ? "TreeLayer" : div_id;
	this.config = new TreeConfig();
	this.nodes = [];
	this.SetConfig = function(dir, width, height, format, restoreimages)
	{
		this.config.SetConfig(dir, width, height, format, restoreimages);
	}
	this.SetImages = function(collapse, expand, nochilds1, nochilds, empty, vertical, verhor1, verhor)
	{
		this.config.SetImages(collapse, expand, nochilds1, nochilds, empty, vertical, verhor1, verhor);
	}
	this.CollapseAll = function()
	{
		for(var c=0; c<this.nodes.length; c++)
			this.nodes[c].CollapseAll();
	}
	this.ExpandAll = function()
	{
		for(var c=0; c<this.nodes.length; c++)
			this.nodes[c].ExpandAll();
	}
	this.AddNode = AddNode;
	this.GetNodeCount = GetNodeCount;
	this.GetNodeCountAtLevel = GetNodeCountAtLevel;
	this.GetNodeAt = function(level,index)
	{
		var levelNodes = [];
		this.Fill(this.nodes,levelNodes,level);
		return levelNodes[index];
	}
	this.GetDraw = function()
	{
		var nodesinlevel = [];
		var levelsdraw = []
		var treedraw = "";
		for(var c=0; c<this.nodes.length; c++)
		{
			treedraw += "<div>";
			treedraw += this.nodes[c].GetDraw(true, 0, c==this.nodes.length-1, nodesinlevel, levelsdraw, this.config);
		}
		return treedraw;
	}
	this.Draw = function()
	{
		document.getElementById(this.div_id).innerHTML = this.GetDraw();
	}
	this.Fill = function(nodes,levelNodes,level) //function(nodes,&levelNodes,level)
	{
		if(level == 0)
			for(var c=0; c<nodes.length; c++)
				levelNodes[levelNodes.length] = nodes[c];
		else if(level > 0)
			for(var c=0; c<nodes.length; c++)
				this.Fill(nodes[c].nodes,levelNodes,level-1);
	}
}

function TreeNode(text, link, image, varname)
{
	this.text = text;
	this.link = link;
	this.image = image;
	this.varname = varname;
	this.nodes = [];
	this.isExpanded = false;
	this.ChangeState = function()
	{
		this.isExpanded = !this.isExpanded;
	}
	this.Collapse = function()
	{
		this.isExpanded = false;
	}
	this.CollapseAll = function()
	{
		for(var c=0; c<this.nodes.length; c++)
			this.nodes[c].CollapseAll();
		this.isExpanded = false;
	}
	this.Expand = function()
	{
		this.isExpanded = true;
	}
	this.ExpandAll = function()
	{
		for(var c=0; c<this.nodes.length; c++)
			this.nodes[c].ExpandAll();
		this.isExpanded = true;
	}
	this.AddNode = AddNode;
	this.GetNodeCount = GetNodeCount;
	this.GetNodeCountAtLevel = GetNodeCountAtLevel;
	this.GetDraw = function(draw, level, islastnode, nodesinlevel, levelsdraw, config)
	{
		var nodedraw = "";
		if(nodesinlevel[level] == null)
			nodesinlevel[level] = 0;
		if(level > 0)
			levelsdraw[level-1] = (!islastnode && this.nodes.length > 0 && this.isExpanded);
		if(draw)
		{
			if(this.nodes.length > 0)
			{
				var image = this.isExpanded ? config.img_collapse : config.img_expand;
				nodedraw += "<a href=\"javascript:clickOn("+level+","+nodesinlevel[level]+",'"+this.varname+"');\">"
					+ "<img alt=\"\" style=\"vertical-align:middle\" src=\""+image+"\" border=\"0\"></a>&nbsp;";
			}
			else
			{
				var image = level > 0 ? config.img_nochilds : config.img_nochilds1;
				nodedraw += "<img alt=\"\" style=\"vertical-align:middle\" src=\""+image+"\" border=\"0\">&nbsp;";
			}
			nodedraw += this.GetDrawItem(config);
			nodedraw += "</div>";
		}
		for(var c=0; c<this.nodes.length; c++)
		{
			if(draw && this.isExpanded)
			{
				nodedraw += "<div>";
				for(var z=0; z<level; z++)
				{
					var image = levelsdraw[z] ? config.img_vertical : config.img_empty;
					nodedraw += "<img alt=\"\" style=\"vertical-align:middle\" src=\""+image+"\" border=\"0\">";
				}
				var image = c == this.nodes.length-1 ? config.img_verhor1 : config.img_verhor;
				nodedraw += "<img alt=\"\" style=\"vertical-align:middle\" src=\""+image+"\" border=\"0\">";
			}
			nodedraw += this.nodes[c].GetDraw(draw && this.isExpanded, level+1, c==this.nodes.length-1, nodesinlevel, levelsdraw, config);
		}
		nodesinlevel[level]++;
		return nodedraw;
	}
	this.GetDrawItem = function(config)
	{
		var itemdraw = "";
		if(this.image != null && this.image != "")
			itemdraw += "<img alt=\"\" style=\"vertical-align:middle\" width=\""+config.icon_width+"\" height=\""+config.icon_height+"\" src=\""+this.image+"\" border=\"0\">&nbsp;";
		if(this.link != null && this.link != "")
			itemdraw += "<a href=\""+this.link+"\"  >"+this.text+"</a>";//linkformat
		else
			itemdraw += this.text;
		return itemdraw;
	}
}

function AddNode(text, link, image)
{
	this.nodes[this.nodes.length] = new TreeNode(text,link,image,this.varname);
}

function GetNodeCount(includeSubTrees)
{
	var count = this.nodes.length;
	if(includeSubTrees)
		for(var c=0; c<this.nodes.length; c++)
			count += this.nodes[c].GetNodeCount(true);
	return count;
}

function GetNodeCountAtLevel(level)
{
	var count = 0;
	if(level == 0)
	{
		count = this.nodes.length;
	}
	else
	{
		for(var c=0; c<this.nodes.length; c++)
			count += this.nodes[c].GetNodeCountAtLevel(level-1);
	}
	return count;
}

function clickOn(level,index,varname)
{
	if(varname == null)
	{
		varname = "TreeObj";
	}
	eval(varname+'.GetNodeAt('+level+','+index+').ChangeState();');
	eval(varname+'.Draw();');
}