/* Author: yangzeming
 * Date: 2013-12-10
 * Desc: 树组件
 */
define("component/tree", function (require, exports, module) {

    var Tree = _.Class({
        initial: function (options) {
            this._eventStack = {};
            var defaultOp = {
                con: "",
                template: [],
                data: [{ id: '11', pId: '-1', name: '首页', open: true }, { id: '12', pId: '-1', name: '管控', open: true }, { id: '13', pId: '12', name: '方案管理' }, { id: '14', pId: '12', name: '预警管理' }, { id: '15', pId: '-1', name: '查询', open: true }, { id: '16', pId: '15', name: '布控人员查询' }, { id: '17', pId: '15', name: '数据源查询' }, { id: '18', pId: '15', name: '背景审查' }, { id: '19', pId: '15', name: '图像查询' }, { id: '20', pId: '-1', name: '统计', open: true }, { id: '21', pId: '20', name: '数据源统计' }, { id: '22', pId: '20', name: '预警统计' }, { id: '23', pId: '20', name: '待定' }, { id: '24', pId: '-1', name: '监控', open: true }, { id: '25', pId: '24', name: '在线值班' }, { id: '26', pId: '24', name: '系统监控' }, { id: '27', pId: '-1', name: '管理', open: true }, { id: '28', pId: '27', name: '系统管理'}],
                key: {
                    children: "children",
                    name: "name",
                    title: "",
                    url: "url"
                },
                hasCheck: true,
                rootName: "系统权限管理",
                dataTemplate: {
                    idKey: "id",
                    pIdKey: "pId"


                }
            };
            this.options = $.extend(true, {}, defaultOp, options);
            this.rootData = {};
            this.rootData[this.options.key.children] = this.transformTozTreeFormat(this.options, this.options.data);
            this.rootData[this.options.key.name] = this.options.rootName;
            this.rootData["id"] = "root";
            this.rootData["open"] = true;
            var _html = this.appendNodes(this.options, 0, [this.rootData], null, true, true);
            this.$con = $(this.options.con);
            this.$con.html(_html);
            this.$node = this.$con.find('[data-role="node"]');
            this.bindEvent();

        },
        /*
        *   id:{
        data : {},
        sub : []
        }
        */
        transformToArrayFormat: function (options, nodes) {
            if (!nodes) return [];
            var childKey = this.options.key.children,
			r = [];
            if (_.isArray(nodes)) {
                for (var i = 0, l = nodes.length; i < l; i++) {
                    r.push(nodes[i]);
                    if (nodes[i][childKey])
                        r = r.concat(data.transformToArrayFormat(setting, nodes[i][childKey]));
                }
            } else {
                r.push(nodes);
                if (nodes[childKey])
                    r = r.concat(data.transformToArrayFormat(setting, nodes[childKey]));
            }
            return r;
        },
        transformTozTreeFormat: function (setting, sNodes) {
            var i, l,
			key = setting.dataTemplate.idKey,
			parentKey = setting.dataTemplate.pIdKey,
			childKey = setting.key.children;
            if (!key || key == "" || !sNodes) return [];

            if ($.isArray(sNodes)) {
                var r = [];
                var tmpMap = [];
                for (i = 0, l = sNodes.length; i < l; i++) {
                    tmpMap[sNodes[i][key]] = sNodes[i];
                }
                for (i = 0, l = sNodes.length; i < l; i++) {
                    if (tmpMap[sNodes[i][parentKey]] && sNodes[i][key] != sNodes[i][parentKey]) {
                        if (!tmpMap[sNodes[i][parentKey]][childKey])
                            tmpMap[sNodes[i][parentKey]][childKey] = [];
                        tmpMap[sNodes[i][parentKey]][childKey].push(sNodes[i]);
                    } else {
                        r.push(sNodes[i]);
                    }
                }
                return r;
            } else {
                return [sNodes];
            }
        },
        render: function (level, node, parentNode, isFirstNode, isLastNode, openFlag, hasChild) {
            var _html = "",
                hasCheck = this.options.hasCheck;
            if (isFirstNode) {
                _html += (level == 0 ? '<ul data-level="' + level + '" data-open="' + openFlag + '">' : '<ul class="tree_line" data-level="' + level + '" data-open="' + openFlag + '">');
            }
            // button ico_docu
            _html += '<li><div data-role="node" data-id="' + node.id + '" data-name="' + node.name + '" data-parent="" data-child="" data-level="' + level + '">';
            if (hasChild) {
                if (openFlag) {
                    _html += '<div class="root_open" data-state="open" data-role="nodespanBtn"></div>';
                    if (hasCheck) {
                        _html += '<input type="button" data-role="nodeCheckBtn" data-state="no" class="check_box" value=""/>';
                    }

                    _html += '<span class="button ico_open"></span><label  data-role="label"  data-state="no"> ' + node.name + '</label></div>';
                } else {
                    _html += '<div class="bottom_close" data-state="close" data-role="nodespanBtn"></div>';
                    if (hasCheck) {
                        _html += '<input type="button" data-role="nodeCheckBtn" data-state="no" class="check_box" value=""/>';
                    }
                    _html += '<span class="button ico_open"></span><label data-role="label" data-state="no"> ' + node.name + '</label></div>';
                }
            } else {
                if (isLastNode) {
                    _html += '<div class="bottom_docu"></div>';
                    if (hasCheck) {
                        _html += '<input type="button" data-role="nodeCheckBtn" data-state="no" class="check_box" value=""/>';
                    }
                    _html += '<span class="button ico_docu"></span><label  data-state="no" data-role="label"> ' + node.name + '</label></div>';
                } else {
                    _html += '<div class="center_docu"></div>';
                    if (hasCheck) {
                        _html += '<input type="button" data-role="nodeCheckBtn" data-state="no" class="check_box" value=""/>';
                    }
                    _html += '<span class="button ico_docu"></span><label  data-state="no" data-role="label"> ' + node.name + '</label></div>';
                }
            }

            /* if (isLastNode) {
            _html += '</li></ul>';
            } else {
            _html += '</li>';
            }*/
            return _html;
        },
        bindEvent: function () {
            var self = this;
            // 关闭不必要的子节点
            //this.$con.find('[data-open="undefined"]').hide();
            this.$con.find('[data-state="close"]').closest("li").find('[data-open="undefined"]').hide();
            var hasCheck = this.options.hasCheck;

            this.$node.delegate('[data-role="nodespanBtn"]', "click", function () {
                var that = $(this),
                    sta = $(this).data("state"),
                    level = that.closest('[data-level]').data("level") + 1;
                if (sta == "open") {
                    that.closest("li").find('[data-level="' + level + '"]').hide();
                    that.attr("data-state", "close");
                    that.data("state", "close");
                    that.removeClass("root_open").addClass("bottom_close");
                    self.trigger("colse", that.parent().data("id"), that.parent().data("name"));
                } else {
                    that.closest("li").find('[data-level="' + level + '"]').show();
                    that.attr("data-state", "open");
                    that.data("state", "open");
                    that.removeClass("bottom_close").addClass("root_open");
                    self.trigger("open", that.parent().data("id"), that.parent().data("name"));
                }
            });
            if (hasCheck) {
                this.$node.delegate('[data-role="nodeCheckBtn"]', "click", function () {
                    var that = $(this),
                    data = $(this).data("state"),
                    level = that.closest('[data-level]').data("level") + 1;
                    if (data == "no") {
                        that.closest("li").find('[data-level="' + level + '"]').find('[data-role="nodeCheckBtn"]').attr("data-state", "check").data("state", "check").addClass("on");
                        that.attr("data-state", "check");
                        that.data("state", "check");
                        that.addClass("on");
                        self.trigger("oncheck", that.parent().data("id"), that.parent().data("name"));

                    } else {
                        self.trigger("discheck", that.parent().data("id"), that.parent().data("name"));
                        that.closest("li").find('[data-level="' + level + '"]').find('[data-role="nodeCheckBtn"]').attr("data-state", "no").data("state", "no").removeClass("on");
                        that.attr("data-state", "no");
                        that.data("state", "no");
                        that.removeClass("on");
                    }

                });
                this.$node.delegate('[data-role="label"]', "click", function () {
                    var that = $(this),
                    data = $(this).data("state"),
                    level = that.closest('[data-level]').data("level") + 1;
                    if (data == "no") {

                        that.attr("data-state", "check");
                        that.data("state", "check");
                        //  that.addClass("on");
                    } else {

                        that.attr("data-state", "no");
                        that.data("state", "no");
                        //that.removeClass("on");
                    }
                    that.parent().find('[data-role="nodeCheckBtn"]').click();
                }).delegate('[data-role="label"]', "mouseenter", function () {
                    $(this).addClass("on");
                }).delegate('[data-role="label"]', "mouseleave", function () {
                    $(this).removeClass("on");
                });
            } else {
                this.$node.delegate('[data-role="label"]', "click", function () {
                    var allLabel = self.$node.find('[data-role="label"]');
                    allLabel.attr("data-state", "no");
                    allLabel.data("state", "no");
                    allLabel.removeClass("on");
                    var that = $(this),
                    data = $(this).data("state"),
                    level = that.closest('[data-level]').data("level") + 1;
                    if (data == "no") {

                        that.attr("data-state", "check");
                        that.data("state", "check");
                        that.addClass("on");
                        self.trigger("oncheck", that.parent().data("id"), that.parent().data("name"));
                        //  that.addClass("on");
                    } else {

                        that.attr("data-state", "no");
                        that.data("state", "no");
                        that.removeClass("on");
                        //that.removeClass("on");
                    }

                });

            }

        },
        getCheckValue: function () {
            var val = [],
                hasCheck = this.options.hasCheck;
            if (!hasCheck) {
                this.$con.find('[data-role="label"]').filter('[data-state="check"]').each(function () {
                    var id = $(this).parent().data("id"),
                        name = $(this).parent().data("name");
                    var param = {};
                    param.id = id;
                    param.name = name;
                    if (id != "root") {
                        val.push(param);
                    }
                });
            } else {
                this.$con.find('[data-role="nodeCheckBtn"]').filter('[data-state="check"]').each(function () {
                    var id = $(this).parent().data("id"),
                        name = $(this).parent().data("name");
                    var param = {};
                    param.id = id;
                    param.name = name;
                    if (id != "root") {
                        val.push(param);
                    }
                });
            
            }
            return val;

        },
        setCheckItem: function (id) {
            if (id.length > 0) {
                for (var i = 0, len = id.length; i < len; i++) {
                    var k = id[i];
                    //.click();
                    var that = this.$con.find('[data-id="' + k + '"]').find('[data-role="nodeCheckBtn"]'),
                        data = that.data("state"),
                        level = that.closest('[data-level]').data("level") + 1;
                    that.closest("li").find('[data-level="' + level + '"]').find('[data-role="nodeCheckBtn"]').attr("data-state", "check").data("state", "check").addClass("on");
                    that.attr("data-state", "check");
                    that.data("state", "check");
                    that.addClass("on");
                }
            }

            // this.$node..find('[data-role="nodeCheckBtn"]').click();

        },
        appendNodes: function (setting, level, nodes, parentNode, initFlag, openFlag) {
            if (!nodes) return [];
            var html = '',
			        childKey = setting.key.children;
            for (var i = 0, l = nodes.length; i < l; i++) {
                var node = nodes[i];
                if (initFlag) {
                    var tmpPNode = (parentNode) ? parentNode : this.rootData,
					        tmpPChild = tmpPNode[childKey],
					        isFirstNode = (i == 0), //((tmpPChild.length == nodes.length) && (i == 0)),
                            hasChild = node[childKey] ? true : false,
					        isLastNode = (i == (nodes.length - 1));
                    html += this.render(level, node, parentNode, isFirstNode, isLastNode, openFlag, hasChild);
                }

                var childHtml = '';
                if (node[childKey] && node[childKey].length > 0) {
                    //make child html first, because checkType
                    childHtml = this.appendNodes(setting, level + 1, node[childKey], node, initFlag, openFlag && node.open, hasChild);
                }
                html += childHtml;
                if (isLastNode) {
                    html += '</li></ul>';
                } else {
                    html += '</li>';
                }
            }
            return html;
        }

    });
    module.exports = Tree;
});
