/**
 *************************************************************************************
 * [标题：ExmayUI JQuery Tree 插件]<br>
 *************************************************************************************
 * [描述：ExmayUI JQuery Tree 插件]<br>
 *************************************************************************************
 * @author Exmay Team / 亿美团队
 *************************************************************************************
 * @version Version 1.0.1 Beta / v1.0.1 测试版
 *************************************************************************************
 */

/*
 * ***********************************************************************************
 * 版权：Copyright © 2012 Exmay Inc. All Rights Reserved. 长沙亿美软件有限公司　版权所有
 * ***********************************************************************************
 * 企业文化：专注　创新　分享　共赢
 * ***********************************************************************************
 * 官方网站：http://www.exmay.com
 * ***********************************************************************************
 * 官方邮箱：service@exmay.com
 * ***********************************************************************************
 */

(function($) {

	// 初始化树
	function initExmayTree(obj, opts) {
		var $obj = $(obj);

		$obj.addClass("exmayui-tree");

		initExmayNode($obj, 0);

		// 初始化节点
		function initExmayNode(ul, depth) {

			// 遍历所有节点
			$(">li", ul).each(function() {
				// 节点
					var $node = $('<div class="exmayui-tree-node"></div>').prependTo($(this));

					// 单选复选
					// 复选(优先)
					if (opts.checkbox) {
						$('<span class="exmayui-tree-checkbox exmayui-checkbox-unchecked"></span>').prependTo($node);
					} else {
						if (opts.radio) {
							$('<span class="exmayui-tree-radio exmayui-tree-radio-0"></span>').prependTo($node);
						}
					}

					// 标题
					var text = $(">span", this).addClass("exmayui-tree-title").appendTo($node).text();

					// 缓存文本
					$node.data("tree-node", {
						text : text,
						url : $(this).attr("url"),
						img : $(this).attr("img"),
						icon : $(this).attr("icon")
					});

					// 子树
					var subTree = $(">ul", this);

					var $folder = $('<span class="exmayui-tree-file-icon exmayui-tree-folder exmayui-tree-folder-open"></span>').addClass($node.icon).prependTo($node);

					if (subTree.length) {
						// 文件夹
						$folder.addClass("exmayui-tree-folder exmayui-tree-folder-open");
						if(opts.disabledNode == "parent") {
							$node.addClass("exmayui-tree-li-disabled");	
						}
						// 展开
						var $expanded = $('<span class="exmayui-tree-hit exmayui-tree-expanded"></span>').prependTo($node);
						if ($(this).next("li").length == 0) {
							if ($(this).prev("li").length != 0) {
								$node.addClass("exmayui-tree-last-li");
							}
						} else {
							$(this).addClass("exmayui-tree-li-li");
//							if(opts.disabledNode == "parent") {
//								$node.addClass("exmayui-tree-li-disabled");	
//							}
						}
						// 递归
						initExmayNode(subTree, depth + 1);
					} else {
						// 文件
						$folder.addClass("exmayui-tree-file");
						if ($(this).next("li").length == 0) {
							$('<span class="exmayui-tree-last-li"></span>').prependTo($node);
						} else {
							$('<span class="exmayui-tree-li"></span>').prependTo($node);
							$(this).addClass("exmayui-tree-li-li");
//							$node.addClass("exmayui-tree-li-disabled");
						}
					}

					// 背景图片处理
					if ($(this).attr("img")) {
						$('<img src="' + $(this).attr("img") + '" />').appendTo($folder);
						$folder.css( {
							backgroundImage : "none"
						});
					}
					if ($(this).attr("icon")) {
						$folder.removeClass();
						$folder.addClass("exmayui-tree-file-icon");
						$folder.addClass($(this).attr("icon"));
					}

				});
		}
		return $obj;
	}
	;

	// 加载远程数据到UL标签内
	function exmayLoadData(obj, ul, param) {
		var opts = $(obj).data("tree").options;
		if (!opts.url)
			return;

		param = param || {};
		
		/*$("body").exmayLoading({
			msg : "数据加载中，请稍候...",
			show : true
		});*/
		
		if (opts.onLoading) {
			opts.onLoading.apply(this, arguments);
		}
		
		var folder = $(ul).prev().find('>span.exmayui-tree-folder');
		folder.addClass('exmayui-tree-loading');
		// AJAX加载JSON数据
		$.ajax( {
			type : 'post',
			url : opts.url,
			data : param,
			dataType : 'json',
			beforeSend : function(data) {
				if(opts.loadEven != "noLoad") {
					if (opts.onBeforeLoad) {
						opts.onBeforeLoad.apply(this, arguments);
						opts.loadEven = "noLoad";
					}
				}
			},
			success : function(data) {
				//alert(data);
				folder.removeClass('exmayui-tree-loading');
				// 加载JSON数据
			initExmayTreeFromJSON(obj, ul, data[opts.entity]);
			// 绑定事件
			bindExmayTreeEvents(obj);
			//$("body").exmayLoading("hide");
			if (opts.onLoadSuccess) {
				opts.onLoadSuccess.apply(this, arguments);
			}
		},
		error : function() {
			folder.removeClass('exmayui-tree-loading');
			if (opts.onLoadError) {
				opts.onLoadError.apply(this, arguments);
			}
		}
		});
	}
	;

	// 加载JSON数据
	function initExmayTreeFromJSON(obj, ul, data) {

		var opts = $(obj).data("tree").options;
		
		// 当为根时清除内容
		if (obj == ul) {
			if(opts.loadEven != "noLoad") {
				$(obj).empty();
			}
		}

		if (opts.clear) {
			if(opts.loadEven != "noLoad") {
				$(obj).empty();
			}
		};

		exmayAppendNodes(ul, data, 0);

		function exmayAppendNodes(ul, children, depth) {

			for ( var i = 0; i < children.length; i++) {
				var li = $('<li></li>').appendTo(ul);
				var item = children[i];

				// 打开还是关闭
				if (item.state != 'open' && item.state != 'closed') {
					item.state = 'open';
				}

				var node = $('<div class="exmayui-tree-node"></div>').appendTo(li);
				node.attr('node-id', item.id);
				node.attr('json', exmayToJsonStringify(item));

				// 缓存节点属性
				node.data("tree-node", {
					id : item.id,
					text : item.text,
					url : item.url,
					img : item.img,
					icon : item.icon,
					attributes : item.attributes
				});

				// 树标题
				$('<span class="exmayui-tree-title"></span>').html(item.text).appendTo(node);

				// 单选复选
				if (opts.checkbox) {
					if (item.checked) {
						$('<span class="exmayui-tree-checkbox exmayui-checkbox-checked"></span>').prependTo(node);
					} else {
						$('<span class="exmayui-tree-checkbox exmayui-checkbox-unchecked"></span>').prependTo(node);
					}
					var parent = exmayGetParentNode(obj, node[0]);
				} else {
					if (opts.radio) {
						$('<span class="exmayui-tree-radio exmayui-tree-radio-0"></span>').prependTo(node);
					}
				}

				// 子节点
				if (item.children) {
					var subul = $('<ul></ul>').appendTo(li);
					if (item.state == 'open') {
						$('<span class="exmayui-tree-file-icon exmayui-tree-folder exmayui-tree-folder-open"></span>').addClass(item.icon).prependTo(node);
						$('<span class="exmayui-tree-hit exmayui-tree-expanded"></span>').prependTo(node);
						if(opts.disabledNode == "parent") {
							node.addClass("exmayui-tree-li-disabled");	
						}
					} else {
						$('<span class="exmayui-tree-file-icon exmayui-tree-folder"></span>').addClass(item.icon).prependTo(node);
						$('<span class="exmayui-tree-hit exmayui-tree-collapsed"></span>').prependTo(node);
						subul.css('display', 'none');
						if(opts.disabledNode == "parent") {
							node.addClass("exmayui-tree-li-disabled");	
						}
					}

					if (i == children.length - 1) {
						if (i != 0) {
							node.addClass("exmayui-tree-last-li");
						}
					} else {
						li.addClass("exmayui-tree-li-li");
//						if(opts.disabledNode == "parent") {
//							node.addClass("exmayui-tree-li-disabled");	
//						}
					}

					exmayAppendNodes(subul, item.children, depth + 1);

				} else {
					if (item.state == 'closed') {
						$('<span class="exmayui-tree-file-icon exmayui-tree-folder"></span>').addClass(item.icon).prependTo(node);
						$('<span class="exmayui-tree-hit exmayui-tree-collapsed"></span>').prependTo(node);
						if(opts.disabledNode == "parent") {
							node.addClass("exmayui-tree-li-disabled");	
						}
					} else {
						//						$('<input type="checkbox" style="vertical-align:bottom;margin:0;height:18px;">').prependTo(node);
						$('<span class="exmayui-tree-file-icon exmayui-tree-file"></span>').addClass(item.icon).prependTo(node);
					}
					if (i == children.length - 1) { // 末节点
						//if(i != 0) {
						if (item.state != 'closed') { // 如果节点不属于关闭类型 // 有子节点的末节点
							$('<span class="exmayui-tree-last-li"></span>').prependTo(node);
						}
						//}

						// 无子节点的末节点
						// 有子节点的末节点

					} else { // 中间节点
						if (item.state != 'closed') {
							$('<span class="exmayui-tree-li"></span>').prependTo(node);
						}
						li.addClass("exmayui-tree-li-li");
//						if(opts.disabledNode == "parent") {
//							node.addClass("exmayui-tree-li-disabled");	
//						}
					}
				}

			}
		}

	}
	;

	// 绑定树事件
	function bindExmayTreeEvents(obj) {
		var $obj = $(obj);
		var opts = $obj.data("tree").options;
		var $tree = $obj.data("tree").exmayTree;
		// 展开或收缩事件绑定
		$(".exmayui-tree-hit", $tree).unbind(".exmayTree").bind("click.exmayTree", function() {
			var $node = $(this).parent();
			//			$(".tree-node-selected", $tree).removeClass("tree-node-selected");
				//			$(this).siblings(".tree-title").addClass("tree-node-selected");
				exmayToggleNode(obj, $node[0]);
				return false;
			}).bind("mouseover.exmayTree", function() {
			//			if ($(this).hasClass("tree-expanded")){
				//				$(this).addClass("tree-expanded-hover");
				//			} else {
				//				$(this).addClass("tree-collapsed-hover");
				//			}
			}).bind("mouseout.exmayTree", function() {
			//			if ($(this).hasClass("tree-expanded")){
				//				$(this).removeClass("tree-expanded-hover");
				//			} else {
				//				$(this).removeClass("tree-collapsed-hover");
				//			}
			});

		$('.exmayui-tree-file-icon', $tree).unbind('.exmayTree').bind("click.exmayTree", function() {
			$('.exmayui-tree-node-selected', $tree).removeClass('exmayui-tree-node-selected');
			$(this).siblings(".exmayui-tree-title").addClass('exmayui-tree-node-selected');
		}).bind('dblclick.exmayTree', function() {
			$(this).siblings(".exmayui-tree-hit").trigger("click");

			if (opts.onDblClick) {
				var data = $(this).parent(".exmayui-tree-node").data("tree-node");
				opts.onDblClick.call(this, {
					id : data.id,
					text : data.text,
					url : data.url,
					img : data.img,
					icon : data.icon,
					attributes : data.attributes,
					obj : this
				});
			}
			return false;
		});

		// 标题点击事件
		$(".exmayui-tree-title", $tree).unbind(".exmayTree").bind('click.exmayTree', function() { // 单击
					$('.exmayui-tree-node-selected', $tree).removeClass('exmayui-tree-node-selected');
					$(this).addClass('exmayui-tree-node-selected');
					if (opts.isOpen) {
						$(this).siblings(".exmayui-tree-hit").trigger("click");
					}
					if(!$(this).parent().hasClass("exmayui-tree-li-disabled")) {
						if (opts.onClick) {
							var data = $(this).parent(".exmayui-tree-node").data("tree-node");
							opts.onClick.call(this, {
								id : data.id,
								text : data.text,
								url : data.url,
								img : data.img,
								icon : data.icon,
								attributes : data.attributes,
								target : this
							});
	
						}
					} else {
						$(this).siblings(".exmayui-tree-hit").trigger("click");
					}

					//return false;
				}).bind('mouseover.exmayTree', function() { // 鼠标悬停
					$(this).addClass('exmayui-tree-node-hover');
					return false;
				}).bind('mouseout.exmayTree', function() { // 鼠标离开
					$(this).removeClass('exmayui-tree-node-hover');
					return false;
				});

		function exmayToggleCheckbox(target, flag) {
			if (opts.checkboxName) {
				if (flag) {
					var id = $(target).parent().attr("node-id");
					if (id) {
						$('<input class="exmay-ui-checkbox" type="hidden" name="' + opts.checkboxName + '" value="' + id + '"/>').insertAfter(target);
					}
				} else {
					$(target).parent().find(".exmay-ui-checkbox").remove();
				}

			}
		}
		;
		
		// 复选事件绑定
		$(".exmayui-tree-checkbox", $tree).unbind(".exmayTree").bind("click.exmayTree", function() {
			if ($(this).hasClass("exmayui-checkbox-unchecked")) {
				$(this).removeClass("exmayui-checkbox-unchecked").addClass("exmayui-checkbox-checked");
				exmayToggleCheckbox(this,true);
			} else if ($(this).hasClass("exmayui-checkbox-checked")) {
				$(this).removeClass("exmayui-checkbox-checked").addClass("exmayui-checkbox-unchecked");
				exmayToggleCheckbox(this,false);
			} else if ($(this).hasClass("exmayui-checkbox-undetermined")) {
				$(this).removeClass("exmayui-checkbox-undetermined").addClass("exmayui-checkbox-checked");
				exmayToggleCheckbox(this,true);
			}
			if(opts.cascade) {
				setParentCheckbox($(this).parent());
				exmaySetChildrenCheckbox($(this).parent());
			}
				return false;
			});

		// 设置父节点选框
		function setParentCheckbox($node) {
			var parent = exmayGetParentNode(obj, $node[0]);
			if (parent) {
				var $parent = $(parent.target);
				var $checkbox = $parent.find(".exmayui-tree-checkbox");
				$checkbox.removeClass("exmayui-checkbox-unchecked exmayui-checkbox-checked exmayui-checkbox-undetermined");
				if (exmayIsAllChildrenCheked($node)) {
					$checkbox.addClass("exmayui-checkbox-checked");
					exmayToggleCheckbox($checkbox[0],true);
				} else if (exmayIsAllChildrenUnchecked($node)) {
					$checkbox.addClass("exmayui-checkbox-unchecked");
					exmayToggleCheckbox($checkbox[0],false);
				} else {
					$checkbox.addClass("exmayui-checkbox-undetermined");
					exmayToggleCheckbox($checkbox[0],false);
				}
				// 递归
				setParentCheckbox($parent);
			}
			;
		}
		;

		// 设置子节点选框
		function exmaySetChildrenCheckbox($node) {
			var $childrenCheckbox = $node.next().find(".exmayui-tree-checkbox");
			$childrenCheckbox.removeClass("exmayui-checkbox-unchecked exmayui-checkbox-checked exmayui-checkbox-undetermined")
			if ($node.find(".exmayui-tree-checkbox").hasClass("exmayui-checkbox-checked")) {
				$childrenCheckbox.addClass("exmayui-checkbox-checked");
				$childrenCheckbox.each(function(){
					exmayToggleCheckbox(this,true);
				});
			} else {
				$childrenCheckbox.addClass("exmayui-checkbox-unchecked");
				$childrenCheckbox.each(function(){
					exmayToggleCheckbox(this,false);
			});
			}
		}
		;

	}
	;

	// 所有选中
	function exmayIsAllChildrenCheked($node) {
		var $checkbox = $node.find(".exmayui-tree-checkbox");
		if ($checkbox.hasClass("exmayui-checkbox-unchecked") || $checkbox.hasClass("exmayui-checkbox-undetermined"))
			return false;
		var exmayIsAllChildrenCheked = true;
		$node.parent().siblings().each(function() {
			if (!$(this).find(".exmayui-tree-checkbox").hasClass("exmayui-checkbox-checked")) {
				exmayIsAllChildrenCheked = false;
			}
		});
		return exmayIsAllChildrenCheked;
	}

	// 全部没选中
	function exmayIsAllChildrenUnchecked($node) {
		var $checkbox = $node.find(".exmayui-tree-checkbox");
		if ($checkbox.hasClass("exmayui-checkbox-checked") || $checkbox.hasClass("exmayui-checkbox-undetermined"))
			return false;
		var exmayIsAllChildrenUnchecked = true;
		$node.parent().siblings().each(function() {
			if (!$(this).find(".exmayui-tree-checkbox").hasClass("exmayui-checkbox-unchecked")) {
				exmayIsAllChildrenUnchecked = false;
			}
		});
		return exmayIsAllChildrenUnchecked;
	}

	// 处理节点
	function exmayToggleNode(obj, $node) {
		var $hit = $(">span.exmayui-tree-hit", $node);
		if ($hit.length == 0)
			return; // is a leaf node

		if ($hit.hasClass("exmayui-tree-expanded")) {
			exmayrCollapseNode(obj, $node);
		} else {
			exmayrExpandNode(obj, $node);
		}
	}
	;

	// 展开节点
	function exmayrExpandNode(obj, node) {
		var $obj = $(obj);
		var opts = $obj.data("tree").options;

		var $hit = $(">span.exmayui-tree-hit", node);
		if ($hit.length == 0)
			return; // is a leaf node

		if ($hit.hasClass("exmayui-tree-collapsed")) {
			$hit.removeClass("exmayui-tree-collapsed exmayui-tree-collapsed-hover").addClass("exmayui-tree-expanded");
			$hit.next().addClass("exmayui-tree-folder-open");
			var $ul = $(node).next();
			if ($ul.length) {
				// 是否有动画效果
				if (opts.animate) {
					$ul.slideDown();
				} else {
					$ul.css("display", "block");
				}
			} else {
				var id = $(node).data("tree-node").id;
				var $subUl = $("<ul></ul>").insertAfter(node);
				//exmayLoadData(obj, $subUl, {id:id,dir:id});	// request children nodes data
				if (opts.parentKey != "dir") {
					exmayLoadData(obj, $subUl, {
						id : id
					});
				} else {
					exmayLoadData(obj, $subUl, {
						dir : id
					}); // request children nodes data
				}
			}
		}
	}
	;

	// 收缩节点
	function exmayrCollapseNode(obj, node) {
		var $obj = $(obj);
		var opts = $obj.data("tree").options;

		var $hit = $(">span.exmayui-tree-hit", node);
		if ($hit.length == 0)
			return; // is a leaf node

		if ($hit.hasClass("exmayui-tree-expanded")) {
			$hit.removeClass("exmayui-tree-expanded exmayui-tree-expanded-hover").addClass("exmayui-tree-collapsed");
			$hit.next().removeClass("exmayui-tree-folder-open");
			// 是否有动画效果
			if (opts.animate) {
				$(node).next().slideUp();
			} else {
				$(node).next().css("display", "none");
			}
		}
	}
	;

	// 获取父结点
	function exmayGetParentNode(target, data) {
		var $node = $(data).parent().parent().prev();
		if ($node.length) {
			return $.extend( {}, $node.data("exmayui-tree-node"), {
				target : $node[0],
				checked : $node.find(".exmayui-tree-checkbox").hasClass("exmayui-checkbox-checked")
			});
		} else {
			return null;
		}
	}
	;

	// 获取所有选中节点
	function exmayGetCheckedNode(obj) {
		var nodes = [];
		$(obj).find(".exmayui-checkbox-checked").each(function() {
			var node = $(this).parent();
			nodes.push($.extend( {}, $.data(node[0], "exmayui-tree-node"), {
				obj : node[0],
				checked : node.find(".tree-checkbox").hasClass("exmayui-checkbox-checked")
			}));
		});
		return nodes;
	}
	
	function exmayGetCheckJsonData(obj) {
		var nodes = [];
		$(obj).find(".exmayui-checkbox-checked").each(function() {
			var node = $(this).parent();
			var jsonData = {
				id:node.attr("node-id"),
				json:node.attr("json")
			}	
			nodes.push(jsonData);
		});
		return nodes;
	}

	function exmayGetChekedItems(target) {
		return $(target).find(".exmayui-checkbox-checked");
	}

	function exmaySetChekedItems(target, data) {
		var ids = data;
		var opts = $(target).data("tree").options;
		opts.cascade = false;
		for ( var i = 0; i < ids.length; i++) {
			var nodeId = ids[i];
			var $node = $("div[node-id='" + nodeId + "']", target);
			$(".exmayui-tree-checkbox", $node).trigger("click");
		}
		opts.cascade = true;
	}

	function exmayGetSelectedNode(obj){
		var node = $(obj).find('span.exmayui-tree-node-selected');
		if (node.length){
			return node.parent();
		} else {
			return null;
		}
	}

	function exmayGetOptions($obj) {
		return {
			url : $obj.attr("url"),
			checkbox : ($obj.attr("checkbox") ? $obj.attr("checkbox") == "true" : undefined),
			animate : ($obj.attr("animate") ? $obj.attr("animate") == "true" : undefined),
			disabledNode : $obj.attr("disabledNode"),
			checkboxName : $obj.attr("checkboxName")
		}
	}
	;

	$.fn.exmayTree = function(options, param) {
		if (typeof options == "string") {
			switch (options) {
			case "options":
				return $.data(this[0], "tree").options;
			case "reload":
				return this.each(function() {
					$(this).empty();
					exmayLoadData(this, this);
				});
			case "getJosnData":return exmayGetCheckJsonData(this[0]);
			case "getParent":
				return exmayGetParentNode(this[0], param);
			case "getChecked":
				return exmayGetCheckedNode(this[0]);
			case "getCheckedItems":
				return exmayGetChekedItems(this[0]);
			case "setCheckedItems":
				return exmaySetChekedItems(this[0], param);
			case "getSelected":
				return exmayGetSelectedNode(this[0]);
			case "getFirstNode":
				return exmayGetFirstNode(this[0]);
			case "isLeaf":
				return exmayIsLeaf(this[0], param);
			case "select":
				return this.each(function() {
					exmayrSelectNode(this, param);
				});
			case "collapse":
				return this.each(function() {
					exmayrCollapseNode(this, $(param));
					});
			case "expand":
				return this.each(function() {
					exmayrExpandNode(this, $(param));
					});
			case "append":
				return this.each(function() {
					exmayAppendNodes(this, param);
				});
			case "toggle":
				return this.each(function() {
					exmayToggleNode(this, $(param));
				});
			case "remove":
				return this.each(function() {
					exmayrRemoveNode(this, param);
				});
			}
		}

		var options = options || {};

		return this.each(function() {
			var $this = $(this);
			var cache = $this.data("tree");
			var opts = null;
			var flag = true;
			if (cache) {
				if(cache.options.url) {
					flag = false;
				}
				opts = $.extend(cache.options, options);
				cache.options = opts;
				if(!opts.cache) {
					flag = true;
				}
			} else {
				opts = $.extend( {}, $.fn.exmayTree.defaults, exmayGetOptions($this), options);
				$this.data("tree", {
					exmayTree : initExmayTree(this, opts),
					options : opts
				});
				//				exmayLoadData(this, this);
			}
			if (flag) {
				if (opts.url) {
					if(opts.loadEven == "noLoad") {
						$(this).empty();
						opts.loadEven = "init"
					};
					exmayLoadData(this, $this, opts.data);
				} else {
					bindExmayTreeEvents(this);
				}
			}
		});
	};

	$.fn.exmayTree.defaults = {
		url : null, // URL
		animate : false, // 特效
		radio : false, // 是否单选
		checkbox : false, // 是否复选
		cascade : true, // 是否级联复选
		checkboxName : null, // 复选名称
		showDeep : 1, // 展示深度
		entity : "items", // 实体
		//text : "name", // 名称
		clear : false, // 清空
		data : null,
		parentKey : "id",
		isOpen : false, // 是否打开子无素
		disabledNode : "",
		cache : true, // 是否缓存
		loadEven : "load", // 初次/每次加载事件
		onLoading : function(){
		},
		onLoadSuccess : function() {
		}, // 数据加载成功
		onLoadError : function() {
		}, // 数据加载失败
		onClick : function(node) {
		}, // node: id,text,attributes,target
		onDblClick : function(node) {
		} // node: id,text,attributes,target
	};

})(jQuery);
