﻿var Dhatv = function(dbox,root,maxlength){
	this.ajaxerror = '服务器错误，请稍候重试或与管理员联系！';//请求错误信息
	this.checkbox = false;//复选框
	this.checkIndex = -1;//检测默认选中状态索引，-1表示不需要进行默认选中的检测
	this.checkedNodes = {};//已选中的节点，for in遍历
	this.constructor = arguments.callee;//修正关系
	this.datasource = [];//静态数据源
	this.dataurl = '';//Ajax数据源
	this.editurl = '';//编辑处理地址
	this.editable = false;//编辑状态
	this.editmenu = null;//编辑菜单
	this.editpanel = null;//编辑面板
	this.extpp = [];//扩展数据名称
	this.iconpath = 'dhatv4/';//图标位置
	this.maxlength = maxlength||100;//每次最多加载节点数
	this.onNodeClick = function(node){alert('onNodeClick:\n'+node);};//节点单击事件
	this.onNodeDblClick = function(node){alert('onNodeDblClick:\n'+node);};//节点双击事件
	this.onContextMenu = function(node){alert('onContextMenu:\n'+node);};//节点右击事件
	this.onNodeOpen = function(node){alert('onNodeOpen:\n'+node);};//节点展开事件
	this.onNodeFocus = function(node){alert('onNodeFocus:\n'+node);};//节点聚焦事件
	this.onNodeChecked = function(node){alert('onNodeChecked:\n'+node);};//节点选中事件
	this.onNodeUnChecked = function(node){alert('onNodeUnChecked:\n'+node);};//节点取消选中事件
	this.expandonnodeclick = true;//节点单击后是否展开此节点
	this.root = root||'dhATV V4.0';//根节点文本
	this.rootNode = null;
	this.sortable = false;//是否允許排序，false不允許,asc順序A-Z,desc倒序Z-A
	this.sortIndex = 0;//排序索引，0表示按數據源中第一個數據進行排序
	this.selectedNode = null;//选中节点
	this.treebox = dbox;//植树框
};
Dhatv.prototype = {
	clearNode:function(node){//清除节点
		var dparent = node.parentNode,dpparent = node.parentNode.parentNode;
		var datasource = this.datasource;
		dparent.removeChild(node);
		var dchild = null,dimg = null,i=0;
		if(!dparent.childNodes.length){
			this.folder2TxtNode(dpparent);//目录节点转变为文本节点
		}else{
			this.resetLastChild(dpparent);//最后一个节点改变样式
		}
	},
	checkUp:function(node){//向上设置checkbox
		try{
			var chkall = true,chkbox = node.parentNode.getElementsByTagName("input");
			for(var n=0;n<chkbox.length;n++){
				if(!chkbox[n].checked){
					chkall=false;
					break;
				}
			}
			var nodeParent = node.parentNode.parentNode,checkstate = nodeParent.childNodes[2].checked,atid;
			nodeParent.childNodes[2].checked = chkall?true:false;
			if(chkall&&!checkstate){//选中事件
				atid=nodeParent.getAttribute('atid');this.checkedNodes[atid] = nodeParent;
				if(this.onNodeChecked&&this.onNodeChecked.constructor==Function){this.onNodeChecked(nodeParent);}
			}
			if(!chkall&&checkstate){//取消选中事件
				atid=nodeParent.getAttribute('atid');delete this.checkedNodes[atid];
				if(this.onNodeUnChecked&&this.onNodeUnChecked.constructor==Function){this.onNodeUnChecked(nodeParent);}
			}
			this.checkUp(nodeParent);
		}catch(e){}
	},
	editEvent:function(e){//编辑菜单事件
		var dtarg = e.srcElement||e.target;
		easyUI.stopEvent(e);
		this.hideEditMenu();
		if(dtarg.tagName=='A'){
			switch(dtarg.innerHTML){
				case '添加':
					this.newNodePanel(this.selectedNode);
					break;
				case '编辑':
					this.editNodePanel(this.selectedNode,'edit');
					break;
				case '转移':
					this.editNodePanel(this.selectedNode,'move');
					break;
				case '删除':
					var fdstr = ((/folder/i.test(this.selectedNode.className)))?'\n该节点下所有子节点将同时被删除！':'';
					if(window.confirm('警告，您将要进行节点的删除操作！'+fdstr+'\n您是否确定要删除该节点？')){
						this.removeNode(this.selectedNode);
					}
					break;
				default:break;
			}
		}
	},
	editNode:function(node,avalue){//编辑节点
		var atid = node&&node.getAttribute('atid');
		var pid = avalue.shift(),txtvalue = avalue.shift();//pid必须存储在avalue的第一索引位置
		var oldtxt = node&&node.getAttribute('txt'),oldpid = node&&node.getAttribute('pid');
		if(!txtvalue||!txtvalue.replace(/\s/g,'').length){alert('节点名称必须输入！');return;}
		if(node.className=='root'){this.root = txtvalue;node.setAttribute('txt',txtvalue);node.lastChild.previousSibling.innerHTML = txtvalue;return;}
		var showEditNode = function(){//展示编辑后节点
			this.clearNode(node);//清除原节点
			var pnode = this.getNodeByDataIndex(0,pid);//得到新的父节点
			if(pnode){
				if((/text/i.test(pnode.className))){this.txtNode2Folder(pnode);}
				if(pnode.lastChild){
					this.setOpenState(pnode,false);
					pnode.lastChild.innerHTML = '';
				}
				this.expandNode(pnode);
				var enode = this.getNodeByDataIndex(0,atid);//得到编辑的节点
				if(enode){this.openUp(enode);this.setFocus(enode);}
			}
		};
		if(node){//修改数据
			var datasource = this.datasource,ndata = null,pindex = null,pcl = 0;
			if(datasource&&datasource.constructor==Array&&datasource.length>0){//静态数据源
				for(var i=0;i<datasource.length;i++){
					ndata = datasource[i];
					if(ndata[0]==oldpid){pindex = i;}
					if(ndata[0]==pid){this.datasource[i][3] = 1;}//修改新父节点hasChildNodes
					if(ndata[0]==atid){this.datasource[i] = [atid,pid,txtvalue,datasource[i][3]].concat(avalue);}
					if(ndata[0]!=atid&&ndata[1]==oldpid){pcl = 1;}
				}
				if(pindex!=null&&!isNaN(pindex)){this.datasource[pindex][3] = pcl;}//修改历史父节点hasChildNodes
				showEditNode.call(this);
			}
			if(this.dataurl.replace(/\s/g,'').length>0){//网络数据源
				var aurl = this.editurl.split('?'),surl = aurl[0],sarg = 'atid='+atid+'&pid='+pid+'&txt='+escape(txtvalue)+'&ext='+escape(avalue.join('|'))+'&cmd=edit';
				if(aurl[1]){sarg = aurl[1]+'&'+sarg;}
				var xrcb = function(xhr){
					if(xhr){
						var rpt = unescape(xhr.responseText);
						if(rpt=='done'){//服务端编辑节点后必须返回 done
							showEditNode.call(this);
						}else{
							alert(rpt);
						}
					}
				};
				easyUI.ajax.post(surl,sarg,true,xrcb.bind(this),this.ajaxerror);
			}
		}
	},
	editNodePanel:function(node,type){//编辑节点面板
		if(!node||!this.editpanel){return;}
		var atid = node&&node.getAttribute("atid");
		var pid = node&&node.getAttribute("pid");
		var txt = node&&node.getAttribute("txt");
		var extpp = this.extpp;
		var iptstr = '<p style="margin:0;padding:5px;"><label style="display:-moz-inline-box;display:inline-block;width:70px;overflow:hidden;">节点名称：</label><input type="text" style="width:230px;height:18px;border:1px solid #7F9DB9;" value="'+txt+'" /></p>';
		if(extpp.length){
			for(var i=0;i<extpp.length;i++){
				iptstr += '<p style="margin:0;padding:5px;"><label style="display:-moz-inline-box;display:inline-block;width:70px;overflow:hidden;">'+extpp[i]+'：</label><input type="text" style="width:230px;height:18px;border:1px solid #7F9DB9;" value="'+(node.getAttribute(extpp[i])||'')+'" /></p>';
			}
		}
		var editform = '<fieldset style="display:'+(type=='move'?'none':'block')+';margin:10px 0;font-size:12px;"><legend>'+txt+'</legend>'+iptstr+'</fieldset>';
		var treeStr = '<fieldset style="display:'+(type=='edit'?'none':'block')+';margin:10px 0;font-size:12px;border:2px inset"><legend>选择父节点</legend><div style="height:150px;overflow:auto;"></div></fieldset><p style="margin:0;text-align:right"><button style="width:60px;">确定</button> <button style="width:60px;">取消</button></p>';
		this.editpanel.popup(editform+treeStr,'编辑节点');
		//创建临时树
		var snlist = this.getNodeList(this.selectedNode);
		var treefs = this.editpanel.dcbd.childNodes[1].childNodes[1];
		var xtree = new this.constructor(treefs);
		xtree.root = this.root;
		xtree.iconpath = this.iconpath;
		xtree.datasource = this.datasource.slice(0);
		xtree.dataurl = this.dataurl;
		xtree.sortable = this.sortable;
		xtree.sortIndex = this.sortIndex;
		xtree.checkbox = false;
		xtree.editable = false;
		xtree.onNodeOpen = null;
		xtree.onNodeFocus = null;
		xtree.onNodeClick = null;
		xtree.onNodeChecked = null;
		xtree.init();
		xtree.rootNode.setAttribute('atid',this.rootNode.getAttribute('atid'));
		xtree.rootNode.setAttribute('pid',this.rootNode.getAttribute('pid'));
		xtree.focusNode(snlist,function(){var tmpnode=xtree.selectedNode.parentNode.parentNode;xtree.clearNode(xtree.selectedNode);xtree.setFocus(tmpnode);});
		//创建临时树结束
		var formobj = this.editpanel.dcbd.getElementsByTagName('input');
		var btnobj = this.editpanel.dcbd.getElementsByTagName('button');
		var btnOk = btnobj[0];//添加
		var btnCancel = btnobj[1];//取消
		btnCancel.onclick = function(){xtree=null;this.close();}.bind(this.editpanel);
		btnOk.onclick = function(){
			var avalue = [],npid = xtree&&xtree.selectedNode&&xtree.selectedNode.getAttribute('atid');
			if(pid!=npid){//更换了父目录
				avalue.push(npid);
			}else{
				avalue.push(pid);
			}
			for(var n=0;n<formobj.length;n++){
				if(formobj[n].value){avalue.push(formobj[n].value);}
			}
			xtree = null;
			this.editpanel.close();
			this.editNode(this.selectedNode,avalue.slice(0));
		}.bind(this);
	},
	expandAll:function(node){//展开指定节点的所有子节点
		var deepopen = function(childNodes,xnode){//深度优先
			if(!xnode){return;}
			var dul = xnode.lastChild,dulcd = dul.childNodes,lcd = dulcd.length;
			if(!lcd||dulcd[0].getAttribute('txt')=='getmore'){this.insertNode(childNodes,xnode);}
			var me = this;
			window.setTimeout(function(){
				var dcd = easyUI.getElementsBy('class','folder','li',xnode),l = dcd.length;
				var dlcd = easyUI.getElementsBy('class','folderl','li',xnode)[0];
				for(var i=0;i<l;i++){me.expandAll(dcd[i]);}
				if(dlcd){me.expandAll(dlcd);}
			},100);
		};
		if(!node){return;}
		this.openUp(node);
		this.openNode(node,null,deepopen);
	},
	expandNode:function(node){//展开指定的节点
		if(!node){return;}
		this.openUp(node);
		this.setFocus(node);
		this.openNode(node);
	},
	focusNode:function(aIndex,callback){//设置焦点到指定位置的节点[0,0,0] 0->0->0
		if(!aIndex||aIndex.constructor!=Array){return;}
		var root = this.treebox.firstChild.firstChild;//根节点
		if(!root){return;}
		if(aIndex.length<2){//设置根目录获得焦点
			this.setFocus(root);
			if(callback&&callback.constructor==Function){callback();}
			return;
		}
		var maxlength = this.maxlength;
		aIndex[0] = 0;//强制起始位置为根节点
		var tmpNode = root,lastNode = null;
		var searchEx = function(){//搜索已存在节点
			if(tmpNode&&tmpNode.lastChild.childNodes.length){aIndex.shift();}
			var i = -1;
			while(aIndex.length&&tmpNode&&tmpNode.lastChild.childNodes.length){
				lastNode = tmpNode;i = aIndex.shift();
				tmpNode = tmpNode.lastChild.childNodes[i]||null;
			}
			tmpNode = (tmpNode)?tmpNode:lastNode;//返回最后有效节点
			if(i>=0&&aIndex.length){aIndex.unshift(i);}//当有处理子节点并且索引序列尚未结束时，重新插入该节点索引
		};
		var searchAsync = function(childNodes,node,aSearch){//异步搜索
			if(aSearch.length===0){//当遍历完索引仍然没有找到，聚焦到当前节点
				this.openUp(node);
				this.setFocus(node);
				childNodes=node=null;return;
			}
			var depart = aSearch&&aSearch.shift();
			if(depart<0||isNaN(depart)){depart = 0;}
			if(childNodes&&childNodes.length>0){
				this.insertNode(childNodes,node);
				var dli = node.getElementsByTagName('li');
				if(depart>=childNodes.length){//当索引值超过子节点数，聚焦到当前节点
					this.openUp(node);
					this.setFocus(node);
					childNodes=node=null;return;
				}
				if(aSearch.length===0){
					var dIndex = dli[depart];
					this.openUp(dIndex);
					this.setFocus(dIndex);
					if(callback&&callback.constructor==Function){callback();}
					childNodes=node=null;
					return;
				}
				node = dli[depart];
			}
			var atid = node.getAttribute('atid');
			var pid = node.getAttribute('pid');
			this.getData(atid,pid,0,arguments.callee,[node,aSearch,maxlength]);//异步哦 ^_^
		};
		searchEx();
		searchAsync.call(this,null,tmpNode,aIndex.slice(0));
		root = tmpNode = lastNode = null;
	},
	folder2TxtNode:function(node){//目录节点转变为文本节点
		if(!node){return;}
		var dul = node.lastChild;
		if(dul){
			dul.style.display = 'none';
			dul.innerHTML = '';
		}
		node.className = node.className.replace(/folder/i,'text');
		var dchild = node.childNodes,dimg = null;
		for(var i=0;i<dchild.length;i++){
			dimg = dchild[i];
			if(dimg.tagName=='IMG'){
				dimg.className = dimg.className.replace(/f(l?)\-open/i,'t$1');
			}
		}
	},
	getData:function(atid,pid,more,callback,args){//返回指定节点子数据
		if(this.datasource.constructor==Array&&this.datasource.length>0){return this.getDataSource(atid,pid,more,callback,args);}
		if(this.dataurl.replace(/\s/g,'').length>0){return this.getDataUrl(atid,pid,more,callback,args);}
	},
	getDataSource:function(atid,pid,more,callback,args){//取静态数据
		var data = this.datasource,il = data.length,arv = [],rlen = (parseInt(this.maxlength,10)+1);
		for(var i=0;i<il;i++){
			if(arv.length>=rlen){break;}
			if(more){
				if(data[i][0]>atid&&data[i][1]==pid){//查询atid比atid大，并且pid等于pid的数据，长度达到指定长度即返回，同样适用于服务端查询
					arv.push(data[i]);
				}
			}else{
				if(data[i][1]==atid){
					arv.push(data[i]);
				}
			}
		}
		if(callback&&callback.constructor==Function){callback.apply(this,[arv.slice(0)].concat(args));}
		return arv.slice(0);
	},
	getDataUrl:function(atid,pid,more,callback,args){//取服务端数据
		var aurl = this.dataurl.split('?'),surl = aurl[0],sarg = 'atid='+atid+'&pid='+pid+'&more='+more+'&l='+(parseInt(this.maxlength,10)+1);
		if(aurl[1]){sarg = aurl[1]+'&'+sarg;}
		//alert(surl + sarg);
		var tv = this;
		var xrcb = function(xhr){
			if(xhr){
				var rpt = unescape(xhr.responseText);
				var rv = null;
				if(rpt.replace(/\s/g,'')!==''){
					rv = eval('0,'+rpt);
					if(callback&&callback.constructor==Function){callback.apply(tv,[rv].concat(args));}
				}
				return rv;
			}
			return null;
		};
		easyUI.ajax.post(surl,sarg,true,xrcb,this.ajaxerror);
	},
	getDataFromList:function(list){//从列表结构(ul,ol,dl)中提取数据源
		var isList = function(tagname){return (tagname)?(/(?:ul|ol|dl)/i.test(tagname)):false;};
		if(!list||!isList(list.tagName)){return null;}
		var alist = [[0,list]],data = [],node = null,elm = null,dchild = null,hasChild = 0,atid = 0;
		while(alist.length){
			node = alist.shift();
			elm = node[1];//ul
			if(!elm||!isList(elm.tagName)){continue;}
			easyUI.clearTxtNode(elm);
			var A = node[0];
			dchild = elm.childNodes;//li
			var tmpdata = [],dlast = null,txt = null,ppt = [];
			var bnr = /(?:ie|firefox)/i.test(navigator.userAgent);//ie,firefox,netscape的attributes索引顺序需要反转
			for(var i=0;i<dchild.length;i++){
				++atid;
				easyUI.clearTxtNode(dchild[i]);
				dlast = dchild[i].lastChild;
				tmpdata.push([atid,dlast]);
				if(isList(dlast.tagName)){
					hasChild = 1;
					txt = dlast.previousSibling&&dlast.previousSibling.nodeValue;
				}else{
					hasChild = 0;
					txt = dlast.nodeValue;
				}
				var dla = dchild[i].attributes,dll = dla.length;
				for(var p=0;p<dll;p++){
					if(dla[p].specified){ppt.push(dla[p].value);}
				}
				if(bnr){ppt = ppt.reverse();}
				data.push([atid,A,txt,hasChild].concat(ppt));
			}
			alist = tmpdata.slice(0).concat(alist);
		}
		return data.slice(0);
	},
	getDIByDataIndex:function(index,value){//根据字段索引取对应数据源索引值
		if(isNaN(index)||value===null||!value.toString().replace(/\s/g,'').length){return;}
		var datasource = this.datasource;
		for(var i=0;i<datasource.length;i++){
			if(datasource[i][index]==value){
				return i;
				break;
			}
		}
	},
	getNodeByDataIndex:function(index,value){//由数据源字段得到节点
		if(isNaN(index)||value===null||!value.toString().replace(/\s/g,'').length){return;}
		var app = ['atid','pid','txt'].concat(this.extpp),pp = app[index];
		if(pp){
			var dli = this.treebox.getElementsByTagName('li'),tmpvalue = null;
			if(dli.length){
				for(var i=0;i<dli.length;i++){
					tmpvalue = dli[i].getAttribute(pp);
					if(tmpvalue==value){
						return dli[i];
						break;
					}
				}
			}
		}
	},
	getNodeList:function(node){//取节点索引序列
		if(!node){return null;}
		var list = [];
		do{
			if(!node||node.tagName!='LI'){break;}
			var i = 0;
			do{
				if(!node.previousSibling||node.previousSibling.tagName!='LI'){break;}
				i++;node = node.previousSibling;
			}while(node);
			list.push(i);
		}while(node.parentNode&&(node=node.parentNode.parentNode));
		return list.reverse().slice(0);
	},
	hideEditMenu:function(){//关闭编辑菜单
		this.editmenu.style.visibility = 'hidden';
	},
	insertNode:function(childNodes,node){//插入节点[[autoID,parentID,nodeValue,hasChildNodes],...]
		if(node&&childNodes&&childNodes.constructor==Array&&childNodes.length>0){
			var dul = node.lastChild;//ul
			var dlast = dul&&dul.lastChild;//node下ul元素中最后一个li
			var mcnl = childNodes.length;
			if(mcnl>this.maxlength){--childNodes.length;}
			//alert(dul+'\n'+dlast+'\n'+node);
			var chkbox = node&&node.childNodes[2];
			var pchecked = (chkbox&&chkbox.tagName=='INPUT')?chkbox.checked:false;//是否选中
			var chkStr = '';//复选框
			var editStr = (this.editable)?'<img class="tvedit" src="'+this.iconpath+'space.gif" />':'';
			var aCNS = [],cnl = childNodes.length,A,P,T,S,tmpCN,cnfl,epn,extpp,sortable = this.sortable,si = this.sortIndex;
			if(sortable){//排序
				childNodes.sort(function(a,b){
					var x = a[si]||0,y = b[si]||0;
					return !isNaN(x)?(sortable.toString().toLowerCase()=='desc')?y-x:x-y:(sortable.toString().toLowerCase()=='desc')?y.localeCompare(x):x.localeCompare(y);
				});
			}
			for(var i=0;i<cnl;i++){
				tmpCN = childNodes[i];cnfl = tmpCN.length;epn='';extpp = '';
				A = tmpCN[0];P = tmpCN[1];T = tmpCN[2];S = tmpCN[3];//必须属性atid,pid,nodevalue,haschild
				if(cnfl>4){//扩展属性，自动冠名为 extpp1,extpp2......
					for(var n=4;n<cnfl;n++){
						epn = (this.extpp.length&&this.extpp[n-4])?this.extpp[n-4]:'extpp'+(n-3);
						extpp += ' '+epn+'="'+tmpCN[n]+'"';
					}
				}
				checked = (pchecked||tmpCN[this.checkIndex]);//是否选中
				chkStr = (this.checkbox)?(checked)?'<input type="checkbox" checked="checked" />':'<input type="checkbox" />':'';//复选框
				checked = pchecked;
				if(S){//目录节点
					aCNS[i] = '<li class="folder" atid="'+A+'" pid="'+P+'" txt="'+T+'"'+extpp+'><img class="tvdash-f" src="'+this.iconpath+'space.gif" /><img class="tvicon-f" src="'+this.iconpath+'space.gif" />'+chkStr+editStr+'<a href="#">'+T+'</a><ul></ul></li>';
				}else{//文本节点
					aCNS[i] = '<li class="text" atid="'+A+'" pid="'+P+'" txt="'+T+'"'+extpp+'><img class="tvdash-t" src="'+this.iconpath+'space.gif" /><img class="tvicon-t" src="'+this.iconpath+'space.gif" />'+chkStr+editStr+'<a href="#">'+T+'</a><ul></ul></li>';
				}
			}
			if(mcnl>this.maxlength){//添加继续加载剩余数据节点
				aCNS.push('<li class="textl" atid="'+A+'" pid="'+P+'" txt="getmore"><img class="tvdash-tl" src="'+this.iconpath+'space.gif" /><img class="tvicon-tl" src="'+this.iconpath+'space.gif" /><a href="#">点击继续加载...</a></li>');
			}else{//全部数据已加载结束，将最后一个节点设置为树梢 ^_^
				var stmp = aCNS[aCNS.length-1];
				//prompt('x',stmp);
				stmp = stmp.replace(/class="(folder|text|tvdash-f|tvdash-t|tvicon-f|tvicon-t)"/ig,'class="$1l"');
				aCNS[aCNS.length-1] = stmp;
			}
			if(dlast&&dlast.getAttribute('txt')=='getmore'){dul.removeChild(dlast);}//移除点击继续加载的节点
			dul.insertAdjacentHTML('beforeend',aCNS.join(''));//插入新节点
			if(checked){//添加到已选中节点
				var dchkednode = dul.getElementsByTagName("li"),cnl = dchkednode.length,dli = null;
				for(var c=0;c<cnl;c++){
					dli = dchkednode[c];atid=dli.getAttribute('atid');this.checkedNodes[atid] = dli;
				}
			}
		}
	},
	newNode:function(node,avalue){//添加节点
		var atid = node&&node.getAttribute("atid");
		var pid = node&&node.getAttribute("pid");
		var txtNode = node&&(/text/i.test(node.className));
		var txtvalue = avalue.shift();
		if(!txtvalue){alert('节点名称必须输入！');this.newNodePanel(node);return;}
		var showNewNode = function(){//展示新节点
			if(txtNode){this.txtNode2Folder(node);}
			if(node.lastChild){
				this.setOpenState(node,false);
				node.lastChild.innerHTML = '';
			}
			this.openNode(this.selectedNode);
		};
		if(node){//添加数据
			var datasource = this.datasource,ndata = null;
			if(datasource&&datasource.constructor==Array&&datasource.length>0){//静态数据源
				var natid = this.datasource.length+1;
				ndata = [natid,atid,txtvalue,0].concat(avalue);
				this.datasource.push(ndata);
				showNewNode.call(this);
			}
			if(this.dataurl.replace(/\s/g,'').length>0){//网络数据源
				var aurl = this.editurl.split(','),surl = aurl[0],sarg = 'atid=&pid='+atid+'&txt='+escape(txtvalue)+'&ext='+escape(avalue.join('|'))+'&cmd=new';
				if(aurl[1]){sarg = sarg+'&'+sarg;}
				var xrcb = function(xhr){
					if(xhr){
						var rpt = unescape(xhr.responseText);
						if(!isNaN(parseInt(rpt,10))){//服务端添加节点后必须返回节点编号atid
							showNewNode.call(this);
						}else{
							alert(rpt);
						}
					}
				};
				easyUI.ajax.post(surl,sarg,true,xrcb.bind(this),this.ajaxerror);
			}
		}
	},
	newNodePanel:function(node){//添加节点面板
		if(!node||!this.editpanel){return;}
		var atid = node&&node.getAttribute("atid");
		var pid = node&&node.getAttribute("pid");
		var txt = node&&node.getAttribute("txt");
		var extpp = this.extpp;
		var ih = 150;
		var iptstr = '<p style="margin:0;padding:5px;"><label style="display:-moz-inline-box;display:inline-block;width:70px;overflow:hidden;">节点名称：</label><input type="text" style="width:230px;height:18px;border:1px solid #7F9DB9;" /></p>';
		if(extpp.length){
			for(var i=0;i<extpp.length;i++){
				iptstr += '<p style="margin:0;padding:5px;"><label style="display:-moz-inline-box;display:inline-block;width:70px;overflow:hidden;">'+extpp[i]+'：</label><input type="text" style="width:230px;height:18px;border:1px solid #7F9DB9;" /></p>';
				ih += 50;
			}
		}
		var addform = '<fieldset style="margin:10px 0;font-size:12px;"><legend>'+txt+'</legend>'+iptstr+'</fieldset><p style="margin:0;text-align:right"><button style="width:60px;">添加</button> <button style="width:60px;">取消</button></p>';
		this.editpanel.popup(addform,'添加节点');
		var formobj = this.editpanel.dcbd.getElementsByTagName('input');
		var btnobj = this.editpanel.dcbd.getElementsByTagName('button');
		var btnOk = btnobj[0];//添加
		var btnCancel = btnobj[1];//取消
		btnCancel.onclick = this.editpanel.close.bind(this.editpanel);
		btnOk.onclick = function(){
			var avalue = [];
			for(var n=0;n<formobj.length;n++){
				if(formobj[n].value){avalue.push(formobj[n].value);}
			}
			this.editpanel.close();
			this.newNode(this.selectedNode,avalue.slice(0));
		}.bind(this);
	},
	openNode:function(node,dtarg,callback){//展开节点
		var atid = node&&node.getAttribute('atid');
		var pid = node&&node.getAttribute('pid');
		var txt = node&&node.getAttribute('txt');
		var cls = node&&node.className;
		var more = (txt=='getmore');
		callback = (typeof callback=='function')?callback:this.insertNode;
		if(more&&dtarg){//点击的目标是加载更多
			dtarg.innerHTML = '<img src="'+this.iconpath+'indicator_arrow.gif" /> 正在加载数据...';
			this.getData(atid,pid,1,callback,[node.parentNode.parentNode]);//插入的节点为它的上一级目录
			return;
		}
		var dul = node&&node.lastChild;//取UL
		if(!(/text/i.test(cls))&&dul){//处理目录节点
			var dimg = null;
			for(var i=0;i<node.childNodes.length;i++){
				dimg = node.childNodes[i];
				cls = dimg.className;
				if(dimg.tagName=='IMG'&&(/(?:tvdash|tvicon)/i.test(cls))){
					var ncls = /open/i.test(cls)?cls.replace(/\-open/i,''):cls+'-open';
					dimg.className = ncls;
				}
			}
			dul.style.display = (dul.style.display!='block')?'block':'none';
			if(!dul.childNodes.length){
				var imgA = '<img class="tvdash-tl" src="'+this.iconpath+'space.gif" />';//虚线、开、关图标
				var imgB = '<img class="tvicon-tl" src="'+this.iconpath+'space.gif" />';//文件夹、文件图标
				dul.innerHTML = '<li class="text text-last" atid="0" pid="0" txt="getmore">'+imgA+imgB+'<a href="#"><img src="'+this.iconpath+'indicator_arrow.gif" /> 正在加载数据...</a></li>';
				this.getData(atid,pid,0,callback,[node]);
			}else{
				if(callback!=this.insertNode){callback.apply(this,[null,node]);}
			}
			if(this.onNodeOpen&&this.onNodeOpen.constructor==Function){this.onNodeOpen(node);}//展开事件
		}
	},
	openUp:function(node){//向上展开节点
		var nodeparent = node&&node.parentNode;
		if(!nodeparent||nodeparent==this.treebox.firstChild){return;}
		if(nodeparent.style.display=='block'){return;}
		this.openNode(nodeparent.parentNode);
		this.openUp(nodeparent.parentNode);
	},
	preload:function(pldata){//预加载元素
		try{
			document.execCommand("BackgroundImageCache", false, true);
		}catch(e){}
		var imgPL = [];
		for(var i=0;i<pldata.length;i++){
			imgPL[i] = new Image();
			imgPL[i].src = pldata[i];
		}
	},
	render:function(list){//渲染已有列表结构(ul,ol,dl)
		var isList = function(tagname){return (tagname)?(/(?:ul|ol|dl)/i.test(tagname)):false;};
		if(!list||!isList(list.tagName)){return;}
		this.datasource = this.getDataFromList(list);
		this.init();
	},
	resetLastChild:function(node){//重置目录节点最后子节点样式
		if(node&&node.lastChild){
			var dlast = node.lastChild.lastChild;
			dlast.className = dlast.className+'l';
			var dchild = dlast.childNodes,dimg = null;
			for(var i=0;i<dchild.length;i++){
				dimg = dchild[i];
				if(dimg.tagName=='IMG'){
					dimg.className = dimg.className.replace(/(tvdash\-f|tvdash\-t)(?!l)/i,'$1l');
				}
			}
		}
	},
	removeNode:function(node){//删除节点
		if(node){//移除数据
			var atid = node.getAttribute("atid"),pid = node.getAttribute("pid");
			var datasource = this.datasource;
			var atidlist = [atid];
			if(datasource&&datasource.constructor==Array&&datasource.length>0){
				(function(){//移除静态数据源
					while(atidlist.length){
						var x = atidlist.shift();
						for(var i=datasource.length;i>0;i--){
							if(datasource[i-1][0]==x||datasource[i-1][1]==x){
								atidlist.push(datasource[i-1][0]);
								datasource.splice(i-1,1);
							}
						}
					}
				})();
				this.clearNode(node);
			}
			if(this.dataurl.replace(/\s/g,'').length>0){//移除网络数据源
				var aurl = this.editurl.split('?'),surl = aurl[0],sarg = 'atid='+atid+'&cmd=del';
				if(aurl[1]){sarg = aurl[1]+'&'+sarg;}
				var xrcb = function(xhr){
					if(xhr){
						var rpt = unescape(xhr.responseText);
						if(rpt=='done'){//服务端删除节点后必须返回 done
							this.clearNode(node);
						}else{
							alert(rpt);
						}
					}
				};
				easyUI.ajax.post(surl,sarg,true,xrcb.bind(this),this.ajaxerror);
			}
		}
	},
	showEditMenu:function(left,top){//展开编辑菜单
		var emenu = this.editmenu;
		emenu.style.left = left+'px';
		emenu.style.top = top+'px';
		emenu.style.visibility = 'visible';
		var node = this.selectedNode;
		var rootNode = (node.className=='root');
		if(rootNode){//根节点只允许添加按钮
			var dul = emenu.childNodes[0];
			var dli = dul.childNodes;
			for(var i=dli.length;i>1;i--){
				dul.removeChild(dli[i-1]);
			}
		}else{
			emenu.innerHTML = emenu.data;
		}
	},
	setFocus:function(node){//设置当前选中节点
		var dlink = node.lastChild.previousSibling;
		if(!dlink||dlink.tagName!='A'){return;}
		dlink.className = 'selected';
		if(this.selectedNode&&this.selectedNode!=node){this.selectedNode.lastChild.previousSibling.className='';}
		this.selectedNode = node;
		if(this.onNodeFocus&&this.onNodeFocus.constructor==Function){this.onNodeFocus(node);}//聚焦事件
	},
	setOpenState:function(node,open){//设置节点展开状态
		if(!node||(/text/i.test(node.className))){return;}
		var dimg = null,cls = '';
		for(var i=0;i<node.childNodes.length;i++){
			dimg = node.childNodes[i];
			cls = dimg.className;
			if(dimg.tagName=='IMG'&&(/(?:tvdash|tvicon)/i.test(cls))){
				var ncls = (!open)?cls.replace(/\-open/i,''):cls+'-open';
				dimg.className = ncls;
			}
		}
		if(node.lastChild){node.lastChild.style.display = open?'block':'none';}
	},
	txtNode2Folder:function(node){//文本节点转目录节点
		var dchild = null,dimg = null,i=0;
		node.className = node.className.replace(/text/i,'folder');
		dchild = node.childNodes;dimg = null;
		for(var i=0;i<dchild.length;i++){
			dimg = dchild[i];
			if(dimg.tagName=='IMG'){
				dimg.className = dimg.className.replace(/(tvdash\-|tvicon\-)t(l?)$/i,'$1f$2');
			}
		}
	},
	treeNode:function(tv){//treenode construct
		this.onclick = function(e){
			e = e||window.event;var dtarg = e.srcElement||e.target,dtargTN = dtarg.tagName,dparent = dtarg.parentNode,atid;
			switch(dtargTN){
				case 'IMG':
					var dtargCLS = dtarg.className;
					if(/tvdash/i.test(dtargCLS)){//开、关图标
						//展开节点
						tv.openNode(dparent);
					}
					if(/tvedit/i.test(dtargCLS)&&tv.editable){//编辑图标
						var pos = easyUI.getPosition(dtarg);
						var pos2 = easyUI.getPosition(tv.treebox);
						if(tv.editmenu.offset){
							var left = pos.x-pos2.x+10,top = pos.y-pos2.y+20;
						}else{
							var left = pos.x,top = pos.y+20;
						}
						//设置选中
						tv.setFocus(dparent);
						//展开编辑菜单
						tv.showEditMenu(left,top);
					}
					break;
				case 'INPUT'://复选框
					if(tv.checkbox){
						var checked = dtarg.checked;
						var foooc = (tv.onNodeChecked&&tv.onNodeChecked.constructor==Function);
						var fooouc = (tv.onNodeUnChecked&&tv.onNodeUnChecked.constructor==Function);
						if(checked){//选中事件
							atid=dparent.getAttribute('atid');tv.checkedNodes[atid] = dparent;
							if(foooc){tv.onNodeChecked(dparent);}
						}
						if(!checked){//取消选中事件
							atid=dparent.getAttribute('atid');delete tv.checkedNodes[atid];
							if(fooouc){tv.onNodeUnChecked(dparent);}
						}
						var chkbox = dparent.getElementsByTagName("Input");
						var cbl = chkbox.length;
						var dcparent = null;
						for(var i=1;i<cbl;i++){
							chkbox[i].checked = checked?true:false;
							dcparent = chkbox[i].parentNode;
							if(checked){//选中事件
								atid=dcparent.getAttribute('atid');tv.checkedNodes[atid] = dcparent;
								if(foooc){tv.onNodeChecked(dcparent);}
							}
							if(!checked){//取消选中事件
								atid=dcparent.getAttribute('atid');delete tv.checkedNodes[atid];
								if(fooouc){tv.onNodeUnChecked(dcparent);}
							}
						}
						tv.checkUp(dparent);
					}
					break;
				case 'A'://文本内容
					easyUI.stopEvent(e);
					if(!(/正在加载数据/i.test(dtarg.innerHTML))){
						if(tv.onNodeClick&&tv.onNodeClick.constructor==Function){tv.onNodeClick(dparent);}//单击事件
						tv.setFocus(dparent);//设置选中
						if(tv.expandonnodeclick){tv.openNode(dparent,dtarg);}//展开节点
					}
					break;
				default:break;
			}
		};
		this.ondblclick = function(e){//双击事件
			e = e||window.event;var dtarg = e.srcElement||e.target,dtargTN = dtarg.tagName,dparent = dtarg.parentNode;
			if(dtargTN=='A'){
				easyUI.stopEvent(e);
				if(!(/正在加载数据/i.test(dtarg.innerHTML))){
					if(tv.onNodeDblClick&&tv.onNodeDblClick.constructor==Function){tv.onNodeDblClick(dparent);}//双击事件
				}
			}
		};
		this.oncontextmenu = function(e){//右击事件
			e = e||window.event;var dtarg = e.srcElement||e.target,dtargTN = dtarg.tagName,dparent = dtarg.parentNode;
			if(dtargTN=='A'){
				easyUI.stopEvent(e);
				if(!(/正在加载数据/i.test(dtarg.innerHTML))){
					var pos = easyUI.getPosition(dtarg);
					var pos2 = easyUI.getPosition(tv.treebox);
					if(tv.editmenu.offset){
						var left = pos.x-pos2.x+10,top = pos.y-pos2.y+20;
					}else{
						var left = pos.x,top = pos.y+20;
					}
					if(tv.onContextMenu&&tv.onContextMenu.constructor==Function){tv.setFocus(dparent);tv.onContextMenu(dparent,left,top);}//右击事件
				}
			}
		};
	},
	init:function(){//初始化
		this.preload([this.iconpath+"icon.png",this.iconpath+"i.gif",this.iconpath+"space.gif",this.iconpath+"indicator_arrow.gif"]);
		var chkStr = (this.checkbox)?'<input type="checkbox" />':'';
		var reditStr = (this.editable)?'<img class="tvedit" src="'+this.iconpath+'space.gif" />':'';
		var editStr = (this.editable)?'<div class="editmenu"><ul><li><a class="tv-add" href="#">添加</a></li><li><a class="tv-edit" href="#">编辑</a></li><li><a class="tv-move" href="#">转移</a></li><li><a class="tv-del" href="#">删除</a></li></ul></div>':'';
		this.treebox.innerHTML = '<ul class="dhatv4"><li class="root" atid="0" pid="0" txt="'+this.root+'"><img class="tvdash" src="'+this.iconpath+'space.gif" /><img class="tvicon" src="'+this.iconpath+'space.gif" />'+chkStr+reditStr+'<a href="#">'+this.root+'</a><ul></ul></li></ul>'+editStr;
		this.treeNode.call(this.treebox.childNodes[0],this);
		this.rootNode = this.treebox.childNodes[0].firstChild;
		if(this.editable){//是否允许编辑
			this.editmenu = this.treebox.childNodes[1];
			this.editmenu.style.position = 'absolute';
			this.editmenu.style.zIndex = 100;
			this.editmenu.style.left = 0;
			this.editmenu.style.top = 0;
			this.editmenu.style.visibility = 'hidden';
			this.editmenu.data = this.editmenu.innerHTML;
			this.editmenu.offset = (this.treebox.style.position=='absolute');
			this.editmenu.onclick = this.editEvent.bind(this);
			if(document.attachEvent){
				document.attachEvent("onmousedown",function(o){return function(e){e=e||window.event;var et=e.srcElement||e.target;if(!o.contains(et)){o.style.visibility='hidden';}};}(this.editmenu));
			}else{
				document.addEventListener("mousedown",function(o){return function(e){e=e||window.event;var et=e.srcElement||e.target;if((o.contains&&!o.contains(et))||(o.compareDocumentPosition&&o.compareDocumentPosition(et)!=20)){o.style.visibility='hidden';}};}(this.editmenu),false);
			}
			window.onunload = function(){document.onmousedown = function(){};};
		}
	}
};
