/**
 * echarts组件：漫游控制器
 *
 * @desc echarts基于Canvas，纯Javascript图表库，提供直观，生动，可交互，可个性化定制的数据统计图表。
 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
 *
 */
define(function (require) {
    var Base = require('./base');
    
    // 图形依赖
    var RectangleShape = require('zrender/shape/Rectangle');
    var SectorShape = require('zrender/shape/Sector');
    var CircleShape = require('zrender/shape/Circle');
    
    var ecConfig = require('../config');
    ecConfig.roamController = {
        zlevel: 0,                  // 一级层叠
        z: 4,                       // 二级层叠
        show: true,
        x: 'left',                 // 水平安放位置，默认为全图左对齐，可选为：
                                   // 'center' ¦ 'left' ¦ 'right'
                                   // ¦ {number}（x坐标，单位px）
        y: 'top',                  // 垂直安放位置，默认为全图顶端，可选为：
                                   // 'top' ¦ 'bottom' ¦ 'center'
                                   // ¦ {number}（y坐标，单位px）
        width: 80,
        height: 120,
        backgroundColor: 'rgba(0,0,0,0)',
        borderColor: '#ccc',       // 图例边框颜色
        borderWidth: 0,            // 图例边框线宽，单位px，默认为0（无边框）
        padding: 5,                // 图例内边距，单位px，默认各方向内边距为5，
                                   // 接受数组分别设定上右下左边距，同css
        handleColor: '#6495ed',
        fillerColor: '#fff',
        step: 15,                  // 移动幅度
        mapTypeControl: null
    };

    var zrUtil = require('zrender/tool/util');
    var zrColor = require('zrender/tool/color');
    var zrEvent = require('zrender/tool/event');

    /**
     * 构造函数
     * @param {Object} messageCenter echart消息中心
     * @param {ZRender} zr zrender实例
     * @param {Object} option 图表参数
     */
    function RoamController(ecTheme, messageCenter, zr, option, myChart) {
        if (!option.roamController || !option.roamController.show) {
            return;
        }
        if (!option.roamController.mapTypeControl) {
            console.error('option.roamController.mapTypeControl has not been defined.');
            return;
        }
        
        Base.call(this, ecTheme, messageCenter, zr, option, myChart);
        
        this.rcOption = option.roamController;
        
        var self = this;
        this._drictionMouseDown = function(params) {
            return self.__drictionMouseDown(params);
        };
        this._drictionMouseUp = function(params) {
            return self.__drictionMouseUp(params);
        };
        this._drictionMouseMove = function(params) {
            return self.__drictionMouseMove(params);
        };
        this._drictionMouseOut = function(params) {
            return self.__drictionMouseOut(params);
        };
        this._scaleHandler = function(params) {
            return self.__scaleHandler(params);
        };
        this.refresh(option);
    }
    
    RoamController.prototype = {
        type: ecConfig.COMPONENT_TYPE_ROAMCONTROLLER,
        _buildShape: function () {
            if (!this.rcOption.show) {
                return;
            }
            // 元素组的位置参数，通过计算所得x, y, width, height
            this._itemGroupLocation = this._getItemGroupLocation();

            this._buildBackground();
            this._buildItem();

            for (var i = 0, l = this.shapeList.length; i < l; i++) {
                this.zr.addShape(this.shapeList[i]);
            }
        },

        /**
         * 构建所有漫游控制器元素
         */
        _buildItem: function () {
            this.shapeList.push(this._getDirectionShape('up'));
            this.shapeList.push(this._getDirectionShape('down'));
            this.shapeList.push(this._getDirectionShape('left'));
            this.shapeList.push(this._getDirectionShape('right'));
            this.shapeList.push(this._getScaleShape('scaleUp'));
            this.shapeList.push(this._getScaleShape('scaleDown'));
        },
        
        _getDirectionShape: function(direction) {
            var r = this._itemGroupLocation.r;
            var x = this._itemGroupLocation.x + r;
            var y = this._itemGroupLocation.y + r;
            
            var sectorShape = {
                zlevel: this.getZlevelBase(),
                z: this.getZBase(),
                style: {
                    x: x,          // 圆心横坐标
                    y: y,          // 圆心纵坐标
                    r: r,          // 圆环外半径
                    startAngle: -45,
                    endAngle: 45,
                    color: this.rcOption.handleColor,
                    text: '>',
                    textX: x + r / 2 + 4,
                    textY: y - 0.5,
                    textAlign: 'center',
                    textBaseline: 'middle',
                    textPosition: 'specific',
                    textColor: this.rcOption.fillerColor,
                    textFont: Math.floor(r / 2) + 'px arial'
                },
                highlightStyle: {
                    color: zrColor.lift(this.rcOption.handleColor, -0.2),
                    brushType: 'fill'
                },
                clickable: true
            };
            switch (direction) {
                case 'up':
                    sectorShape.rotation = [Math.PI / 2, x, y];
                    break;
                case 'left':
                    sectorShape.rotation = [Math.PI, x, y];
                    break;
                case 'down':
                    sectorShape.rotation = [-Math.PI / 2, x, y];
                    break;
            }

            sectorShape = new SectorShape(sectorShape);
            sectorShape._roamType = direction;
            sectorShape.onmousedown = this._drictionMouseDown;
            sectorShape.onmouseup = this._drictionMouseUp;
            sectorShape.onmousemove = this._drictionMouseMove;
            sectorShape.onmouseout = this._drictionMouseOut;
            
            return sectorShape;
        },
        
        _getScaleShape: function(text) {
            var width = this._itemGroupLocation.width;
            var height = this._itemGroupLocation.height - width;
            height = height < 0 ? 20 : height;  // 确保height不为负
            
            var r = Math.min(width / 2 - 5, height) / 2;
            var x = this._itemGroupLocation.x 
                    + (text === 'scaleDown' ? (width - r) : r);
            var y = this._itemGroupLocation.y + this._itemGroupLocation.height - r;

            var scaleShape = {
                zlevel: this.getZlevelBase(),
                z: this.getZBase(),
                style: {
                    x: x,
                    y: y,
                    r: r,
                    color: this.rcOption.handleColor,
                    text: text === 'scaleDown' ? '-' : '+',
                    textX: x,
                    textY: y - 2,
                    textAlign: 'center',
                    textBaseline: 'middle',
                    textPosition: 'specific',
                    textColor: this.rcOption.fillerColor,
                    textFont: Math.floor(r) + 'px verdana'
                },
                highlightStyle: {
                    color: zrColor.lift(this.rcOption.handleColor, -0.2),
                    brushType: 'fill'
                },
                clickable: true
            };
            
            scaleShape = new CircleShape(scaleShape);
            scaleShape._roamType = text;
            scaleShape.onmousedown = this._scaleHandler;
            
            return scaleShape;
        },
        
        _buildBackground: function () {
            var padding = this.reformCssArray(this.rcOption.padding);

            this.shapeList.push(new RectangleShape({
                zlevel: this.getZlevelBase(),
                z: this.getZBase(),
                hoverable :false,
                style: {
                    x: this._itemGroupLocation.x - padding[3],
                    y: this._itemGroupLocation.y - padding[0],
                    width: this._itemGroupLocation.width + padding[3] + padding[1],
                    height: this._itemGroupLocation.height + padding[0] + padding[2],
                    brushType: this.rcOption.borderWidth === 0 ? 'fill' : 'both',
                    color: this.rcOption.backgroundColor,
                    strokeColor: this.rcOption.borderColor,
                    lineWidth: this.rcOption.borderWidth
                }
            }));
        },

        /**
         * 根据选项计算漫游控制器实体的位置坐标
         */
        _getItemGroupLocation: function () {
            var padding = this.reformCssArray(this.rcOption.padding);
            var width = this.rcOption.width;
            var height = this.rcOption.height;
            
            var zrWidth = this.zr.getWidth();
            var zrHeight = this.zr.getHeight();
            var x;
            switch (this.rcOption.x) {
                case 'center' :
                    x = Math.floor((zrWidth - width) / 2);
                    break;
                case 'left' :
                    x = padding[3] + this.rcOption.borderWidth;
                    break;
                case 'right' :
                    x = zrWidth
                        - width
                        - padding[1]
                        - padding[3]
                        - this.rcOption.borderWidth * 2;
                    break;
                default :
                    x = this.parsePercent(this.rcOption.x, zrWidth);
                    break;
            }
            
            var y;
            switch (this.rcOption.y) {
                case 'top' :
                    y = padding[0] + this.rcOption.borderWidth;
                    break;
                case 'bottom' :
                    y = zrHeight
                        - height
                        - padding[0]
                        - padding[2]
                        - this.rcOption.borderWidth * 2;
                    break;
                case 'center' :
                    y = Math.floor((zrHeight - height) / 2);
                    break;
                default :
                    y = this.parsePercent(this.rcOption.y, zrHeight);
                    break;
            }

            return {
                x: x,
                y: y,
                r: width / 2,
                width: width,
                height: height
            };
        },

        __drictionMouseDown: function(params) {
            this.mousedown = true;
            this._drictionHandlerOn(params);
        },
        
        __drictionMouseUp: function(params) {
            this.mousedown = false;
            this._drictionHandlerOff(params);
        },
        
        __drictionMouseMove: function(params) {
            if (this.mousedown) {
                this._drictionHandlerOn(params);
            }
        },
        
        __drictionMouseOut: function(params) {
            this._drictionHandlerOff(params);
        },
        
        _drictionHandlerOn: function(params) {
            this._dispatchEvent(params.event, params.target._roamType);
            clearInterval(this.dircetionTimer);
            var self = this;
            this.dircetionTimer = setInterval(function() {
                self._dispatchEvent(params.event, params.target._roamType);
            }, 100);
            zrEvent.stop(params.event);
        },
        
        _drictionHandlerOff: function(params) {
            clearInterval(this.dircetionTimer);
        },
        
        __scaleHandler: function(params) {
            this._dispatchEvent(params.event, params.target._roamType);
            zrEvent.stop(params.event);
        },
        
        _dispatchEvent: function(event, roamType){
            this.messageCenter.dispatch(
                ecConfig.EVENT.ROAMCONTROLLER,
                event, 
                {
                    roamType: roamType,
                    mapTypeControl: this.rcOption.mapTypeControl,
                    step: this.rcOption.step
                },
                this.myChart
            );
        },
        /**
         * 刷新
         */
        refresh: function (newOption) {
            if (newOption) {
                this.option = newOption || this.option;
                this.option.roamController = this.reformOption(this.option.roamController);
                this.rcOption = this.option.roamController;
            }
            this.clear();
            this._buildShape();
        }
    };
    
    
    zrUtil.inherits(RoamController, Base);
    
    require('../component').define('roamController', RoamController);
    
    return RoamController;
});


