// supplier of id's and factory for treenodes
var TreeHandler = {
	idTeller : 0,
	idPrefix  : "to-",
	all       : {},
	selected  : null,
	onSelect  : null,
	getId     : function() { return this.idPrefix + this.idTeller++; },
	toggle    : function (oItem) { this.all[oItem.id.replace('-p','')].toggle(); },
	toggleItem  : function (oItem) { this.all[oItem.id.replace('-a','')].toggle();},
	select    : function (oItem) { this.all[oItem.id.replace('-icon','')].select(); },
	insertHTMLBeforeEnd	:	function (oElement, sHTML) {
		if (oElement.insertAdjacentHTML != null) {
			oElement.insertAdjacentHTML("BeforeEnd", sHTML)
			return;
		}
		var df;
		var r = oElement.ownerDocument.createRange();
		r.selectNodeContents(oElement);
		r.collapse(false);
		df = r.createContextualFragment(sHTML);
		oElement.appendChild(df);

	}
};
// configuration
var TreeConfig = {
	iIcon           : '/_images/menu/I.png',
	lIcon           : '/_images/menu/L.png',
	tIcon           : '/_images/menu/T.png',
	lMinusIcon      : '/_images/menu/Lminus.png',
	lPlusIcon       : '/_images/menu/Lplus.png',
	tMinusIcon      : '/_images/menu/Tminus.png',
	tPlusIcon       : '/_images/menu/Tplus.png',
	blankIcon       : '/_images/menu/blank.png'
};

function TreeNode(strLabel, strAction,type) {
	this.childNodes  = [];
	this.text   = strLabel;
	this.action = strAction;
	this.type   = (type==null || type=="")?"":"-"+type;
	this._last  = false;
	this.id     = TreeHandler.getId();
	TreeHandler.all[this.id] = this;
}

TreeNode.prototype.add = function (node, constructTree) {
	//add to my childnodes collection
	node.parentNode = this;
	this.childNodes[this.childNodes.length] = node;
	var root = this;
	if (this.childNodes.length >=2) {
		this.childNodes[this.childNodes.length -2]._last = false;
	}
	while (root.parentNode) { root = root.parentNode; }
	if (root.rendered) {
		if (this.childNodes.length >= 2) {
			document.getElementById(this.childNodes[this.childNodes.length -2].id + '-p').src = ((this.childNodes[this.childNodes.length -2].folder)?((this.childNodes[this.childNodes.length -2].open)?TreeConfig.tMinusIcon:TreeConfig.tPlusIcon):TreeConfig.tIcon);
			if (this.childNodes[this.childNodes.length -2].folder) {
				this.childNodes[this.childNodes.length -2].plusIcon = TreeConfig.tPlusIcon;
				this.childNodes[this.childNodes.length -2].minusIcon = TreeConfig.tMinusIcon;
			}
			this.childNodes[this.childNodes.length -2]._last = false;
		}
		this._last = true;
		var tempNode = this;
		while (tempNode.parentNode) {
			for (var i = 0; i < tempNode.parentNode.childNodes.length; i++) {
				if (tempNode.id == tempNode.parentNode.childNodes[i].id) { break; }
			}

			if (++i == tempNode.parentNode.childNodes.length) { tempNode.parentNode._last = true; }
			else { tempNode.parentNode._last = false; }
			tempNode = tempNode.parentNode;
		}
		TreeHandler.insertHTMLBeforeEnd(document.getElementById(this.id + '-c'), node.toString());
		if ((!this.folder) && (!this.openIcon)) {
			this.icon = TreeConfig.folderIcon;
			this.openIcon = TreeConfig.openFolderIcon;
		}
		if (!this.folder) { this.folder = true; this.collapse(true); }
		if (!constructTree) { this.indent(); }
	}
	return node;
}

TreeNode.prototype.toggle = function() {
	if (this.folder) {
		if (this.open) { this.collapse(); }
		else { this.expand(); }
}	}

TreeNode.prototype.select = function() {
	if(document.getElementById(this.id).className=="hv-rootitem"+this.type)
		document.getElementById(this.id+'-a').className = 'hv-rootitem'+this.type+'-selected';
	else
		document.getElementById(this.id+'-a').className = 'hv-item'+this.type+'-selected';
	//document.getElementById(this.id + '-a').scrollIntoView();
}
TreeNode.prototype.deSelect = function() {
	document.getElementById(this.id + '-a').className = '';
	TreeHandler.selected = null;
}

TreeNode.prototype.focus = function() {
	if ((TreeHandler.selected) && (TreeHandler.selected != this)) { TreeHandler.selected.deSelect(); }
	TreeHandler.selected = this;
	document.getElementById(this.id + '-a').focus();
	if (TreeHandler.onSelect) { TreeHandler.onSelect(this); }
}

TreeNode.prototype.doExpand = function() {
	if (this.childNodes.length) {document.getElementById(this.id + '-c').style.display = 'block'; }
	this.open = true;
}

TreeNode.prototype.doCollapse = function() {
	if (this.childNodes.length) { document.getElementById(this.id + '-c').style.display = 'none'; }
	this.open = false;
}

TreeNode.prototype.expandAll = function() {
	this.expandChildren();
	if ((this.folder) && (!this.open)) { this.expand(); }
}

TreeNode.prototype.expandChildren = function() {
	for (var i = 0; i < this.childNodes.length; i++) {
		this.childNodes[i].expandAll();
    }
}

TreeNode.prototype.collapseAll = function() {
	this.collapseChildren();
	if ((this.folder) && (this.open)) { this.collapse(true); }
}

TreeNode.prototype.collapseChildren = function() {
	for (var i = 0; i < this.childNodes.length; i++) {
		this.childNodes[i].collapseAll();
    }
}

TreeNode.prototype.indent = function(lvl, del, last, level, nodesLeft) {
	if (lvl == null) { lvl = -2; }
	var state = 0;
	for (var i = this.childNodes.length - 1; i >= 0 ; i--) {
		state = this.childNodes[i].indent(lvl + 1, del, last, level);
		if (state) { return; }
	}
	if (del) {
		if ((level >= this._level) && (document.getElementById(this.id + '-p'))) {
			if (this.folder) {
				document.getElementById(this.id + '-p').src = (this.open)?TreeConfig.lMinusIcon:TreeConfig.lPlusIcon;
				this.plusIcon = Config.lPlusIcon;
				this.minusIcon = Config.lMinusIcon;
			}
			else if (nodesLeft) { document.getElementById(this.id + '-p').src = TreeConfig.lIcon; }
			return 1;
	}	}
	var tempNode = document.getElementById(this.id + '-i-' + lvl);
	if (tempNode) {
		if ((tempNode._last) || ((del) && (last))) { tempNode.src =  TreeConfig.blankIcon; }
		else { tempNode.src =  TreeConfig.iIcon; }
	}
	return 0;
}

function Tree(strLabel, strAction,type) {

	this.base = TreeNode;
	this.base(strLabel, strAction,type);
	this.open  = true;
	this.folder    = true;
	this.rendered  = false;
	this.onSelect  = null;
	this.isTree = true;
}

Tree.prototype= new TreeNode;

Tree.prototype.getSelected = function() {
	if (TreeHandler.selected) { return TreeHandler.selected; }
	else { return null; }
}

Tree.prototype.expand = function() {
	this.doExpand();
}

Tree.prototype.collapse = function(b) {
	if (!b) { this.focus(); }
	this.doCollapse();
}

Tree.prototype.getFirst = function() {
	return null;
}

Tree.prototype.getLast = function() {
	return null;
}

Tree.prototype.getNextSibling = function() {
	return null;
}

Tree.prototype.getPreviousSibling = function() {
	return null;
}

Tree.prototype.toString = function() {
	var str=""
	for (var i = 0; i < this.childNodes.length; i++) {

		str += this.childNodes[i].toString(i, this.childNodes.length);
	}
	this.rendered = true;
	return str;
};

function TreeItem(strLabel, strAction, type) {
	this.base = TreeNode;
	this.base(strLabel, strAction,type);
	this.open = false;
	//if (eParent) { eParent.add(this); }
	this.isTree=false;
}

TreeItem.prototype = new TreeNode;

TreeItem.prototype.expand = function() {
	this.doExpand();
	if(this.childNodes.length>0)document.getElementById(this.id + '-p').src = this.minusIcon;
}

TreeItem.prototype.collapse = function(b) {
	if (!b) { this.focus(); }
	this.doCollapse();
	document.getElementById(this.id + '-p').src = this.plusIcon;
}

TreeItem.prototype.getFirst = function() {
	return this.childNodes[0];
}

TreeItem.prototype.getLast = function() {
	if (this.childNodes[this.childNodes.length - 1].open) { return this.childNodes[this.childNodes.length - 1].getLast(); }
	else { return this.childNodes[this.childNodes.length - 1]; }
}

TreeItem.prototype.getNextSibling = function() {
	for (var i = 0; i < this.parentNode.childNodes.length; i++) {
		if (this == this.parentNode.childNodes[i]) { break; }
	}
	if (++i == this.parentNode.childNodes.length) { return this.parentNode.getNextSibling(); }
	else { return this.parentNode.childNodes[i]; }
}

TreeItem.prototype.getPreviousSibling = function(b) {
	for (var i = 0; i < this.parentNode.childNodes.length; i++) {
		if (this == this.parentNode.childNodes[i]) { break; }
	}
	if (i == 0) { return this.parentNode; }
	else {
		if ((this.parentNode.childNodes[--i].open) || (b && this.parentNode.childNodes[i].folder)) { return this.parentNode.childNodes[i].getLast(); }
		else { return this.parentNode.childNodes[i]; }
    }
}

TreeItem.prototype.toString = function (nItem, nItemCount) {
	var tempNode = this.parentNode;
	var strRoot="item";
	if (tempNode.isTree) {strRoot="rootitem";}
	var indent = '';
	// voor eerste lijntje tree moet "" zijn
	if (nItem + 1 == nItemCount && this.parentNode.text!="") { this.parentNode._last = true; }
	var i = 0;
	while (tempNode.parentNode) {
		tempNode = tempNode.parentNode;
		indent = "<img id=\"" + this.id + "-i-" + i + "\" src=\"" + ((tempNode._last)?TreeConfig.blankIcon:TreeConfig.iIcon) + "\">" + indent;
		i++;
	}
	this._level = i;
	if (this.childNodes.length) { this.folder = 1; }
	else { this.open = false; }
	var label = this.text.replace(/</g, '&lt;').replace(/>/g, '&gt;');
	//alert(this.text+" class=" + strRoot);
	var str = "<div id=\"" + this.id + "\" class=\"hv-"+strRoot+this.type+"\">";
	str += indent;
	str += "<img id=\"" + this.id + "-p\" src=\"" + ((this.folder)?((this.open)?((this.parentNode._last)?TreeConfig.lMinusIcon:TreeConfig.tMinusIcon):((this.parentNode._last)?TreeConfig.lPlusIcon:TreeConfig.tPlusIcon)):((this.parentNode._last)?TreeConfig.lIcon:TreeConfig.tIcon)) + "\" onclick=\"TreeHandler.toggle(this);\">"
	//if childs toggle
	if(this.folder==1) {
        str += "<a target=\"_top\" href=\""+this.action+"\" id=\"" + this.id + "-a\">" + label + "</a></div>";
	}else
		str += "<a target=\"_top\" href=\"" + this.action + "\" id=\"" + this.id + "-a\">" + label + "</a></div>";
	str += "<div id=\"" + this.id + "-c\" class=\"hv-container\" style=\"display: " + ((this.open)?'block':'none') + ";\">";
	for (var i = 0; i < this.childNodes.length; i++) str += this.childNodes[i].toString(i,this.childNodes.length);
	str += "</div>";
	this.plusIcon = ((this.parentNode._last)?TreeConfig.lPlusIcon:TreeConfig.tPlusIcon);
	this.minusIcon = ((this.parentNode._last)?TreeConfig.lMinusIcon:TreeConfig.tMinusIcon);
	return str;
}
