var taskMsgTrees = {};

/**
 * 树形控件
 */
function TaskMsgTree() {
	this.jQueryObj = this.div           = null;         //树形控件容器层
	this.getNodeService                 = null;         //获得节点数据的Service
	this.addNodeService                 = null;         //添加节点数据的Service
	this.updateNodeService              = null;         //修改节点数据的Service
	this.deleteNodeService              = null;         //删除节点数据的Service
	this.addLeafNodeService             = null;         //添加页节点数据的Service
	this.updateLeafNodeService          = null;         //修改页节点数据的Service
	this.deleteLeafNodeService          = null;         //删除页节点数据的Service
	this.showNodeCheckbox               = false;        //是否显示选择框
	this.showNodeEditButton             = false;        //是否显示编辑按钮
	this.showNodeDeleteButton           = false;        //是否显示删除按钮
	this.showLeafNodeCheckbox           = false;        //是否显示叶节点选择框
	this.showLeafNodeEditButton         = false;        //是否显示叶节点编辑按钮
	this.showLeafNodeDeleteButton       = false;        //是否显示叶节点删除按钮
	this.nodeDataMember                 = null;         //节点绑定的数据成员
	this.leafNodeDataMember             = null;         //叶节点绑定的数据成员
	this.nodes                          = {};           //节点集合
	this.leafNodes                      = {};           //页节点集合
	this.rootNodes                      = [];           //根节点数组
	this.rootLeafNodes                  = [];           //根页节点数组
	this.rootNodeParentId               = 0;            //根节点父节点编号
	this.nodeIdFieldName                = "id";         //节点编号字段
	this.nodeNameFieldName              = "name";       //节点名称字段
	this.nodeParentIdFieldName          = "parent_id";  //节点父节点编号字段
	this.leafNodeIdFieldName            = "id";         //页节点编号字段
	this.leafNodeNameFieldName          = "name";       //页节点名称字段
	this.leafNodeParentIdFieldName      = "parent_id";  //叶节点的父节点编号字段
	this.iconColor                      = "deep";       //图标颜色，默认为空，表示深色，如果要用浅色，值为deep
	this.checkAllChildOnCheckParent     = true;         //选中父节点时选中所有子节点
	this.unCheckAllChildOnUnCheckParent = false;        //取消选中父节点后取消选中所有子节点
	this.checkParentOnCheckChild        = false;        //选中子节点后选中父节点
	this.unCheckParentOnUnCheckAllChild = true;         //取消选中所有子节点后取消选中父节点
	this.nodeOnClick                    = null;         //节点点击事件
	this.leafNodeOnClick                = null;         //叶节点点击事件
	this.nodeEditButtonOnClick          = null;         //节点编辑按钮点击事件
	this.nodeDeleteButtonOnClick        = null;         //节点删除按钮点击事件
	this.leafNodeEditButtonOnClick      = null;         //叶节点编辑按钮点击事件
	this.leafNodeDeleteButtonOnClick    = null;         //叶节点删除按钮点击事件
	this.onDataParse                    = null;         //用户自定义的数据解析方法 
	this.multiCheck                     = true;         //是否允许多选
	this.expandAll					          	= false;		    //是否展开全部节点
	this.onLoaded		            				= null;		    	//加载完成回调

	//当前树形控件，在回调函数内使用
	var thisTree = this;

  /**
   * 初始化树形控件
   * @param  {[type]} _div [description]
   */
	this.init = function(_div) {
		this.div = _div;
	  this.getNodeService = this.div.attr("getNodeService");
		this.addNodeService = this.div.attr("addNodeService");
		this.updateNodeService = this.div.attr("updateNodeService");
		this.deleteNodeService = this.div.attr("deleteNodeService");
		this.addLeafNodeService = this.div.attr("addLeafNodeService");
		this.updateLeafNodeService = this.div.attr("updateLeafNodeService");
		this.deleteLeafNodeService = this.div.attr("deleteLeafNodeService");
		this.nodeDataMember = this.div.attr("nodeDataMember");
		this.nodeOnClick = this.div.attr("nodeOnClick");
		this.leafNodeOnClick = this.div.attr("leafNodeOnClick");
		this.nodeEditButtonOnClick = this.div.attr("nodeEditButtonOnClick");
		this.nodeDeleteButtonOnClick = this.div.attr("nodeDeleteButtonOnClick");
		this.leafNodeEditButtonOnClick = this.div.attr("leafNodeEditButtonOnClick");
		this.leafNodeDeleteButtonOnClick = this.div.attr("leafNodeDeleteButtonOnClick");
		this.onDataParse = this.div.attr("onDataParse");
		this.onLoaded = this.div.attr("onLoaded");
    if(this.div.attr("expandAll")=="true") this.expandAll = true;
		if(this.div.attr("showNodeCheckbox")=="true") this.showNodeCheckbox = true;
		if(this.div.attr("showNodeEditButton")=="true") this.showNodeEditButton = true;
		if(this.div.attr("showNodeDeleteButton")=="true") this.showNodeDeleteButton = true;
		if(this.div.attr("showLeafNodeCheckbox")=="true") this.showLeafNodeCheckbox = true;
		if(this.div.attr("showLeafNodeEditButton")=="true") this.showLeafNodeEditButton = true;
		if(this.div.attr("showLeafNodeDeleteButton")=="true") this.showLeafNodeDeleteButton = true;
		if(this.div.attr("checkParentOnCheckChild")=="true") this.checkParentOnCheckChild = true;
		if(this.div.attr("unCheckAllChildOnUnCheckParent")=="true") this.unCheckAllChildOnUnCheckParent = true;
		if(this.div.attr("multiCheck")=="false") this.multiCheck = false;
		if(this.div.attr("iconColor")) this.iconColor = this.div.attr("iconColor");

		this.getData();
	};

	/**
	 * 获得树形控件数据
	 */
	this.getData = function() {
		if(!this.getNodeService) {
			console.log("请提供getNodeService！");
			return;
		}
		(new TaskMsgService(this.getNodeService)).request(null, this.onGetResponse);
	};

	/**
	 * 处理服务器端响应
	 * @param  {[type]} req [description]
	 * @param  {[type]} res [description]
	 */
	this.onGetResponse = function(req, res) {
    //如果用户自定义了数据解析方法，则调用该方法解析数据，否则按默认规则解析
		if(thisTree.onDataParse) {
			eval(thisTree.onDataParse+"(thisTree, req, res)");
		} else {
			if(!thisTree.nodeDataMember) {
				console.log("请为树型控件设置[nodeDataMember]属性！");
				return;
			} 
			var nodesData = res[thisTree.nodeDataMember];
			if(!nodesData) {
				console.log("服务器返回结果中没有名为["+thisTree.nodeDataMember+"]的参数！");
				return;
			}

			var nodeIdArr = []; 

			//将服务器端返回数据转换为节点对象
			if(nodesData instanceof Array) {
				for(var i=0;i<nodesData.length;i++) {
					var nodeData = nodesData[i];
					var node = {};
					node.id = nodeData[thisTree.nodeIdFieldName];
					node.name = nodeData[thisTree.nodeNameFieldName];
					node.parentId = nodeData[thisTree.nodeParentIdFieldName];
					node.data = nodeData;
					node.childNodes = [];
					if(thisTree.leafNodeDataMember) node.leafNodes = [];
					//node.tag = nodeData;
					thisTree.nodes[node.id] = node;
					nodeIdArr.push(node.id);
				}
			} else {
				for(objId in nodesData) {
					var nodeData = nodesData[objId];
					var node = {};
					node.id = nodeData[thisTree.nodeIdFieldName];
					node.name = nodeData[thisTree.nodeNameFieldName];
					node.parentId = nodeData[thisTree.nodeParentIdFieldName];
					node.data = nodeData;
					node.childNodes = [];
					if(thisTree.leafNodeDataMember) node.leafNodes = [];
					//node.tag = nodeData;
					thisTree.nodes[node.id] = node;
					nodeIdArr.push(node.id);
				}
			}

			//如果有页节点数据，则生成页节点对象
			if(thisTree.leafNodeDataMember && res[thisTree.leafNodeDataMember]) {
				var leafNodesData = res[thisTree.leafNodeDataMember];
				for(var i=0;i<leafNodesData.length;i++) {
					var nodeData = leafNodesData[i];
					var node = {};
					node.id = nodeData[thisTree.leafNodeIdFieldName];
					node.name = nodeData[thisTree.leafNodeNameFieldName];
					node.parentId = nodeData[thisTree.leafNodeParentIdFieldName];
					//node.tag = nodeData;
					thisTree.leafNodes[node.id] = node;
					var parentNode = thisTree.nodes[node.parentId];
					if(parentNode) {
						parentNode.leafNodes.push(node);
					}
				}
			}

			//生成节点之间的关系
			for(var i=0;i<nodeIdArr.length;i++) {
				var nodeId = nodeIdArr[i];
				var node = thisTree.nodes[nodeId];
				if(node.parentId==thisTree.rootNodeParentId) {
					thisTree.rootNodes.push(nodeId);
				} else {
					var parentNode = thisTree.nodes[node.parentId];
					if(parentNode) {
						parentNode.childNodes.push(nodeId);
					}
				}
			}
		}

		//alert(JSON.stringify(thisTree.nodes));
		
		thisTree.dataBind(req,res);
	};

	this.dataBind = function(req,res) {
		for(var i=0;i<this.rootNodes.length;i++) {
			var node = this.nodes[this.rootNodes[i]];
			if(!node.parentId) node.parentId = this.rootNodeParentId;
			this.createNode(this.div, node, 5);
		}
		if(thisTree.onLoaded) {
			eval(thisTree.onLoaded+"(req,res)");
		}
	};

	this.addNode = function(id, name, parentId, tag) {
		var node = {};
		node.id = id;
		node.name = name;
		node.parentId = parentId;
		node.childNodes = [];
		if(this.leafNodeDataMember) node.leafNodes = [];
		if(tag) node.tag = tag;
		this.nodes[node.id] = node;
		var marginLeft = 5;
		var parentDiv = this.div;
		if(node.parentId!=this.rootNodeParentId) {
			marginLeft = getPixel($("#nodeIconDiv_"+node.parentId).css("margin-left"))+20;
			parentDiv = $("#childNodesDiv_"+node.parentId);
			if(parentDiv.length==0) return;
			var parentNode = this.nodes[node.parentId];
			if(!parentNode) return;
			parentNode.childNodes.push(node.id);
			var parentIconDiv = $("#nodeIconDiv_"+node.parentId);
			if(parentIconDiv.find("img").get(0).src.indexOf("/dot")>0) {
				parentIconDiv.find("img").get(0).src = TaskMsgClientAPIDir + "images/expand"+this.iconColor+".png";
			}
		}
		this.createNode(parentDiv, node, marginLeft);
	};

	/**
	 * 修改节点
	 * @param  {[type]} id       [description]
	 * @param  {[type]} name     [description]
	 * @param  {[type]} parentId [description]
	 * @return {[type]}          [description]
	 */
	this.updateNode = function(id, name, parentId) {
		var node = this.nodes[id];
		if(!node) return;
		var nodeDiv = $("#nodeDiv_"+id);
		var childNodesDiv = $("#childNodesDiv_"+id);
		var nodeIconDiv = $("#nodeIconDiv_"+id);
		if(node.name!=name) {
			node.name = name;
			nodeDiv.find(".TaskMsgTreeNodeText").text(name);
		}
		if(node.parentId != parentId) {
			if(node.parentId!=this.rootNodeParentId) {
				var parentOld = this.nodes[node.parentId];
				parentOld.childNodes.deleteMember(node.id);
				//如果老的父节点没有其他子节点了，则应该修改老父节点的图标为无法收起或展开
				if(parentOld.childNodes.length==1) {
					var parentOldIconDiv = $("#nodeIconDiv_"+node.parentId);
					parentOldIconDiv.find("img").get(0).src = TaskMsgClientAPIDir + "images/dot"+this.iconColor+".png";
				}
			}
			var parentDiv = null;
			var parentMargin = 5;
			if(parentId==this.rootNodeParentId) {
				parentDiv = this.div;
			} else {
				parentDiv = $("#childNodesDiv_"+parentId);
				var parentNewIconDiv = $("#nodeIconDiv_"+parentId);
				parentMargin = getPixel(parentNewIconDiv.css("margin-left"))+20;
				this.setChildMargin(node, parentMargin);
				var parentNew = this.nodes[parentId];
				//如果新的父节点原来没有子节点，则应该修改新父节点的图标为展开
				if(parentNew.childNodes.length==0) {
					parentNewIconDiv.find("img").get(0).src = TaskMsgClientAPIDir + "images/expand"+this.iconColor+".png";
				}
				parentNew.childNodes.push(id);
			}
			nodeIconDiv.css("margin-left", parentMargin+"px");
			var nodeTextDivWidth = this.getNodeTextDivWidth(parentMargin);
			nodeDiv.find(".TaskMsgTreeNodeText").css("width", nodeTextDivWidth);
			nodeDiv.css("background-color", "");
			$("#nodeDelBtn_"+id).hide();
			$("#nodeEditBtn_"+id).hide();
			parentDiv.append(nodeDiv.clone());
			parentDiv.append(childNodesDiv.clone());
			node.parentId = parentId;
			nodeDiv.remove();
			childNodesDiv.remove();
		}
	};

	/**
	 * 设置子节点左边距
	 * @param {[type]} parent       [description]
	 * @param {[type]} parentMargin [description]
	 */
	this.setChildMargin = function(parent, parentMargin) {
		var nodeTextDivWidth = this.getNodeTextDivWidth(parentMargin+20);
		for(var i=0;i<parent.childNodes.length;i++) {
			var node = this.nodes[parent.childNodes[i]];
			var nodeDiv = $("#nodeDiv_"+node.id);
			nodeDiv.find(".TaskMsgTreeNodeText").css("width", nodeTextDivWidth);
			var nodeIconDiv = $("#nodeIconDiv_"+node.id);
			nodeIconDiv.css("margin-left", (parentMargin+20)+"px");
			this.setChildMargin(node, parentMargin+20);
		}
		if(!parent.leafNodes) return;
		for(var i=0;i<parent.leafNodes.length;i++) {
			var leafNode = this.leafNodes[parent.leafNodes[i]];
			var nodeDiv = $("#leafNodeDiv_"+node.id);
			nodeDiv.find(".TaskMsgTreeNodeText").css("width", nodeTextDivWidth);
			var nodeIconDiv = $("#nodeIconDiv_"+leafNode.id);
			nodeIconDiv.css("margin-left", (parentMargin+20)+"px");
		}
	};

	/**
	 * 删除节点
	 * @param  {[type]} nodeId [description]
	 * @return {[type]}        [description]
	 */
	this.deleteNode = function(nodeId) {
		if(!(nodeId in this.nodes)) return;
		//删除节点对应的html元素
		$("#nodeDiv_"+nodeId).remove();
		$("#childNodesDiv_"+nodeId).remove();
		var node = this.nodes[nodeId];
		//删除子节点
		this.deleteChildNode(node);
		//解除与父节点的关联
		if(node.parentId!=this.rootNodeParentId) {
			var parentNode = this.nodes[node.parentId];
			parentNode.childNodes.deleteMember(node.id);
			//如果父节点没有其他子节点了，则应该修改父节点的图标为无法收起或展开
			if(parentNode.childNodes.length==0) {
				var parentIconDiv = $("#nodeIconDiv_"+node.parentId);
				parentIconDiv.find("img").get(0).src = TaskMsgClientAPIDir + "images/dot"+this.iconColor+".png";
			}
		}
		//删除自己
		delete this.nodes[nodeId];
		node = null;
	};

	this.deleteChildNode = function(node) {
		for(var i=0;i<node.childNodes.length;i++) {
			var childNodeId = node.childNodes[i];
			var childNode = this.nodes[childNodeId];
			if(!childNode) continue;
			this.deleteChildNode(childNode);
			delete this.nodes[childNode.id];
			childNode = null;
			//node.childNodes.deleteMember(childNode.id);
		}
		if(!node.leafNodes) return;
		for(var i=0;i<node.leafNodes.length;i++) {
			var leafNodeId = node.leafNodes[i];
			var leafNode = this.leafNodes[leafNodeId];
			delete this.leafNodes[leafNode.id];
			//node.leafNodes.deleteMember(leafNode.id);
			leafNode = null;
		}
	};

	this.getNodeTextDivWidth = function(marginLeft) {
		//动态计算每个节点内文本框的最大宽度，以便文字过长时能自动出现省略号
		var divWidth = this.div.get(0).offsetWidth;
		var nodeTextWidth = divWidth-marginLeft-16-22;
		if(this.showNodeCheckbox) nodeTextWidth -= 25;
		if(this.showNodeDeleteButton) nodeTextWidth -= 21;
		if(this.showNodeEditButton) nodeTextWidth -= 21;
		return nodeTextWidth;
	};

	this.getLeafNodeTextDivWidth = function(marginLeft) {
		//动态计算每个节点内文本框的最大宽度，以便文字过长时能自动出现省略号
		var divWidth = this.div.get(0).offsetWidth;
		var nodeTextWidth = divWidth-marginLeft-16-22;
		if(this.showLeafNodeCheckbox) nodeTextWidth -= 25;
		if(this.showLeafNodeDeleteButton) nodeTextWidth -= 21;
		if(this.showLeafNodeEditButton) nodeTextWidth -= 21;
		return nodeTextWidth;
	};

	/**
	 * 创建节点
	 * @param  {[type]} parentDiv  [description]
	 * @param  {[type]} node       [description]
	 * @param  {[type]} marginLeft [description]
	 */
	this.createNode = function(parentDiv, node, marginLeft) {
		var toggleIcon = "dot";
		var haveChild = false;
		if(node.childNodes.length>0 || (node.leafNodes && node.leafNodes.length>0)) haveChild = true;
		if(haveChild){ 
          toggleIcon = "expand";
          if(this.expandAll)
            toggleIcon = "toggle";
        }
		var nodeHtml = "<div id=\"nodeDiv_"+node.id+"\" class=\"TaskMsgTreeNode\" nodeId=\""+node.id+"\" "
			+"onmouseover=\"treeNodeOnMouseOver(this, "+node.id+")\" "
			+"onmouseout=\"treeNodeOnMouseOut(this, "+node.id+")\" >"
			+"<div id=\"nodeIconDiv_"+node.id+"\" style=\"float: left; height:23px; margin-top: 7px; margin-left: "+marginLeft+"px;\">"
			+"<img src=\""+TaskMsgClientAPIDir + "images/"+toggleIcon+this.iconColor+".png\""
			+" style=\"width:16px;height:16px;cursor:pointer;\" onclick=\"treeNodeToggleIconOnClick(this, "+node.id+")\"></div>";
		if(this.showNodeCheckbox) {
          if(this.multiCheck) {
			  nodeHtml += "<div class=\"TaskMsgTreeNodeCheckbox\"><input id=\"nodeCbk_"
			    +node.id+"\" type=\"checkbox\" value=\""+node.id
			    +"\" onclick=\"treeNodeCbkOnClick(this, "+node.id+")\"></div>";
		  } else {
		  	nodeHtml += "<div class=\"TaskMsgTreeNodeCheckbox\"><input id=\"nodeCbk_"
			    +node.id+"\" type=\"radio\" value=\""+node.id
			    +"\" onclick=\"treeNodeCbkOnClick(this, "+node.id+")\"></div>";
		  }
		}
		nodeHtml += "<div class=\"TaskMsgTreeNodeText\" style=\"width:"+this.getNodeTextDivWidth(marginLeft)+"px;"
		if(this.iconColor=="deep") nodeHtml += "color:#333333";
		nodeHtml += "\" onclick=\"treeNodeOnClick(this, "+node.id+")\">"+node.name+"</div>";
		if(this.showNodeDeleteButton) {
			nodeHtml += "<div id=\"nodeDelBtn_"+node.id+"\" style=\"float:right;margin-top: 7px; margin-right: 5px; display:none\">"
			+"<img src=\""+TaskMsgClientAPIDir + "images/del"+this.iconColor+".png\" title=\"删除\" "
			+"onclick=\"nodeDeleteButtonOnClick(this, "+node.id+")\" style=\"cursor:pointer\"></div>";
		}
		if(this.showNodeEditButton) {
			nodeHtml += "<div id=\"nodeEditBtn_"+node.id+"\" style=\"float:right;margin-top: 7px; margin-right: 5px; display:none\">"
			+"<img src=\""+TaskMsgClientAPIDir + "images/edit"+this.iconColor+".png\" title=\"修改\" "
			+"onclick=\"nodeEditButtonOnClick(this, "+node.id+")\" style=\"cursor:pointer\"></div>";
		}
		nodeHtml += "</div>";
		parentDiv.append(nodeHtml);
      
    var childCss = "";
    if(!this.expandAll) childCss += "display:none";
		var childNodesDiv = $("<div id=\"childNodesDiv_"+node.id+"\" style=\""+childCss+"\"></div>");
		if(haveChild) {
			for(var i=0;i<node.childNodes.length;i++) {
				var childNode = this.nodes[node.childNodes[i]];
				//如果子节点没有设置父节点编号属性，则在此设置一下
				//目前在选择部门和人员时需要这么做
				if(!childNode.parentId) childNode.parentId = node.id;
				this.createNode(childNodesDiv, childNode, marginLeft+20);
			} 
			if(node.leafNodes && node.leafNodes.length>0) {
				for(var i=0;i<node.leafNodes.length;i++) {
					var leafNode = this.leafNodes[node.leafNodes[i]];
					if(!leafNode.parentId) leafNode.parentId = node.id;
					this.createLeafNode(childNodesDiv, leafNode, marginLeft+20);
				} 
			}
		}
		parentDiv.append(childNodesDiv);
	};

	/**
	 * 创建页节点
	 * @param  {[type]} parentDiv  [description]
	 * @param  {[type]} node       [description]
	 * @param  {[type]} marginLeft [description]
	 */
	this.createLeafNode = function(parentDiv, node, marginLeft) {
		var nodeHtml = "<div id=\"leafNodeDiv_"+node.id+"\" class=\"TaskMsgTreeNode\" nodeId=\""+node.id+"\" "
			+"onmouseover=\"leafNodeOnMouseOver(this, "+node.id+");\" "
			+"onmouseout=\"leafNodeOnMouseOut(this, "+node.id+");\">"
			+"<div style=\"float: left; line-height:30px; margin-left: "+(marginLeft+16)+"px;\">";
		if(this.showLeafNodeCheckbox) {
			if(this.multiCheck) {
			  nodeHtml += "<div class=\"TaskMsgTreeLeafNodeCheckbox\"><input id=\"leafNodeCbk_"
			    +node.id+"\" type=\"checkbox\" value=\""+node.id
			    +"\" onclick=\"treeLeafNodeCbkOnClick(this, "+node.id+")\"></div>";
		  } else {
		  	nodeHtml += "<div class=\"TaskMsgTreeLeafNodeCheckbox\"><input id=\"leafNodeCbk_"
			    +node.id+"\" type=\"radio\" value=\""+node.id
			    +"\" onclick=\"treeLeafNodeCbkOnClick(this, "+node.id+")\"></div>";
		  }
		} 
		nodeHtml += "<div class=\"TaskMsgTreeNodeText\" style=\"cursor:pointer;width:"
		  +this.getLeafNodeTextDivWidth(marginLeft)+"px;"
		if(this.iconColor=="deep") nodeHtml += "color:#333333";
		nodeHtml += "\" onclick=\"treeLeafNodeOnClick(this, "+node.id+")\">"+node.name+"</div></div>";
		if(this.showLeafNodeDeleteButton) {
			nodeHtml += "<div style=\"float:right;margin-top: 7px; margin-right: 5px;\">"
			+"<img src=\""+TaskMsgClientAPIDir + "images/del"+this.iconColor+".png\" title=\"删除\" "
			+"onclick=\"leafNodeDeleteButtonOnClick(this, "+node.id+")\" style=\"cursor:pointer\"></div>";
		}
		if(this.showLeafNodeEditButton) {
			nodeHtml += "<div style=\"float:right;margin-top: 7px; margin-right: 5px;\">"
			+"<img src=\""+TaskMsgClientAPIDir + "images/edit"+this.iconColor+".png\" title=\"修改\" "
			+"onclick=\"leafNodeEditButtonOnClick(this, "+node.id+")\" style=\"cursor:pointer\"></div>";
		}
		nodeHtml += "</div>";
		parentDiv.append(nodeHtml);
	};

	this.haveChild = function(nodeId) {
		return (this.nodes[nodeId].childNodes.length>0 
			|| (this.nodes[nodeId].leafNodes
			&& this.nodes[nodeId].leafNodes.length>0));
	};

	this.getCheckedNodes = function(getData) {
		var nodes = [];
		var me = this;
		this.div.find(".TaskMsgTreeNodeCheckbox").each(function() {
			var input = $(this).find("input");
			if(input.get(0).checked && input.val()!="") {
				var node = me.nodes[input.val()];
				if(getData) {
					nodes.push(node);
				} else {
					nodes.push({
						id: node.id,
						name: node.name,
						parentId: node.parentId
					});
				}
			}
		});
		return nodes;
	};

	this.getCheckedLeafNodes = function(getData) {
		var nodes = [];
		var me = this;
		this.div.find(".TaskMsgTreeLeafNodeCheckbox").each(function() {
			var input = $(this).find("input");
			if(input.get(0).checked && input.val()!="") {
				var node = me.leafNodes[input.val()];
				if(getData) {
					nodes.push(node);
				} else {
					nodes.push({
						id: node.id,
						name: node.name,
						parentId: node.parentId
					});
				}
			}
		});
		return nodes;
	};

	this.getCheckedNodesValue = function() {
		var values = "";
		this.div.find(".TaskMsgTreeNodeCheckbox").each(function() {
			var input = $(this).find("input");
			if(input.get(0).checked && input.val()!="") {
				if(values!="") values += ",";
				values += input.val();
			}
		});
		return values;
	};

	this.getCheckedLeafNodesValue = function() {
		var values = "";
		this.div.find(".TaskMsgTreeLeafNodeCheckbox").each(function() {
			var input = $(this).find("input");
			if(input.get(0).checked && input.val()!="") {
				if(values!="") values += ",";
				values += input.val();
			}
		});
		return values;
	};
}

/**
 * 获得当前树形控件
 * @param  {[type]} child [description]
 * @return {[type]}       [description]
 */
function getCurTree(srcElement) {
	var div = $(srcElement).closest(".TaskMsgTree");
	return taskMsgTrees[div.attr("id")];
}

/**
 * 处理节点展开收起按钮点击事件
 * @param  {[type]} img    [description]
 * @param  {[type]} nodeId [description]
 */
function treeNodeToggleIconOnClick(img, nodeId) {
	var tree = getCurTree(img);
    if(!tree.haveChild(nodeId)) return;
	var childNodesDiv = $("#childNodesDiv_"+nodeId);
	var iconColor = "";
	if(img.src.indexOf("deep")>0) iconColor = "deep";
	if(img.src.indexOf(TaskMsgClientAPIDir + "images/toggle")>=0) {
		img.src = TaskMsgClientAPIDir + "images/expand"+iconColor+".png";
		childNodesDiv.hide();
	} else {
		img.src = TaskMsgClientAPIDir + "images/toggle"+iconColor+".png";
		childNodesDiv.show();
	}
}

/**
 * 处理节点选择框点击事件
 * @param  {[type]} cbk    [description]
 * @param  {[type]} nodeId [description]
 */
function treeNodeCbkOnClick (cbk, nodeId) {
	var tree = getCurTree(cbk);
	var node = tree.nodes[nodeId];
	if(cbk.checked) {
    if(tree.multiCheck) {
			if(tree.checkAllChildOnCheckParent) {
				$("#childNodesDiv_"+nodeId).find("input").each(function() {
					$(this).get(0).checked = cbk.checked;
				});
			}
			if(tree.checkParentOnCheckChild) {
				var parentId = node.parentId;
				while(parentId!=tree.rootNodeParentId) {
					var parentNode = tree.nodes[parentId];
					var parentCbk = $("#nodeCbk_"+parentId);
					if(parentCbk.length==0) break;
					parentCbk.get(0).checked = true;
					parentId = parentNode.parentId;
				}
			}
	  } else {
	  	$(":radio").each(function(){
	  		if($(this).attr("id")!="nodeCbk_"+nodeId) $(this).get(0).checked = false;
	  	});
	  }
	} else {
		if(tree.unCheckAllChildOnUnCheckParent) {
			$("#childNodesDiv_"+nodeId).find("input").each(function() {
				$(this).get(0).checked = cbk.checked;
			});
		}
		if(tree.unCheckParentOnUnCheckAllChild) {
			unCheckParent(tree, node);
		}
	}
}

/**
 * 处理叶节点选择框点击事件
 * @param  {[type]} cbk    [description]
 * @param  {[type]} nodeId [description]
 */
function treeLeafNodeCbkOnClick (cbk, nodeId) {
	var tree = getCurTree(cbk);
	var node = tree.leafNodes[nodeId];
	if(cbk.checked) {
		if(tree.multiCheck) {
			if(tree.checkParentOnCheckChild) {
				var parentId = node.parentId;
				while(parentId!=tree.rootNodeParentId) {
					var parentNode = tree.nodes[parentId];
					var parentCbk = $("#nodeCbk_"+parentId);
					if(parentCbk.length==0) break;
					parentCbk.get(0).checked = true;
					parentId = parentNode.parentId;
				}
			}
		} else {
	  	$(":radio").each(function(){
	  		if($(this).attr("id")!="leafNodeCbk_"+nodeId) $(this).get(0).checked = false;
	  	});
		}
	} else {
		if(tree.unCheckParentOnUnCheckAllChild) {
			unCheckParent(tree, node);
		}
	}
}

/**
 * 取消选中父节点
 * @param  {[type]} tree [description]
 * @param  {[type]} node [description]
 */
function unCheckParent(tree, node) {
	var parentId = node.parentId;
	if(parentId==tree.rootNodeParentId) return;
	var parentNode = tree.nodes[parentId];
	for(var i=0;i<parentNode.childNodes.length;i++) {
		var childCbk = $("#nodeCbk_"+parentNode.childNodes[i]);
		if(childCbk.length==0) continue;
		if(childCbk.get(0).checked) return;
	}
	if(tree.showLeafNodeCheckbox && parentNode.leafNodes) {
		for(var i=0;i<parentNode.leafNodes.length;i++) {
			var childCbk = $("#nodeCbk_"+parentNode.leafNodes[i]);
			if(childCbk.length==0) continue;
			if(childCbk.get(0).checked) return;
		}
	}
	
	var parentCbk = $("#nodeCbk_"+parentId);
	if(parentCbk.length==0) return;
	parentCbk.get(0).checked = false;
	unCheckParent(tree, parentNode);
}

/**
 * 处理节点点击事件
 * @param  {[type]} srcElement [description]
 * @param  {[type]} nodeId     [description]
 */
function treeNodeOnClick(srcElement, nodeId) {
	var tree = getCurTree(srcElement);
	if(tree.nodeOnClick) eval(tree.nodeOnClick+"("+nodeId+")");
	var img = $(srcElement).parent().find("img").get(0);
	treeNodeToggleIconOnClick(img, nodeId);
}

/**
 * 处理叶节点点击事件
 * @param  {[type]} srcElement [description]
 * @param  {[type]} nodeId     [description]
 */
function treeLeafNodeOnClick(srcElement, nodeId) {
	var tree = getCurTree(srcElement);
	if(tree.leafNodeOnClick) eval(tree.leafNodeOnClick+"("+nodeId+")");
}

function treeNodeOnMouseOver(srcElement, nodeId) {
	var tree = getCurTree(srcElement);
	var onMouseOverBgColor = "#666666";
	if(tree.iconColor=="deep") {
		onMouseOverBgColor = "#EEEEEE";
	}
	$(srcElement).css("background-color", onMouseOverBgColor);
	$("#nodeDelBtn_"+nodeId).show();
	$("#nodeEditBtn_"+nodeId).show();
}

function treeNodeOnMouseOut(srcElement, nodeId) {
	$(srcElement).css("background-color", "");
	$("#nodeDelBtn_"+nodeId).hide();
	$("#nodeEditBtn_"+nodeId).hide();
}

function leafNodeOnMouseOver(srcElement, nodeId) {
	var tree = getCurTree(srcElement);
	var onMouseOverBgColor = "#666666";
	if(tree.iconColor=="deep") {
		onMouseOverBgColor = "#EEEEEE";
	}
	$(srcElement).css("background-color", onMouseOverBgColor);
	$("#leafNodeDelBtn_"+nodeId).show();
	$("#leafNodeEditBtn_"+nodeId).show();
}

function leafNodeOnMouseOut(srcElement, nodeId) {
	$(srcElement).css("background-color", "");
	$("#leafNodeDelBtn_"+nodeId).hide();
	$("#leafNodeEditBtn_"+nodeId).hide();
}

/**
 * 处理节点编辑按钮点击事件
 * @param  {[type]} srcElement [description]
 * @param  {[type]} nodeId     [description]
 */
function nodeEditButtonOnClick(srcElement, nodeId) {
	var tree = getCurTree(srcElement);
	if(tree.nodeEditButtonOnClick) {
		var node = tree.nodes[nodeId];
		eval(tree.nodeEditButtonOnClick+"(node)");
	}
}

/**
 * 处理节点删除按钮点击事件
 * @param  {[type]} srcElement [description]
 * @param  {[type]} nodeId     [description]
 */
function nodeDeleteButtonOnClick(srcElement, nodeId) {
	if(!confirm("确定删除？")) return;
	var tree = getCurTree(srcElement);
	if(tree.nodeDeleteButtonOnClick) {
		eval(tree.nodeDeleteButtonOnClick+"("+nodeId+")");
	} else if(tree.deleteNodeService) {
		var args = {};
		args[tree.nodeIdFieldName] = nodeId;
		args.childs = "";
		var nodeDiv = $("#childNodesDiv_"+nodeId);
		nodeDiv.find(".TaskMsgTreeNode").each(function() {
			if(args.childs!="") args.childs += ",";
			args.childs += $(this).attr("nodeId");
		});
		var service = new TaskMsgService(tree.deleteNodeService);
		service.srcElement = srcElement;
		service.request(args, onDeleteTreeNode);
	}
}

function onDeleteTreeNode(req, res) {
	var tree = getCurTree(req.srcElement);
	var nodeId = req[tree.nodeIdFieldName];
	tree.deleteNode(nodeId);
}

/**
 * 处理叶节点编辑按钮点击事件
 * @param  {[type]} srcElement [description]
 * @param  {[type]} nodeId     [description]
 */
function leafNodeEditButtonOnClick(srcElement, nodeId) {
	var tree = getCurTree(srcElement);
	if(tree.leafNodeEditButtonOnClick) eval(tree.leafNodeEditButtonOnClick+"("+nodeId+")");
}

/**
 * 处理叶节点删除按钮点击事件
 * @param  {[type]} srcElement [description]
 * @param  {[type]} nodeId     [description]
 */
function leafNodeDeleteButtonOnClick(srcElement, nodeId) {
	var tree = getCurTree(srcElement);
	if(tree.leafNodeDeleteButtonOnClick) eval(tree.leafNodeDeleteButtonOnClick+"("+nodeId+")");
}

/**
 * 在页面加载完后初始化当前页面内的所有树形控件
 */
$(function() {
  $(".TaskMsgTree").each(function(index) {
    var tree = new TaskMsgTree();
    if($(this).attr("id")) {
      tree.id = $(this).attr("id");
    } else {
      tree.id = "TaskMsgTree_"+index;
      $(this).attr("id", tree.id);
    }
    taskMsgTrees[tree.id] = tree;
    tree.init($(this));
  });
});