var leaf_img="";   //叶节点图片
var branch_close_img=""; //分支关闭时的图片
var branch_open_img="";  //分支打开时的图片
var indent=10;  //左边缩进,默认值20px
var lastSelected=null; //指向当前选择的LI元素,可以通过它来访问树中下一个节点

//============================ 以下是初始化部分 ==================================

function init() //初始化
{   if (document.all.tree==null) return; 
	var coll = document.all.tree.children.tags("UL");
	var s="";
	if (coll!=null)
	   for (var i=0;i<coll.length;i++)
		{
			s+="<ul>"+initUL(coll[i])+"</ul>";	
		}
	document.all.tree.innerHTML=s; //画出目录树
}

function initUL(r)  //初始化UL tag,返回修改后的r的innerHTML
{   
	var sn="";
	var cli=r.children.tags("LI");
	if (cli!=null)
		for (var i=0;i<cli.length;i++)
			sn+=initLI(cli[i]);				  
   return sn;
}


function initLI(r)  //初始化LI tag,返回修改后的r的outerHTML
{		    
  var si=r.innerHTML;
  var p=si.length;  
  var sn="";
  var leaf=true;
  var cul=r.children.tags("UL");
  if (cul!=null&&cul.length>0)  //如果r有子表
  {	  p=si.indexOf("<UL>");      //找到子表的起始位置p
  	  leaf=false;            //r不是树叶
	  for (var i=0;i<cul.length;i++)
	  	sn+="<ul style='display: none; margin-left:"+indent+";'>"+initUL(cul[i])+"</ul>";	  		
  }  
  var oimg=(r.open_img!=null)? r.open_img:branch_open_img;
  var cimg=(r.close_img!=null)? r.close_img:branch_close_img;
  var limg=(r.leaf_img!=null)? r.leaf_img:leaf_img;	
  var imgstr="";
  if (leaf) imgstr="<img leaf_img='"+limg+"' src='"+limg+"'>";  
	else imgstr="<img open_img='"+oimg+"' close_img='"+cimg+"' src='"+cimg+"'>";
  sn="<li class='"+((leaf)? "leaf":"branch")+"' style='list-style-type:none'>"+
	  "<span status='closed' onMouseOver='doclick(this)' style='Cursor:hand;'>"+
      imgstr+
	  " <span class='unselected'>"+
  	  si.substring(0,p)+
	  "</span>"+
	  "</span>"+
	  sn+
	  "</li>";  
  return sn;  	
}

//============================ 以上是初始化部分 ==================================


//====================== 以下函数响应鼠标单击事件 =================================

function doclick(r)  //响应鼠标单击事件,r是一个span元素
{  
   if (r.parentElement.className=="branch") //如果选择的是树枝（r的parentElement是一个LI元素）
   {
	 //alert(r.status);
	 if (r.status=="closed") r.status="opened"; else r.status="closed"; //改变节点r的状态标记
	// alert(r.status);
	 var cul=r.parentElement.children.tags("UL"); 
	 if (cul!=null)	 
		 for (var i=0;i<cul.length;i++)
			if (r.status=="closed")  cul[i].style.display="none"; else cul[i].style.display="block";
	 var mm=r.children[0]; //r一共有两个儿子元素，第一个为IMG元素，mm指向r的第一个儿子图片
	 if (r.status=="closed") mm.src=mm.close_img; else mm.src=mm.open_img; //切换图片	 
   }   
   if (lastSelected!=null) lastSelected.children[0].children[1].className="unselected";  //改变上一次选择的节点的外观
   r.children[1].className="selected";  //改变当前选择的节点的外观，r.children[1]是一个SPAN元素
   //注意，上面两句次序不能颠倒
   lastSelected=r.parentElement;  //改变当前选择的节点
}

//====================== 以上函数响应鼠标单击事件 =================================



//======================== 以下函数根据绝对URL在树中定位 ==========================

function locate(s)  //根据url=s 定位，s必须是绝对地址，返回所找到的LI节点,但是不做任何事
{	
 if (document.all.tree==null) return;  
 var coll = document.all.tree.children.tags("UL");
 var e;

	if (coll!=null)
	   for (var i=0;i<coll.length;i++)
	   {
	    e=FindInUL(coll[i],s);  //在每棵子树中找；
	   	if (e!=null) return(e); 
	   	} 
	return(null);
}

function FindInUL(r,s)  //在UL tag r中定位s
{    
	var cli=r.children.tags("LI");
	var e;
	if (cli!=null&&cli.length>0)
		for (var i=0;i<cli.length;i++)
		 {  		 	
		 	e=FindInLI(cli[i],s);
			if (e!=null) return(e);
		}	
   return(null);  
}

function FindInLI(r,s) //在LI tag r中定位s
{
	var lnk=GetLink(r); //返回LI节点r里面的第一个A元素
	if (lnk!=null&&lnk.href==s) 
	 {  
		//LocateNode(r);  //定位节点r		
	 	return(r);
	 }	
	var cul=r.children.tags("UL");
	var e;
	if (cul!=null&&cul.length>0) 
		for (var i=0;i<cul.length;i++)
		{
			e=FindInUL(cul[i],s);
 			if (e!=null) return(e);		
		}		
	return(null);
}

//======================== 以上函数根据绝对URL在树中定位 ==========================

function GetLink(e)  //e是一个LI元素，返回e里面的第一个A元素
{
	if (e==null) return(null);
	var lnk=e.children[0].children[1].children.tags("A");
	if (lnk==null||lnk.length==0) return(null);	else return(lnk[0]);
}

function select(e) //选择节点e，e 必须是一个LI元素,将e的父辈目录全部打开，e如果是目录也将其打开
{	  
   if (e==null) return;
   if (lastSelected!=null) lastSelected.children[0].children[1].className="unselected";  //改变上一次选择的节点的外观
   e.children[0].children[1].className="selected";  //改变当前选择的节点的外观，e.children[0].children[1]是一个SPAN元素
   //注意，上面两句次序不能颠倒
   lastSelected=e;  //改变当前选择的节点
   if (e.className=="branch")  //如果e是树枝
   {
	   e.children[0].status="opened";
	   var mm=e.children[0].children[0];  //切换图片
	   mm.src=mm.open_img;
	   var cul=e.children.tags("UL");
	   if (cul!=null)	   
		  for (var i=0;i<cul.length;i++)
			cul[i].style.display="block";	   
   }
}



//===================== 以下函数根据节点r(一个LI元素)在树中定位 ====================

function LocateNode(r) //定位节点r,成功则返回true，否则返回false
{
	if (document.all.tree==null) return; 
	var coll = document.all.tree.children.tags("UL");
	if (coll!=null)
	   for (var i=0;i<coll.length;i++)
			if (FindNodeInUL(coll[i],r)) return(true);//在每棵子树中找节点r；	   	
	return(false);
}

function FindNodeInUL(t,r)  //在UL tag t中定位节点r
{   
	var cli=t.children.tags("LI");
	if (cli!=null&&cli.length>0)
		for (var i=0;i<cli.length;i++)
		 {  		 	
		 	if (FindNodeInLI(cli[i],r))
			{
			    t.style.display="block";  //改变t的可视性
			    return(true);
			}
		}	
   return(false);  
}

function FindNodeInLI(t,r) //在LI tag t中定位节点r
{	
	if (t==r) 
	 {
	 	select(t);  //选中LI节点t
	 	return(true);
	 }	
	var cul=t.children.tags("UL");
	if (cul!=null&&cul.length>0) 
		for (var i=0;i<cul.length;i++)
		{
			if (FindNodeInUL(cul[i],r))
			{
				t.children[0].status="opened";
				var mm=t.children[0].children[0];  //切换t的图片
				mm.src=mm.open_img;
				return(true);
			}
		}		
	return(false);
}



//===================== 以上函数根据节点r(一个LI元素)在树中定位 ====================


//========================= 以下函数将所有的目录关闭 ==============================

function closeAll() //将所有的目录折叠
{   if (document.all.tree==null) return; 
	var coll = document.all.tree.children.tags("UL");
	if (coll!=null)
	   for (var i=0;i<coll.length;i++)
	    { 
			var cli=coll[i].children.tags("LI");
			if (cli!=null&&cli.length>0)
	      		for (var j=0;j<cli.length;j++)	closeLI(cli[j]);    	 	 	   	
	   	}
	if (lastSelected!=null) lastSelected.children[0].children[1].className="unselected";  //改变上一次选择的节点的外观
	lastSelected=null; 	
}
	

function closeLI(r)  //将节点r(一个LI元素）里面的各层关闭
{
	var cul=r.children.tags("UL");
	if (cul!=null&&cul.length>0) //如果r是目录
	{	
		r.children[0].status="closed";
		var mm=r.children[0].children[0];
		mm.src=mm.close_img;       //切换目录图片
		for (var i=0;i<cul.length;i++)
		{
			var cli=cul[i].children.tags("LI");
			if (cli!=null)			
				for (var j=0;j<cli.length;j++) closeLI(cli[j]);
			cul[i].style.display="none";
		}
	}
}

//========================= 以上函数将所有的目录关闭 ==============================

//========================= 以下函数将所有的目录打开 ==============================

function openAll()  //将所有的目录打开
{  
	if (document.all.tree==null) return; 
	var coll = document.all.tree.children.tags("UL");
	if (coll!=null)
	   for (var i=0;i<coll.length;i++)
	    { 
			var cli=coll[i].children.tags("LI");
			if (cli!=null&&cli.length>0)
	      		for (var j=0;j<cli.length;j++)	openLI(cli[j]);    	 	 	   	
	   	}
	if (lastSelected!=null) lastSelected.children[0].children[1].className="unselected";  //改变上一次选择的节点的外观
	lastSelected=null; 	
}	

function openLI(r)  //将节点r(一个LI元素）里面的各层打开
{
	var cul=r.children.tags("UL");
	if (cul!=null&&cul.length>0) //如果r是目录
	{	
		r.children[0].status="opened";
		var mm=r.children[0].children[0];
		mm.src=mm.open_img;       //切换目录图片
		for (var i=0;i<cul.length;i++)
		{
			var cli=cul[i].children.tags("LI");
			if (cli!=null)			
				for (var j=0;j<cli.length;j++) openLI(cli[j]);
			cul[i].style.display="block";
		}
	}
}

//========================= 以上函数将所有的目录关闭 ==============================


//====================== 以下函数找到树中下一个相邻节点 ============================

function nextNode(e)  //找到节点e在树中的下一个相邻节点，e 必须是LI元素
{   
	if (e==null||e.tagName!="LI") return(null);
	var cul=e.children.tags("UL"); 
	if (cul!=null&&cul.length>0)  //如果e有儿子
	{ 
	  var t=cul[0].children.tags("LI"); 
	  if (t!=null&&t.length>0) 	
	  	return(t[0]);  //返回e 的第一个儿子;	 	
	}	
	var par,i,son;
	while (true)
	{
		par=e.parentElement;  //par是e的父亲元素，应该是一个UL元素
		if (par==null||par.tagName!="UL") return(null);//如果e没有父亲，则失败返回	
		son=par.children.tags("LI");
		if (son!=null&&son.length>0)
			for (i=0;i<son.length;i++) 
				if (son[i]==e) break; //找到e在其父亲的儿子中的索引
		i++;
		if (i<son.length) return(son[i]);//e不是他的父亲的最后一个儿子，返回e的父亲的下一个儿子
		e=par.parentElement;  //e现在是一个LI元素
		if (e==null||e.tagName!="LI") return(null);
	}	
}


//====================== 以下函数找到树中上一个相邻节点 ============================

function prevNode(e)  //找到节点e在树中的上一个相邻节点，e 必须是LI元素
{   
	if (e==null||e.tagName!="LI") return(null);
	var par,i,son;		
	par=e.parentElement;
	if (par==null||par.tagName!="UL") return(null);//如果e没有父亲，则失败返回		
	son=par.children.tags("LI");	
	if (son!=null&&son.length>0)
		for (i=0;i<son.length;i++) 
			if (son[i]==e) break; //找到e在其父亲的儿子中的索引	
	if (i>0) return(son[i-1]);//e不是他的父亲的第一个儿子，返回e的父亲的上一个儿子		
	par=par.parentElement;
//	while (par!=null&&par.tagName!="BODY"&&par.tagName!="LI") par=par.parentElement;
	if (par!=null&&par.tagName=="LI") return(par);
							else return(null);
		
}
