/**
 * @ignore
 * checkable tree node
 * @author yiminghe@gmail.com
 */
KISSY.add("tree/check-node", function (S, Node, TreeNode) {
    var $ = Node.all,
        PARTIAL_CHECK = 2,
        CHECK = 1,
        EMPTY = 0;

    /**
     * Checked tree node. xclass: 'check-tree-node'.
     * @class KISSY.Tree.CheckNode
     * @extends KISSY.Tree.Node
     */
    var CheckNode = TreeNode.extend({
        handleClickInternal: function (e) {
            var self = this,
                checkState,
                expanded = self.get("expanded"),
                expandIconEl = self.get("expandIconEl"),
                tree = self.get("tree"),
                target = $(e.target);

            // 需要通知 tree 获得焦点
            tree.focus();

            // 点击在 +- 号,切换状态
            if (target.equals(expandIconEl)) {
                self.set("expanded", !expanded);
                return;
            }

            // 单击任何其他地方都切换 check 状态
            checkState = self.get("checkState");

            if (checkState == CHECK) {
                checkState = EMPTY;
            } else {
                checkState = CHECK;
            }


            self.set("checkState", checkState);

           self.fire("click");
            return true;
        },

        _onSetCheckState: function (s) {
            var self = this,
                parent = self.get('parent'),
                checkCount,
                i,
                c,
                cState,
                cs;

            if (s == CHECK || s == EMPTY) {
                S.each(self.get("children"), function (c) {
                    c.set("checkState", s);
                });
            }

            // 每次状态变化都通知 parent 沿链检查,一层层向上通知
            // 效率不高,但是结构清晰
            if (parent) {
                checkCount = 0;
                cs = parent.get("children");
                for (i = 0; i < cs.length; i++) {
                    c = cs[i];
                    cState = c.get("checkState");
                    // 一个是部分选,父亲必定是部分选,立即结束
                    if (cState == PARTIAL_CHECK) {
                        parent.set("checkState", PARTIAL_CHECK);
                        return;
                    } else if (cState == CHECK) {
                        checkCount++;
                    }
                }

                // 儿子都没选,父亲也不选
                if (checkCount === 0) {
                    parent.set("checkState", EMPTY);
                } else
                // 儿子全都选了,父亲也全选
                if (checkCount == cs.length) {
                    parent.set("checkState", CHECK);
                }
                // 有的儿子选了,有的没选,父亲部分选
                else {
                    parent.set("checkState", PARTIAL_CHECK);
                }
            }
        }
    }, {
        ATTRS:{
            checkIconEl: {
            },

            checkable: {
                value: true,
                view: 1
            },

            /**
             * Enums for check states.
             * CheckNode.PARTIAL_CHECK: checked partly.
             * CheckNode.CHECK: checked completely.
             * CheckNode.EMPTY: not checked.
             * @type {Number}
             */
            checkState: {
                // check 的三状态
                // 0 一个不选
                // 1 儿子有选择
                // 2 全部都选了
                value: 0,
                sync: 0,
                view: 1
            },

            defaultChildCfg: {
                value: {
                    xclass: 'check-tree-node'
                }
            }
        },
        xclass: "check-tree-node"
    });

    /**
     * check node's check state enum
     * @enum {Number} KISSY.Tree.CheckNode.CheckState
     */
    CheckNode.CheckState={
        /**
         * checked partly.
         */
        PARTIAL_CHECK: PARTIAL_CHECK,
        /**
         * checked completely.
         */
        CHECK: CHECK,
        /**
         * not checked at all.
         */
        EMPTY: EMPTY
    };

    return CheckNode;
}, {
    requires: ['node', './node']
});