define(function(require, exports, module) {
    var kity = require('../core/kity');
    var utils = require('../core/utils');

    var Minder = require('../core/minder');
    var MinderNode = require('../core/node');
    var Command = require('../core/command');
    var Module = require('../core/module');
    var Renderer = require('../core/render');

    Module.register('Select', function() {
        var minder = this;
        var rc = minder.getRenderContainer();

        // 在实例上渲染框选矩形、计算框选范围的对象
        var marqueeActivator = (function() {

            // 记录选区的开始位置（mousedown的位置）
            var startPosition = null;

            // 选区的图形
            var marqueeShape = new kity.Path();

            // 标记是否已经启动框选状态
            //    并不是 mousedown 发生之后就启动框选状态，而是检测到移动了一定的距离（MARQUEE_MODE_THRESHOLD）之后
            var marqueeMode = false;
            var MARQUEE_MODE_THRESHOLD = 10;

            return {
                selectStart: function(e) {
                    // 只接受左键
                    if (e.originEvent.button || e.originEvent.altKey) return;

                    // 清理不正确状态
                    if (startPosition) {
                        return this.selectEnd();
                    }

                    startPosition = e.getPosition(rc).round();
                },
                selectMove: function(e) {
                    if (minder.getStatus() == 'textedit') {
                        return;
                    }
                    if (!startPosition) return;

                    var p1 = startPosition,
                        p2 = e.getPosition(rc);

                    // 检测是否要进入选区模式
                    if (!marqueeMode) {
                        // 距离没达到阈值，退出
                        if (kity.Vector.fromPoints(p1, p2).length() < MARQUEE_MODE_THRESHOLD) {
                            return;
                        }
                        // 已经达到阈值，记录下来并且重置选区形状
                        marqueeMode = true;
                        rc.addShape(marqueeShape);
                        marqueeShape
                            .fill(minder.getStyle('marquee-background'))
                            .stroke(minder.getStyle('marquee-stroke')).setOpacity(0.8).getDrawer().clear();
                    }

                    var marquee = new kity.Box(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y),
                        selectedNodes = [];

                    // 使其犀利
                    marquee.left = Math.round(marquee.left);
                    marquee.top = Math.round(marquee.top);
                    marquee.right = Math.round(marquee.right);
                    marquee.bottom = Math.round(marquee.bottom);

                    // 选区形状更新
                    marqueeShape.getDrawer().pipe(function() {
                        this.clear();
                        this.moveTo(marquee.left, marquee.top);
                        this.lineTo(marquee.right, marquee.top);
                        this.lineTo(marquee.right, marquee.bottom);
                        this.lineTo(marquee.left, marquee.bottom);
                        this.close();
                    });

                    // 计算选中范围
                    minder.getRoot().traverse(function(node) {
                        var renderBox = node.getLayoutBox();
                        if (!renderBox.intersect(marquee).isEmpty()) {
                            selectedNodes.push(node);
                        }
                    });

                    // 应用选中范围
                    minder.select(selectedNodes, true);

                    // 清除多余的东西
                    window.getSelection().removeAllRanges();
                },
                selectEnd: function(e) {
                    if (startPosition) {
                        startPosition = null;
                    }
                    if (marqueeMode) {
                        marqueeShape.fadeOut(200, 'ease', 0, function() {
                            if (marqueeShape.remove) marqueeShape.remove();
                        });
                        marqueeMode = false;
                    }
                }
            };
        })();

        var lastDownNode = null,
            lastDownPosition = null;
        return {
            'init': function() {
                window.addEventListener('mouseup', function() {
                    marqueeActivator.selectEnd();
                });
            },
            'events': {
                'mousedown': function(e) {

                    var downNode = e.getTargetNode();

                    // 没有点中节点：
                    //     清除选中状态，并且标记选区开始位置
                    if (!downNode) {
                        this.removeAllSelectedNodes();
                        marqueeActivator.selectStart(e);

                        this.setStatus('normal');
                    }

                    // 点中了节点，并且按了 shift 键：
                    //     被点中的节点切换选中状态
                    else if (e.isShortcutKey('Ctrl')) {
                        this.toggleSelect(downNode);
                    }

                    // 点中的节点没有被选择：
                    //     单选点中的节点
                    else if (!downNode.isSelected()) {
                        this.select(downNode, true);
                    }

                    // 点中的节点被选中了，并且不是单选：
                    //     完成整个点击之后需要使其变为单选。
                    //     不能马上变为单选，因为可能是需要拖动选中的多个节点
                    else if (!this.isSingleSelect()) {
                        lastDownNode = downNode;
                        lastDownPosition = e.getPosition();
                    }
                },
                'mousemove': marqueeActivator.selectMove,
                'mouseup': function(e) {
                    var upNode = e.getTargetNode();

                    // 如果 mouseup 发生在 lastDownNode 外，是无需理会的
                    if (upNode && upNode == lastDownNode) {
                        var upPosition = e.getPosition();
                        var movement = kity.Vector.fromPoints(lastDownPosition, upPosition);
                        if (movement.length() < 1) this.select(lastDownNode, true);
                        lastDownNode = null;
                    }

                    // 清理一下选择状态
                    marqueeActivator.selectEnd(e);
                },
                //全选操作
                'normal.keydown': function(e) {

                    if (e.isShortcutKey('ctrl+a')) {
                        var selectedNodes = [];

                        this.getRoot().traverse(function(node) {
                            selectedNodes.push(node);
                        });
                        this.select(selectedNodes, true);
                        e.preventDefault();
                    }
                }
            }
        };
    });
});