/**
 * 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;
});