var treeNumbers = new Array();
var lastZeroLevelNode = null;
// Node object
function Node(id, pid, type,  open, selected, ls, hc, ai, p, dn ) {
	this.id = id;
	this.pid = pid;
	this.type = type;
	this._io = open;
	this._is = selected;
	this._ls = ls;
	this._hc = hc;
	this._ai = ai;
	this._p = p;
	this._dn = dn;
};

function ge(id) {
	return document.getElementById(id);
}

// Tree object
function dTree(objName, prefixUrl) {
	this.config = {
		styleSelector : "",
		styleClassForFirstLevel : ""
	}

    if("" + prefixUrl == "undefined") {
        prefixUrl = "";
    }
    var imgPrefix = prefixUrl == null || prefixUrl.length == 0 || prefixUrl.lastIndexOf("/") == prefixUrl.length - 1 ? prefixUrl : prefixUrl + "/";

	this.icon = {
//		empty		: imgPrefix + 'e.gif',
//		circle		: imgPrefix + 'c.gif',
//		nlPlus		: imgPrefix + 'nlp.gif',
//		nlMinus		: imgPrefix + 'nlm.gif'
		emptyClass	: 'iconEmpty',
		circleClass	: 'iconCircle',
		nlPlusClass	: 'iconNLPlus',
		nlMinusClass	: 'iconNLMinus'
	};

	this.obj = objName;
	this.aNodes = [];
	this.root = new Node(-1);
	this.completed = true;
};

// Adds a new node to the node array
dTree.prototype.add = function(id, pid, type, open, selected, ls, hc, ai, dn ) {
	this.aNodes[this.aNodes.length] = new Node(id, pid, type, open=="1" , selected=="1" , ls=="1", hc=="1", ai, this.aNodes[pid], dn);
};

// Open/close all nodes
dTree.prototype.openAll = function() {
	this.oAll(true);
};

dTree.prototype.closeAll = function() {
	this.oAll(false);
};

// Returns the selected node
dTree.prototype.getSelected = function() {
	var sn	= null;
	v = ge("cstree");
	if(!v) {
		sn = v.value;
	}
	return (sn) ? sn : null;
};

// Highlights the selected node
dTree.prototype.s = function(id) {
	var tids = window["tids_" + this.getTreeNumber()];
	if (tids[id] && tids[id].indexOf("_")!=-1 ) return;
	var cn = this.aNodes[id];
	if (!this.isSelected(id) && id!=0) { //Root node cannot be selected!
		/* //'turning off' the previous selected node
		if (this.selectedNode || this.selectedNode==0) { 
			eOld = ge("s" + this.obj + this.selectedNode);
			eOld.className = this.config.styleSelector + "node";
		}*/
		eNew = ge("s" + this.obj + id);
		if(eNew && eNew.className.indexOf('reltermnode')>=0 ) { 
			eNew.className = this.config.styleSelector + "nodeSel";
		}
		//this.selectedNode = id;
		var newId = tids[Number(cn.id)];
		v = ge("cstree");
		if(v) {
			value_ = v.value;
			v.value = value_+"."+newId;
		}
	}
};

dTree.prototype.doOpen = function(id) {
    	var cn = this.aNodes[id];
	if(!cn._io) this.o(id);
};

// Toggle Open or close
dTree.prototype.o = function(id) {
	var tids = window["tids_" + this.getTreeNumber()];
	var es = window["es_" + this.getTreeNumber()];
	if ( !ge('d' + this.obj + id) ) return; //if no children - nothing to do
	var cn = this.aNodes[id];
	this.nodeStatus(!cn._io, id, cn._ls);
	cn._io = !cn._io;
	if(statswitch) {
		var term = sStrip(es[id]);
		actnode = cn;
		var fullterm=term;
		while(actnode._p && actnode._p.id) {
			actnode = actnode._p;
			fullterm = es[actnode.id] + "/" + fullterm;
		}
		var rec = ssid+"!RC" + (cn._io ? "E" : "H") + "!"+ encURI(sStrip(fullterm)) +"!"+actTreeOrder()+"!"+this.aNodes[id]._dn+"!"+encURI(sStrip(clustDisplStr))+"!"+encURI(sStrip(swthnstr));
		addStat(rec);
	}
	this.updateSavedValues();
};

// Open or close all nodes
dTree.prototype.oAll = function(status) {
	for (var n=0; n<this.aNodes.length; n++) {
		if (this.aNodes[n]._hc && this.aNodes[n].pid != this.root.id) {
			this.nodeStatus(status, n, this.aNodes[n]._ls)
			this.aNodes[n]._io = status;
		}
	}
	this.updateSavedValues();
};

// Opens the tree to a specific node
dTree.prototype.openTo = function(nId, bSelect, bFirst) {
	if (!bFirst) {
		for (var n=0; n<this.aNodes.length; n++) {
			if (this.aNodes[n].id == nId) {
				nId=n;
				break;
			}
		}
	}

	var cn=this.aNodes[nId];
	if (cn.pid==this.root.id || !cn._p) return;
	cn._io = true;
	cn._is = bSelect;
	if (this.completed && cn._hc) this.nodeStatus(true, cn._ai, cn._ls);
	if (this.completed && bSelect) this.s(cn._ai);
	else if (bSelect) this._sn=cn._ai;
	this.openTo(cn._p._ai, false, true);
};

// Changes the style class of nodes with the given "type"
dTree.prototype.setNodeStyle = function(type_, class_, clasForSelectedNodes_) {
	for (var n=0; n<this.aNodes.length; n++) {
		if (this.aNodes[n].type==type_) {
			obj_ = ge('s'+this.obj+this.aNodes[n].id);
			if(obj_) {
				if( !this.isSelected(this.aNodes[n].id) ) {
					obj_.className=class_;
				} else {
					obj_.className=clasForSelectedNodes_;
				}
			}
		}
                //set opened or close 
                var cn = this.aNodes[n];
                this.nodeStatus(cn._io, n, cn._ls);
	}
};

// Closes all nodes on the same level as certain node
dTree.prototype.closeLevel = function(node) {
	for (var n=0; n<this.aNodes.length; n++) {
		if (this.aNodes[n].pid == node.pid && this.aNodes[n].id != node.id && this.aNodes[n]._hc) {
			this.nodeStatus(false, n, this.aNodes[n]._ls);
			this.aNodes[n]._io = false;
			this.closeAllChildren(this.aNodes[n]);
		}
	}
}

// Closes all children of a node
dTree.prototype.closeAllChildren = function(node) {
	for (var n=0; n<this.aNodes.length; n++) {
		if (this.aNodes[n].pid == node.id && this.aNodes[n]._hc) {
			if (this.aNodes[n]._io) this.nodeStatus(false, n, this.aNodes[n]._ls);
			this.aNodes[n]._io = false;
			this.closeAllChildren(this.aNodes[n]);
		}
	}
}

// Change the status of a node(open or closed)
dTree.prototype.nodeStatus = function(status, id, bottom) {
	eDiv	= ge('d' + this.obj + id);
	eJoin	= ge('j' + this.obj + id);
    eTitle  = ge('div' + this.obj + id);
	if(!eJoin || !eDiv) return;
	//eJoin.src = (status)?this.icon.nlMinus:this.icon.nlPlus;
    eJoin.className = (status)?this.icon.nlMinusClass:this.icon.nlPlusClass;
	eDiv.style.display = (status) ? 'block': 'none';
    if (eTitle){
       eTitle.className = (status) ? 'rtdtree rtdtreeOpen' : 'rtdtree';
    }
};

//  Generates the list of ids of open nodes as a string and saves it as a form parameter
dTree.prototype.updateSavedValues = function() {
	var str = '';
	v = ge("cotree_" + this.getTreeNumber());
	var tids = window["tids_" + this.getTreeNumber()];
	if(v) {
		for (var n=0; n<this.aNodes.length; n++) {
			if (this.aNodes[n]._io && this.aNodes[n].pid != this.root.id) {
				if (str) str += '.';
				str += tids[Number(this.aNodes[n].id)];
			}
		}
	}
	v.value = str;
};


// Checks if a node id is in the list
dTree.prototype.isSelected = function(id) {
	var aSelected = null;
	v = ge("cstree");
	if(!v) return false;
	aSelected = v.value.split('.');
	var id_ = window["tids_" + this.getTreeNumber()][Number(id)];
	for (var n=0; n<aSelected.length; n++)
		if (aSelected[n] == id_) {return true;}
	return false;
};

// Checks if a node id is in the list
dTree.prototype.isOpen = function(id) {
	var tids = window["tids_" + this.getTreeNumber()];
	var aOpen = null;
	v = ge("cotree_" + this.getTreeNumber());
	if(!v) return false;
	aOpen = v.value.split('.');
	var id_ = tids[Number(id)];
	for (var n=0; n<aOpen.length; n++)
		if (aOpen[n] == id_) return true;
	return false;
};

dTree.prototype.getTreeNumber = function() {
	var objNameArray = this.obj.split("_");
	if (objNameArray.length == 3){
		return objNameArray[1];
	}else{
		return "0";
	}
};

function getId(which, treeNumber){
	i=1; 
	var actualTids = window["tids_" + treeNumber];
	while(obj=actualTids[i]) {
		if(obj==which) return i;
		i++;
	}
}
