/**
 * echarts组件：孤岛数据
 *
 * @desc echarts基于Canvas，纯Javascript图表库，提供直观，生动，可交互，可个性化定制的数据统计图表。
 * @author Kener (@Kener-林峰, linzhifeng@baidu.com)
 *
 */
define(function (require) {
    /**
     * 构造函数
     * @param {Object} messageCenter echart消息中心
     * @param {ZRender} zr zrender实例
     * @param {Object} option 图表选项
     */
    function Island(messageCenter, zr) {
        // 基类装饰
        var ComponentBase = require('../component/base');
        ComponentBase.call(this, zr);
        // 可计算特性装饰
        var CalculableBase = require('./calculableBase');
        CalculableBase.call(this, zr);

        var ecConfig = require('../config');
        var ecData = require('../util/ecData');

        var zrEvent = require('zrender/tool/event');

        var self = this;
        self.type = ecConfig.CHART_TYPE_ISLAND;
        var option;

        var _zlevelBase = self.getZlevelBase();
        var _nameConnector;
        var _valueConnector;
        var _zrHeight = zr.getHeight();
        var _zrWidth = zr.getWidth();

        /**
         * 孤岛合并
         *
         * @param {string} tarShapeIndex 目标索引
         * @param {Object} srcShape 源目标，合入目标后删除
         */
        function _combine(tarShape, srcShape) {
            var zrColor = require('zrender/tool/color');
            var value = ecData.get(tarShape, 'value')
                        + ecData.get(srcShape, 'value');
            var name = ecData.get(tarShape, 'name')
                       + _nameConnector
                       + ecData.get(srcShape, 'name');

            tarShape.style.text = name + _valueConnector + value;

            ecData.set(tarShape, 'value', value);
            ecData.set(tarShape, 'name', name);
            tarShape.style.r = option.island.r;
            tarShape.style.color = zrColor.mix(
                tarShape.style.color,
                srcShape.style.color
            );
        }

        /**
         * 刷新
         */
        function refresh(newOption) {
            if (newOption) {
                newOption.island = self.reformOption(newOption.island);
                option = newOption;
    
                _nameConnector = option.nameConnector;
                _valueConnector = option.valueConnector;
            }
        }
        
        function render(newOption) {
            refresh(newOption);

            for (var i = 0, l = self.shapeList.length; i < l; i++) {
                zr.addShape(self.shapeList[i]);
            }
        }
        
        function getOption() {
            return option;
        }

        function resize() {
            var newWidth = zr.getWidth();
            var newHieght = zr.getHeight();
            var xScale = newWidth / (_zrWidth || newWidth);
            var yScale = newHieght / (_zrHeight || newHieght);
            if (xScale == 1 && yScale == 1) {
                return;
            }
            _zrWidth = newWidth;
            _zrHeight = newHieght;
            for (var i = 0, l = self.shapeList.length; i < l; i++) {
                zr.modShape(
                    self.shapeList[i].id,
                    {
                        style: {
                            x: Math.round(self.shapeList[i].style.x * xScale),
                            y: Math.round(self.shapeList[i].style.y * yScale)
                        }
                    }
                );
            }
        }

        function add(shape) {
            var name = ecData.get(shape, 'name');
            var value = ecData.get(shape, 'value');
            var seriesName = typeof ecData.get(shape, 'series') != 'undefined'
                             ? ecData.get(shape, 'series').name
                             : '';
            var font = self.getFont(option.island.textStyle);
            var islandShape = {
                shape : 'circle',
                id : zr.newShapeId(self.type),
                zlevel : _zlevelBase,
                style : {
                    x : shape.style.x,
                    y : shape.style.y,
                    r : option.island.r,
                    color : shape.style.color || shape.style.strokeColor,
                    text : name + _valueConnector + value,
                    textFont : font
                },
                draggable : true,
                hoverable : true,
                onmousewheel : self.shapeHandler.onmousewheel,
                _type : 'island'
            };
            if (islandShape.style.color == '#fff') {
                islandShape.style.color = shape.style.strokeColor;
            }
            self.setCalculable(islandShape);
            ecData.pack(
                islandShape,
                {name:seriesName}, -1,
                value, -1,
                name
            );
            self.shapeList.push(islandShape);
            zr.addShape(islandShape);
        }

        function del(shape) {
            zr.delShape(shape.id);
            var newShapeList = [];
            for (var i = 0, l = self.shapeList.length; i < l; i++) {
                if (self.shapeList[i].id != shape.id) {
                    newShapeList.push(self.shapeList[i]);
                }
            }
            self.shapeList = newShapeList;
        }

        /**
         * 数据项被拖拽进来， 重载基类方法
         */
        function ondrop(param, status) {
            if (!self.isDrop || !param.target) {
                // 没有在当前实例上发生拖拽行为则直接返回
                return;
            }
            // 拖拽产生孤岛数据合并
            var target = param.target;      // 拖拽安放目标
            var dragged = param.dragged;    // 当前被拖拽的图形对象

            _combine(target, dragged);
            zr.modShape(target.id, target);

            status.dragIn = true;

            // 处理完拖拽事件后复位
            self.isDrop = false;

            return;
        }

        /**
         * 数据项被拖拽出去， 重载基类方法
         */
        function ondragend(param, status) {
            var target = param.target;      // 拖拽安放目标
            if (!self.isDragend) {
                // 拖拽的不是孤岛数据，如果没有图表接受孤岛数据，需要新增孤岛数据
                if (!status.dragIn) {
                    target.style.x = zrEvent.getX(param.event);
                    target.style.y = zrEvent.getY(param.event);
                    add(target);
                    status.needRefresh = true;
                }
            }
            else {
                // 拖拽的是孤岛数据，如果有图表接受了孤岛数据，需要删除孤岛数据
                if (status.dragIn) {
                    del(target);
                    status.needRefresh = true;
                }
            }

            // 处理完拖拽事件后复位
            self.isDragend = false;

            return;
        }

        /**
         * 滚轮改变孤岛数据值
         */
        self.shapeHandler.onmousewheel = function(param) {
            var shape = param.target;

            var event = param.event;
            var delta = zrEvent.getDelta(event);
            delta = delta > 0 ? (-1) : 1;
            shape.style.r -= delta;
            shape.style.r = shape.style.r < 5 ? 5 : shape.style.r;

            var value = ecData.get(shape, 'value');
            var dvalue = value * option.island.calculateStep;
            if (dvalue > 1) {
                value = Math.round(value - dvalue * delta);
            }
            else {
                value = (value - dvalue * delta).toFixed(2) - 0;
            }

            var name = ecData.get(shape, 'name');
            shape.style.text = name + ':' + value;

            ecData.set(shape, 'value', value);
            ecData.set(shape, 'name', name);

            zr.modShape(shape.id, shape);
            zr.refresh();
            zrEvent.stop(event);
        };

        self.refresh = refresh;
        self.render = render;
        self.resize = resize;
        self.getOption = getOption;
        self.add = add;
        self.del = del;
        self.ondrop = ondrop;
        self.ondragend = ondragend;
    }

    // 图表注册
    require('../chart').define('island', Island);
    
    return Island;
});