jui.define("chart.widget.topologyctrl", [ "util.base" ], function(_) {

    /**
     * @class chart.widget.topologyctrl
     * @extends chart.widget.core
     */
    var TopologyControlWidget = function() {
        var self = this, axis = null;
        var targetKey, startX, startY;
        var renderWait = false;
        var scale = 1, boxX = 0, boxY = 0;
        var nodeIndex = 0;

        function renderChart() {
            if(renderWait === false) {
                setTimeout(function () {
                    self.chart.render();
                    setBrushEvent();

                    renderWait = false;
                }, 70);

                renderWait = true;
            }
        }

        function initDragEvent() {
            self.on("axis.mousemove", function(e) {
                axis.root.attr({ cursor: "move" });
                if(!_.typeCheck("string", targetKey)) return;

                var xy = axis.c(targetKey),
                    dragX = e.chartX / xy.scale,
                    dragY = e.chartY / xy.scale;

                xy.setX(startX + (dragX - startX));
                xy.setY(startY + (dragY - startY));

                renderChart();
            }, axis.index);

            self.on("axis.mouseup", endDragAction, axis.index);
            self.on("bg.mouseup", endDragAction);
            self.on("bg.mouseout", endDragAction);

            function endDragAction(e) {
                if(!_.typeCheck("string", targetKey)) return;
                targetKey = null;
            }
        }

        function initZoomEvent() {
            self.on("axis.mousewheel", function(e) {
                var e = window.event || e,
                    delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail))),
                    xy = axis.c(targetKey);

                if(delta > 0) {
                    if(scale < 2) {
                        scale += 0.1;
                    }
                } else {
                    if(scale > 0.6) {
                        scale -= 0.1;
                    }
                }

                xy.setScale(scale);
                renderChart();
            }, axis.index);
        }

        function initMoveEvent() {
            var startX = null, startY = null;

            self.on("axis.mousedown", function(e) {
                if(_.typeCheck("string", targetKey)) return;
                if(startX != null || startY != null) return;

                startX = boxX + e.x;
                startY = boxY + e.y;
            }, axis.index);

            self.on("axis.mousemove", function(e) {
                if(startX == null || startY == null) return;

                var xy = axis.c(targetKey);
                boxX = startX - e.x;
                boxY = startY - e.y

                xy.setView(-boxX, -boxY);
                renderChart();
            }, axis.index);

            self.on("chart.mouseup", endMoveAction);
            self.on("chart.mouseout", endMoveAction);
            self.on("bg.mouseup", endMoveAction);
            self.on("bg.mouseout", endMoveAction);

            function endMoveAction(e) {
                if(startX == null || startY == null) return;

                startX = null;
                startY = null;
            }
        }

        function getBrushElement() {
            var children = self.svg.root.get(0).children,
                index = 0,
                element = null;

            for(var i = 0; i < children.length; i++) {
                var cls = children[i].attr("class");

                if(cls && cls.indexOf("topologynode") != -1) {
                    if(index == self.widget.brush) {
                        element = children[i];
                        break;
                    }

                    index++;
                }
            }

            return element;
        }

        function setBrushEvent() {
            var element = getBrushElement();
            if(element == null) return;

            element.each(function (i, node) {
                (function (index) {
                    if (isNaN(index)) return;

                    node.on("mousedown", function (e) {
                        if (_.typeCheck("string", targetKey)) return;

                        var key = axis.getValue(axis.data[index], "key"),
                            xy = axis.c(key);

                        targetKey = key;
                        startX = xy.x / xy.scale;
                        startY = xy.y / xy.scale;

                        axis.cache.activeNodeKey = targetKey;

                        // 선택한 노드 맨 마지막으로 이동
                        //xy.moveLast();
                    });
                })(parseInt(node.attr("index")));
            });
        }

        this.draw = function() {
            var brush = this.chart.get("brush", this.widget.brush);

            // axis 글로벌 변수에 설정
            axis = this.chart.axis(brush.axis);

            if(this.widget.zoom) {
                initZoomEvent(axis);
            }

            if(this.widget.move) {
                initMoveEvent(axis);
            }

            initDragEvent(axis);
            setBrushEvent(axis);

            return this.chart.svg.group();
        }
    }

    TopologyControlWidget.setup = function() {
        return {
            /** @cfg {Boolean} [move=false] Set to be moved to see the point of view of the topology map. */
            move: false,
            /** @cfg {Boolean} [zoom=false] Set the zoom-in / zoom-out features of the topology map. */
            zoom: false,
            /** @cfg {Number} [brush=0] Specifies a brush index for which a widget is used. */
            brush: 0
        }
    }

    return TopologyControlWidget;
}, "chart.widget.core");