﻿	
	
	

	
	
	function addNode(parent, textval, primaryKey) {
		var i;
		var tempnode;
		var nodelist = this.nodelist;		//'This' refer to the tree object!
				
		i = nodelist.length;
		
		nodelist[i] = new nodeStruct;
		
		nodelist[i].index = i;
		nodelist[i].trid = this.name + "_" + i;
		nodelist[i].imgOnClick = "onclick='" + this.name + ".expand("+i+")'";
		nodelist[i].nodeOnClick = "onclick='" + this.name+".onTreeNodeClick("+i+", event)'";

		if (primaryKey)
			nodelist[i].primaryKey = primaryKey;
		
		nodelist[i].parent = parent;
		if (nodelist[parent])
			nodelist[i].parentKey = nodelist[parent].primaryKey;
		
		nodelist[i].text = trim(textval);
		nodelist[i].fetched = !this.needFetch;


		//not root node						
		if (i > 0) {
			//the node's parent has no any child
			if (nodelist[parent].child == -1) {
				nodelist[parent].child = i;
				nodelist[parent].last = i;
			//the node's parent has child
			} else {
				//get the curr parent' last child
				tempnode = nodelist[nodelist[parent].last];
				//set the old last's sibling
				tempnode.sibling = i;
				//set the new last
				nodelist[parent].last = i;
			}	
		}
	}
	
	function addNodeByPrimaryKey(primaryKey, parentKey, textval) {
		for (var j = 0;j < this.nodelist.length; j++) {
			if (this.nodelist[j] && this.nodelist[j].primaryKey == parentKey) {
				this.addNode(j, textval, primaryKey)
				break;
			}
		}	
	}
	
	
	
	function nodeStruct() {
		this.index = 0;
		this.parent = -1;
		this.primaryKey = "";
		this.parentKey = "";		
		this.sibling = -1;				//sibling index; -1 
		this.last = -1				// the last child
		this.child = -1;				// -1 represent no child;
		this.trid = "";
		this.imgOnClick = "";
		this.nodeOnClick = "";
		this.text = "";
		this.folded = true;
		this.fetched = true;		
	}
	
	function tree(name, contain, needFetch){
		this.nodelist=new Array();
		this.name = name;
		this.contain = contain;
		if (needFetch)
			this.needFetch = needFetch;
		else
			this.needFetch = false;
		
		this.selected = -1;
		
		
		//function
		this.addNode=addNode;
		this.addNodeByPrimaryKey=addNodeByPrimaryKey;
		this.addNodeByPrimaryKeyFromChild=addNodeByPrimaryKeyFromChild;
		this.write=write;
		this.expandNode=expandNode;
		this.expandNodeByPrimaryKey=expandNodeByPrimaryKey;
		this.expand=expand;
		this.saveOrUpdateNode=saveOrUpdateNode;
		this.saveOrUpdateNodeByPrimaryKey=saveOrUpdateNodeByPrimaryKey;
		this.deleteNode=deleteNode;
		this.deleteNodeByPrimaryKey=deleteNodeByPrimaryKey;
		this.moveUpNode=moveUpNode;
		this.moveUpNodeByPrimaryKey=moveUpNodeByPrimaryKey;
		this.moveDownNode=moveDownNode;
		this.moveDownNodeByPrimaryKey=moveDownNodeByPrimaryKey;
		this.moveNode=moveNode;
		this.moveNodeByPrimaryKey=moveNodeByPrimaryKey;
		this.fetchTreeData = fetchTreeData;
		this.onTreeNodeClick = onTreeNodeClick;		
		this.onLoad = onLoad;
		this.onUnLoad = onUnLoad;
		
		//this.addNode(-1, "root", "##_root_##");
		//this.nodelist[0].fetched=true;		
		
	}
	

	function globalVars(imagedir){

		// Sets the global variables for the script. 
		// These may be changed to quickly customize the tree's apperance

		//Imgages
		this.imagedir=imagedir;
						
		this.plusImg = this.imagedir + "plus.gif";
		this.plusdownImg = this.imagedir + "plusdown.gif";
		this.plusupImg = this.imagedir + "plusup.gif";
		
		this.singleupImg = this.imagedir  + "singleup.gif";
		this.singledownImg = this.imagedir  + "singledown.gif";
				
		this.minusImg = this.imagedir  + "minus.gif";
		this.minusupImg = this.imagedir  + "minusup.gif";
		this.minusdownImg = this.imagedir  + "minusdown.gif";
		
		this.blankImg = this.imagedir + "blank.gif";
		this.blankupImg = this.imagedir + "blankup.gif";
		this.blankdownImg = this.imagedir + "blankdown.gif";
		
		this.emptyImg = this.imagedir + "empty.gif";
		this.emptyImgNode = "<IMG SRC='" + this.emptyImg + "' WIDTH=16 HEIGHT=18 Border=0>";
		this.lineImg = this.imagedir + "line.gif";
		this.lineImgNode = "<IMG SRC='" + this.lineImg + "' WIDTH=16 HEIGHT=18 Border=0>";
	}



	function expand(TableID){
		var tempnode=this.nodelist[TableID];
		var nowimg;
		var SvId;
		
		if (this.needFetch && !tempnode.fetched) {
			this.fetchTreeData(TableID);
			tempnode.fetched = true;
		}
		
		tempnode.folded = !tempnode.folded;
		
		if(tempnode.folded==false) {
			if(tempnode.child!=-1) {			//has child
				if(tempnode.index==0)			//first one!
					if(tempnode.sibling==-1)
						nowimg=gVars.singledownImg;
					else
						nowimg=gVars.minusupImg;
				else
					if(tempnode.sibling==-1)			//last one!
						nowimg=gVars.minusdownImg;
					else
						nowimg=gVars.minusImg;			 
				if(tempnode.index!=0) { 	  
					document.getElementById(tempnode.trid).style.display = "";		//To display		  	  
					document.getElementById("img_" + tempnode.trid).src = nowimg;	 
				}						 
			}		
		} else {
			if(tempnode.child!=-1) {
				if(tempnode.index==0)			//first one!
					if(tempnode.sibling==-1)
						nowimg=gVars.singleupImg;
					else
						nowimg=gVars.plusupImg;
				else
					if(tempnode.sibling==-1)			//last one!
						nowimg=gVars.plusdownImg;
					else
						nowimg=gVars.plusImg;
				document.getElementById(tempnode.trid).style.display = "none";		//To hide	  
				document.getElementById("img_" + tempnode.trid).src = nowimg;		//Can't put at the bottom Coz the nowimg can be empty!
			}
		}
  }

  function write() {
  
  	for (var i = 0; i < this.nodelist.length;i ++) {
		if (this.nodelist[i])
			this.nodelist[i].folded = true;
	}
	this.onUnLoad();
	
	
	if (this.nodelist.length > 1) {
		var html = new StringBuffer(1000);
		writelevel(this.nodelist[this.nodelist[0].child], 1, this, this.name, this.needFetch, html);	
	 	
	 	this.contain.innerHTML = "";	
		this.contain.innerHTML = html.toString();
	}
		
	this.onLoad();

  }

  function writelevel(tempnode, level, treeNodes, treeNodesName, needFetch, html){
	var endsibling;
	var nowimg, i, j, temp;
	var nodelist = treeNodes.nodelist;
	
	html.append("<TABLE CELLPADDING=0 CELLSPACING=0>");
	
	do{
		if(tempnode.child==-1) {
		  if(tempnode.index==0) {			//first one!
			 if (needFetch && !tempnode.fetched)
			 	nowimg=gVars.plusupImg;
			 else
			 	nowimg=gVars.blankupImg;
		  } else {
		    if(tempnode.sibling==-1) {			//last one!
		    	if (needFetch && !tempnode.fetched)
		  	  		nowimg=gVars.plusdownImg;
		  	  	else
		  	  		nowimg=gVars.blankdownImg;
            } else {
            	if (needFetch && !tempnode.fetched)
			  	  	nowimg=gVars.plusImg;
			  	else
			  		nowimg=gVars.blankImg;
			}
		  }
		} else
		  if(tempnode.index==0)			//first one!
   		   if(tempnode.sibling=-1)		//Only one
		     nowimg=gVars.singleupImg;
		   else 
			 nowimg=gVars.plusupImg;
		  else
		    if(tempnode.sibling==-1)			//last one!
		  	  nowimg=gVars.plusdownImg;
            else
		  	  nowimg=gVars.plusImg;
		
		html.append("<TR><TD NOWRAP>");
		for(i=1;i<level;i++)
		{
		  temp = tempnode;	
		  for(j=0;j<level-i-1;j++)
			temp = nodelist[temp.parent];
			
		  if(nodelist[temp.parent].sibling!=-1)		
			html.append(gVars.lineImgNode);
		  else
			html.append(gVars.emptyImgNode);
		}

		html.append("<IMG ID='img_" + tempnode.trid + "' SRC='" + nowimg + "' "+ tempnode.imgOnClick +" WIDTH=16 HEIGHT=18 Border=0 style='cursor:hand'>");
		html.append("</TD><TD WIDTH='100%' NOWRAP ID='td_" + tempnode.trid + "' " + tempnode.nodeOnClick + ">");

		if (tempnode.text) {	
			html.append(tempnode.text);
		}
		
		html.append("</TD></TR>");
	    
	    if(tempnode.child != -1) {
	    	//有儿子,那么该节点被fetch过了
	    	tempnode.fetched = true;
			html.append("<TR ID=" + tempnode.trid +" style='display:none'><TD COLSPAN=2 NOWRAP>");
			writelevel(nodelist[tempnode.child],level+1,treeNodes,treeNodesName,needFetch,html);
			html.append("</TD></TR>");
		}	
	    
		endsibling = tempnode.sibling;
		tempnode = nodelist[tempnode.sibling];

	} while (endsibling != -1);
	
	html.append("</TABLE>");
  }
  
	function expandNode(TableID) {	
		var tempTableObj = document.getElementById(this.name + "_"+ TableID.toString());
		if (TableID == 0) return;
		if (tempTableObj)
			this.expand(TableID);
		var tempnode = this.nodelist[TableID];
		this.expandNode(tempnode.parent);
	}
	
	function expandNodeByPrimaryKey(primaryKey) {		
		for (j = 0;j < this.nodelist.length; j++) {
			if (this.nodelist[j] && this.nodelist[j].primaryKey == primaryKey) {
				this.expandNode(j);
				break;
			}
		}
	}
	
	
	//在某个子节点下增加一个新节点
	function addNodeByPrimaryKeyFromChild(primaryKey, text, childKey) {
		var parent = -1, child = -1;
		for (var j = 0;j < this.nodelist.length; j++) {
			if (this.nodelist[j] && this.nodelist[j].primaryKey == childKey) {
				child = j;
				break;
			}
		}		
		
		//同级存在
		if (this.nodelist[child]) {
			//共同的父亲
			parent = this.nodelist[child].parent;
			this.addNode(parent, text, primaryKey);
			//当前新增的节点
			temp = this.nodelist[this.nodelist.length - 1];
			//上移新增的节点			
			while (this.nodelist[child].sibling != temp.index) {
				this.moveUpNode(temp.index);
			}
		} else {
			return;
		}
		
		this.write();
		this.expandNode(parent);
	}
	
	function saveOrUpdateNode(index, text, parent, primaryKey) {
		if (this.nodelist[index]) {
			this.nodelist[index].text = text;
			parent = this.nodelist[index].parent;
		} else if (parent) {
			this.addNode(parent, text, primaryKey);
		} else {
			return;
		}
				
		this.write();
		this.expandNode(parent);
	}
	
	function saveOrUpdateNodeByPrimaryKey(primaryKey, text, parentKey) {
		var parent = -2;
		for (var j = 0;j < this.nodelist.length; j++) {
			if (this.nodelist[j] && this.nodelist[j].primaryKey == primaryKey) {
				this.saveOrUpdateNode(j, text, this.nodelist[j].parent, primaryKey);
				return;
			} else if (this.nodelist[j] && this.nodelist[j].primaryKey == parentKey) {
				parent = j;
			}
		}
		
		if (parentKey && parent != -2) {
			this.saveOrUpdateNode(-1, text, parent, primaryKey);
		}
	}
	
	//移动树上的某个节点到新的父节点下	
	function moveNode(index, parent) {
		if (this.nodelist[index] && this.nodelist[parent]) {
			//从以前节点下移去
			//not the first node
			if (this.nodelist[this.nodelist[index].parent].child != index) {
				//the parent node
				temp = this.nodelist[this.nodelist[this.nodelist[index].parent].child];	
				//find the index node's pre node
				while (temp.sibling != index)
					temp = this.nodelist[temp.sibling];
				//set the temp node's sibling is the index nodes' sibling
				temp.sibling = this.nodelist[index].sibling;
				//if index node is the last node
				if (temp.sibling == -1) {
					this.nodelist[this.nodelist[index].parent].last = temp.index;
				}
			//is the first node
			} else {
				//set the parent's child is the index node's sibling
				this.nodelist[this.nodelist[index].parent].child = this.nodelist[index].sibling;
				//if index node is the last node
				if (this.nodelist[index].sibling == -1) {
					this.nodelist[this.nodelist[index].parent].last = -1
				}
			}
			
			
			//加入新的父亲下
			this.nodelist[index].sibling = -1;
			this.nodelist[index].parent = parent;
			//parent's has child
			if (this.nodelist[parent].child != -1) {
				this.nodelist[this.nodelist[parent].last].sibling = index;
				this.nodelist[parent].last = index;
			} else {
				this.nodelist[parent].child = index;
				this.nodelist[parent].last = index;
			}
		} else {
			return;
		}
		
		this.write();
		this.expandNode(parent);
	}
	
	//移动树上的某个节点到新的父节点下
	//通过主键来移动
	function moveNodeByPrimaryKey(primaryKey, parentKey) {
		var hasFound = 0;
		var index = -1, parent = -1;
		for (var j = 0;j < this.nodelist.length; j++) {
			if (this.nodelist[j] && this.nodelist[j].primaryKey == primaryKey) {
				index = j;
				hasFound++;
			} else if (this.nodelist[j] && this.nodelist[j].primaryKey == parentKey) {
				parent = j;
				hasFound++;
			}
			if (hasFound == 2) break;
		}		
		if (index != -1 && parent != -1)
			this.moveNode(index, parent);
	}
	
	//上移某个节点
	function moveUpNode(index) {
		if (this.nodelist[index]) {
			//not the first node
			if (this.nodelist[this.nodelist[index].parent].child != index) {
				//the parent node
				var temp = this.nodelist[this.nodelist[this.nodelist[index].parent].child];	
				//find the index node's pre node
				while (temp.sibling != index)
					temp = this.nodelist[temp.sibling];
				//if the temp is not first	
				if (this.nodelist[this.nodelist[index].parent].child != temp.index) {
					//find the up node's up node
					var temp1 = this.nodelist[this.nodelist[this.nodelist[index].parent].child];
					while (temp1.sibling != temp.index)
						temp1 = this.nodelist[temp1.sibling];
					
					temp.sibling = this.nodelist[index].sibling;
					this.nodelist[index].sibling = temp.index;
					temp1.sibling = index;
						
				//temp is the first
				} else {
					temp.sibling = this.nodelist[index].sibling;
					this.nodelist[index].sibling = temp.index;
					this.nodelist[this.nodelist[index].parent].child = index;
				}
				//if index is the last
				if (this.nodelist[this.nodelist[index].parent].last == index)
					this.nodelist[this.nodelist[index].parent].last = temp.index;
					
			//first node		
			} else {
				return;
			}				
		} else {
			return;
		}

		this.write();
		this.expandNode(this.nodelist[index].parent);
	}
	
	//用主键上移某个节点
	function moveUpNodeByPrimaryKey(primaryKey) {
		var index = -1;
		for (var j = 0;j < this.nodelist.length; j++) {
			if (this.nodelist[j] && this.nodelist[j].primaryKey == primaryKey) {
				index = j;
				break;
			}
		}
		if (index != -1)
			this.moveUpNode(index);
	}
	
	//下移某个节点
	function moveDownNode(index) {
		if (this.nodelist[index]) {
			//is not the tail node
			if (this.nodelist[index].sibling != -1) {
				temp = this.nodelist[this.nodelist[index].sibling];
				//not the first node
				if (this.nodelist[this.nodelist[index].parent].child != index) {
					var temp1 = this.nodelist[this.nodelist[this.nodelist[index].parent].child];
					while (temp1.sibling != index)
						temp1 = this.nodelist[temp1.sibling];
					
					this.nodelist[index].sibling = temp.sibling;
					temp.sibling = index;
					temp1.sibling = temp.index;
					
				//first node
				} else {
					this.nodelist[index].sibling = temp.sibling;
					temp.sibling = index;
					this.nodelist[this.nodelist[index].parent].child = temp.index;
				}
				
				//temp is the last
				if (this.nodelist[this.nodelist[index].parent].last == temp.index)
					this.nodelist[this.nodelist[index].parent].last = index;
			} else {
				return;
			}
		} else {
			return;
		}
				
		this.write();
		this.expandNode(this.nodelist[index].parent);
	}
	
	//下移某个节点通过主键完成
	function moveDownNodeByPrimaryKey(primaryKey) {
		var index = -1;
		for (var j = 0;j < this.nodelist.length; j++) {
			if (this.nodelist[j] && this.nodelist[j].primaryKey == primaryKey) {
				index = j;
				break;
			}
		}
		if (index != -1)
			this.moveDownNode(index);
	
	}

	function deleteNode(index) {		
		
		if (this.nodelist[index]) {
			//not the first node
			if (this.nodelist[this.nodelist[index].parent].child != index) {
				//the parent node
				temp = this.nodelist[this.nodelist[this.nodelist[index].parent].child];	
				//find the index node's pre node
				while (temp.sibling != index)
					temp = this.nodelist[temp.sibling];
				//set the temp node's sibling is the index nodes' sibling
				temp.sibling = this.nodelist[index].sibling;
				//if index node is the last node
				if (temp.sibling == -1) {
					this.nodelist[this.nodelist[index].parent].last = temp.index;
				}
			//is the first node
			} else {
				//set the parent's child is the index node's sibling
				this.nodelist[this.nodelist[index].parent].child = this.nodelist[index].sibling;
				//if index node is the last node
				if (this.nodelist[index].sibling == -1) {
					this.nodelist[this.nodelist[index].parent].last = -1
				}
			}
			var parent = this.nodelist[index].parent;
			//delete the index node
			this.nodelist[index] = this.nodelist[-1];
		}
						
		this.write();
		this.expandNode(parent);
	}
	
	function deleteNodeByPrimaryKey(primaryKey) {
		for (var j = 0;j < this.nodelist.length; j++) {
			if (this.nodelist[j] && this.nodelist[j].primaryKey == primaryKey) {
				this.deleteNode(j);
				return;
			}
		}
	}
	
	function onTreeNodeClick(index, event) {
		if (typeof this.onfocus == "function") {
			this.onfocus(document.getElementById("td_"+this.name+"_"+index), 
						 document.getElementById("td_"+this.name+"_"+this.selected),
						 event,
						 index);
		}
			
		if (typeof this.onclick == "function")
			this.onclick(document.getElementById("td_"+this.name+"_"+index), 
						 event,
						 index);
					
	}
	
	function onUnLoad() {
		if (typeof this.onunload == "function") {
			this.onunload();
		}
	}
	
	function onLoad() {	
		if (typeof this.onload == "function") {
			this.onload();
		}
		
		if (typeof this.refresh == "function") {
			this.refresh();
		}
	}
	
	function fetchTreeData(index) {
		frmObj = document.getElementsByName("iFrameTree_" + this.name)[0];
		src = frmObj.src;
		start = src.indexOf("globe.tree.parent");		
		if (start != -1) {
			end = src.indexOf("&", start);
			end = (end==-1)?"":src.substring(end);
			src = src.substring(0, start+18) + this.nodelist[index].primaryKey + end;
						
		} else {
			src += "&globe.tree.parent=" + this.nodelist[index].primaryKey;
		}
		frmObj.src = src;
	}
 
	var gVars=new globalVars(appName + "/images/");	
