/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { __DEV__ } from '../../config';
import * as zrUtil from 'zrender/src/core/util';
import Eventful from 'zrender/src/mixin/Eventful';
import * as graphic from '../../util/graphic';
import * as interactionMutex from './interactionMutex';
import DataDiffer from '../../data/DataDiffer';
var curry = zrUtil.curry;
var each = zrUtil.each;
var map = zrUtil.map;
var mathMin = Math.min;
var mathMax = Math.max;
var mathPow = Math.pow;
var COVER_Z = 10000;
var UNSELECT_THRESHOLD = 6;
var MIN_RESIZE_LINE_WIDTH = 6;
var MUTEX_RESOURCE_KEY = 'globalPan';
var DIRECTION_MAP = {
  w: [0, 0],
  e: [0, 1],
  n: [1, 0],
  s: [1, 1]
};
var CURSOR_MAP = {
  w: 'ew',
  e: 'ew',
  n: 'ns',
  s: 'ns',
  ne: 'nesw',
  sw: 'nesw',
  nw: 'nwse',
  se: 'nwse'
};
var DEFAULT_BRUSH_OPT = {
  brushStyle: {
    lineWidth: 2,
    stroke: 'rgba(0,0,0,0.3)',
    fill: 'rgba(0,0,0,0.1)'
  },
  transformable: true,
  brushMode: 'single',
  removeOnClick: false
};
var baseUID = 0;
/**
 * @alias module:echarts/component/helper/BrushController
 * @constructor
 * @mixin {module:zrender/mixin/Eventful}
 * @event module:echarts/component/helper/BrushController#brush
 *        params:
 *            areas: Array.<Array>, coord relates to container group,
 *                                    If no container specified, to global.
 *            opt {
 *                isEnd: boolean,
 *                removeOnClick: boolean
 *            }
 *
 * @param {module:zrender/zrender~ZRender} zr
 */

function BrushController(zr) {
  Eventful.call(this);
  /**
   * @type {module:zrender/zrender~ZRender}
   * @private
   */

  this._zr = zr;
  /**
   * @type {module:zrender/container/Group}
   * @readOnly
   */

  this.group = new graphic.Group();
  /**
   * Only for drawing (after enabledBrush).
   *     'line', 'rect', 'polygon' or false
   *     If passing false/null/undefined, disable brush.
   *     If passing 'auto', determined by panel.defaultBrushType
   * @private
   * @type {string}
   */

  this._brushType;
  /**
   * Only for drawing (after enabledBrush).
   *
   * @private
   * @type {Object}
   */

  this._brushOption;
  /**
   * @private
   * @type {Object}
   */

  this._panels;
  /**
   * @private
   * @type {Array.<nubmer>}
   */

  this._track = [];
  /**
   * @private
   * @type {boolean}
   */

  this._dragging;
  /**
   * @private
   * @type {Object}
   */

  this._lastMouseMovePoint = {};
  /**
   * @private
   * @type {Array}
   */

  this._covers = [];
  /**
   * @private
   * @type {moudule:zrender/container/Group}
   */

  this._creatingCover;
  /**
   * `true` means global panel
   * @private
   * @type {module:zrender/container/Group|boolean}
   */

  this._creatingPanel;
  /**
   * @private
   * @type {boolean}
   */

  this._enableGlobalPan;
  /**
   * @private
   * @type {boolean}
   */

  /**
   * @private
   * @type {string}
   */
  this._uid = 'brushController_' + baseUID++;
  /**
   * @private
   * @type {Object}
   */

  this._handlers = {};
  each(mouseHandlers, function (handler, eventName) {
    this._handlers[eventName] = zrUtil.bind(handler, this);
  }, this);
}

BrushController.prototype = {
  constructor: BrushController,

  /**
   * If set to null/undefined/false, select disabled.
   * @param {Object} brushOption
   * @param {string|boolean} brushOption.brushType 'line', 'rect', 'polygon' or false
   *                          If passing false/null/undefined, disable brush.
   *                          If passing 'auto', determined by panel.defaultBrushType.
   *                              ('auto' can not be used in global panel)
   * @param {number} [brushOption.brushMode='single'] 'single' or 'multiple'
   * @param {boolean} [brushOption.transformable=true]
   * @param {boolean} [brushOption.removeOnClick=false]
   * @param {Object} [brushOption.brushStyle]
   * @param {number} [brushOption.brushStyle.width]
   * @param {number} [brushOption.brushStyle.lineWidth]
   * @param {string} [brushOption.brushStyle.stroke]
   * @param {string} [brushOption.brushStyle.fill]
   * @param {number} [brushOption.z]
   */
  enableBrush: function (brushOption) {
    this._brushType && doDisableBrush(this);
    brushOption.brushType && doEnableBrush(this, brushOption);
    return this;
  },

  /**
   * @param {Array.<Object>} panelOpts If not pass, it is global brush.
   *        Each items: {
   *            panelId, // mandatory.
   *            clipPath, // mandatory. function.
   *            isTargetByCursor, // mandatory. function.
   *            defaultBrushType, // optional, only used when brushType is 'auto'.
   *            getLinearBrushOtherExtent, // optional. function.
   *        }
   */
  setPanels: function (panelOpts) {
    if (panelOpts && panelOpts.length) {
      var panels = this._panels = {};
      zrUtil.each(panelOpts, function (panelOpts) {
        panels[panelOpts.panelId] = zrUtil.clone(panelOpts);
      });
    } else {
      this._panels = null;
    }

    return this;
  },

  /**
   * @param {Object} [opt]
   * @return {boolean} [opt.enableGlobalPan=false]
   */
  mount: function (opt) {
    opt = opt || {};
    this._enableGlobalPan = opt.enableGlobalPan;
    var thisGroup = this.group;

    this._zr.add(thisGroup);

    thisGroup.attr({
      position: opt.position || [0, 0],
      rotation: opt.rotation || 0,
      scale: opt.scale || [1, 1]
    });
    this._transform = thisGroup.getLocalTransform();
    return this;
  },
  eachCover: function (cb, context) {
    each(this._covers, cb, context);
  },

  /**
   * Update covers.
   * @param {Array.<Object>} brushOptionList Like:
   *        [
   *            {id: 'xx', brushType: 'line', range: [23, 44], brushStyle, transformable},
   *            {id: 'yy', brushType: 'rect', range: [[23, 44], [23, 54]]},
   *            ...
   *        ]
   *        `brushType` is required in each cover info. (can not be 'auto')
   *        `id` is not mandatory.
   *        `brushStyle`, `transformable` is not mandatory, use DEFAULT_BRUSH_OPT by default.
   *        If brushOptionList is null/undefined, all covers removed.
   */
  updateCovers: function (brushOptionList) {
    brushOptionList = zrUtil.map(brushOptionList, function (brushOption) {
      return zrUtil.merge(zrUtil.clone(DEFAULT_BRUSH_OPT), brushOption, true);
    });
    var tmpIdPrefix = '\0-brush-index-';
    var oldCovers = this._covers;
    var newCovers = this._covers = [];
    var controller = this;
    var creatingCover = this._creatingCover;
    new DataDiffer(oldCovers, brushOptionList, oldGetKey, getKey).add(addOrUpdate).update(addOrUpdate).remove(remove).execute();
    return this;

    function getKey(brushOption, index) {
      return (brushOption.id != null ? brushOption.id : tmpIdPrefix + index) + '-' + brushOption.brushType;
    }

    function oldGetKey(cover, index) {
      return getKey(cover.__brushOption, index);
    }

    function addOrUpdate(newIndex, oldIndex) {
      var newBrushOption = brushOptionList[newIndex]; // Consider setOption in event listener of brushSelect,
      // where updating cover when creating should be forbiden.

      if (oldIndex != null && oldCovers[oldIndex] === creatingCover) {
        newCovers[newIndex] = oldCovers[oldIndex];
      } else {
        var cover = newCovers[newIndex] = oldIndex != null ? (oldCovers[oldIndex].__brushOption = newBrushOption, oldCovers[oldIndex]) : endCreating(controller, createCover(controller, newBrushOption));
        updateCoverAfterCreation(controller, cover);
      }
    }

    function remove(oldIndex) {
      if (oldCovers[oldIndex] !== creatingCover) {
        controller.group.remove(oldCovers[oldIndex]);
      }
    }
  },
  unmount: function () {
    this.enableBrush(false); // container may 'removeAll' outside.

    clearCovers(this);

    this._zr.remove(this.group);

    return this;
  },
  dispose: function () {
    this.unmount();
    this.off();
  }
};
zrUtil.mixin(BrushController, Eventful);

function doEnableBrush(controller, brushOption) {
  var zr = controller._zr; // Consider roam, which takes globalPan too.

  if (!controller._enableGlobalPan) {
    interactionMutex.take(zr, MUTEX_RESOURCE_KEY, controller._uid);
  }

  each(controller._handlers, function (handler, eventName) {
    zr.on(eventName, handler);
  });
  controller._brushType = brushOption.brushType;
  controller._brushOption = zrUtil.merge(zrUtil.clone(DEFAULT_BRUSH_OPT), brushOption, true);
}

function doDisableBrush(controller) {
  var zr = controller._zr;
  interactionMutex.release(zr, MUTEX_RESOURCE_KEY, controller._uid);
  each(controller._handlers, function (handler, eventName) {
    zr.off(eventName, handler);
  });
  controller._brushType = controller._brushOption = null;
}

function createCover(controller, brushOption) {
  var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption);
  cover.__brushOption = brushOption;
  updateZ(cover, brushOption);
  controller.group.add(cover);
  return cover;
}

function endCreating(controller, creatingCover) {
  var coverRenderer = getCoverRenderer(creatingCover);

  if (coverRenderer.endCreating) {
    coverRenderer.endCreating(controller, creatingCover);
    updateZ(creatingCover, creatingCover.__brushOption);
  }

  return creatingCover;
}

function updateCoverShape(controller, cover) {
  var brushOption = cover.__brushOption;
  getCoverRenderer(cover).updateCoverShape(controller, cover, brushOption.range, brushOption);
}

function updateZ(cover, brushOption) {
  var z = brushOption.z;
  z == null && (z = COVER_Z);
  cover.traverse(function (el) {
    el.z = z;
    el.z2 = z; // Consider in given container.
  });
}

function updateCoverAfterCreation(controller, cover) {
  getCoverRenderer(cover).updateCommon(controller, cover);
  updateCoverShape(controller, cover);
}

function getCoverRenderer(cover) {
  return coverRenderers[cover.__brushOption.brushType];
} // return target panel or `true` (means global panel)


function getPanelByPoint(controller, e, localCursorPoint) {
  var panels = controller._panels;

  if (!panels) {
    return true; // Global panel
  }

  var panel;
  var transform = controller._transform;
  each(panels, function (pn) {
    pn.isTargetByCursor(e, localCursorPoint, transform) && (panel = pn);
  });
  return panel;
} // Return a panel or true


function getPanelByCover(controller, cover) {
  var panels = controller._panels;

  if (!panels) {
    return true; // Global panel
  }

  var panelId = cover.__brushOption.panelId; // User may give cover without coord sys info,
  // which is then treated as global panel.

  return panelId != null ? panels[panelId] : true;
}

function clearCovers(controller) {
  var covers = controller._covers;
  var originalLength = covers.length;
  each(covers, function (cover) {
    controller.group.remove(cover);
  }, controller);
  covers.length = 0;
  return !!originalLength;
}

function trigger(controller, opt) {
  var areas = map(controller._covers, function (cover) {
    var brushOption = cover.__brushOption;
    var range = zrUtil.clone(brushOption.range);
    return {
      brushType: brushOption.brushType,
      panelId: brushOption.panelId,
      range: range
    };
  });
  controller.trigger('brush', areas, {
    isEnd: !!opt.isEnd,
    removeOnClick: !!opt.removeOnClick
  });
}

function shouldShowCover(controller) {
  var track = controller._track;

  if (!track.length) {
    return false;
  }

  var p2 = track[track.length - 1];
  var p1 = track[0];
  var dx = p2[0] - p1[0];
  var dy = p2[1] - p1[1];
  var dist = mathPow(dx * dx + dy * dy, 0.5);
  return dist > UNSELECT_THRESHOLD;
}

function getTrackEnds(track) {
  var tail = track.length - 1;
  tail < 0 && (tail = 0);
  return [track[0], track[tail]];
}

function createBaseRectCover(doDrift, controller, brushOption, edgeNames) {
  var cover = new graphic.Group();
  cover.add(new graphic.Rect({
    name: 'main',
    style: makeStyle(brushOption),
    silent: true,
    draggable: true,
    cursor: 'move',
    drift: curry(doDrift, controller, cover, 'nswe'),
    ondragend: curry(trigger, controller, {
      isEnd: true
    })
  }));
  each(edgeNames, function (name) {
    cover.add(new graphic.Rect({
      name: name,
      style: {
        opacity: 0
      },
      draggable: true,
      silent: true,
      invisible: true,
      drift: curry(doDrift, controller, cover, name),
      ondragend: curry(trigger, controller, {
        isEnd: true
      })
    }));
  });
  return cover;
}

function updateBaseRect(controller, cover, localRange, brushOption) {
  var lineWidth = brushOption.brushStyle.lineWidth || 0;
  var handleSize = mathMax(lineWidth, MIN_RESIZE_LINE_WIDTH);
  var x = localRange[0][0];
  var y = localRange[1][0];
  var xa = x - lineWidth / 2;
  var ya = y - lineWidth / 2;
  var x2 = localRange[0][1];
  var y2 = localRange[1][1];
  var x2a = x2 - handleSize + lineWidth / 2;
  var y2a = y2 - handleSize + lineWidth / 2;
  var width = x2 - x;
  var height = y2 - y;
  var widtha = width + lineWidth;
  var heighta = height + lineWidth;
  updateRectShape(controller, cover, 'main', x, y, width, height);

  if (brushOption.transformable) {
    updateRectShape(controller, cover, 'w', xa, ya, handleSize, heighta);
    updateRectShape(controller, cover, 'e', x2a, ya, handleSize, heighta);
    updateRectShape(controller, cover, 'n', xa, ya, widtha, handleSize);
    updateRectShape(controller, cover, 's', xa, y2a, widtha, handleSize);
    updateRectShape(controller, cover, 'nw', xa, ya, handleSize, handleSize);
    updateRectShape(controller, cover, 'ne', x2a, ya, handleSize, handleSize);
    updateRectShape(controller, cover, 'sw', xa, y2a, handleSize, handleSize);
    updateRectShape(controller, cover, 'se', x2a, y2a, handleSize, handleSize);
  }
}

function updateCommon(controller, cover) {
  var brushOption = cover.__brushOption;
  var transformable = brushOption.transformable;
  var mainEl = cover.childAt(0);
  mainEl.useStyle(makeStyle(brushOption));
  mainEl.attr({
    silent: !transformable,
    cursor: transformable ? 'move' : 'default'
  });
  each(['w', 'e', 'n', 's', 'se', 'sw', 'ne', 'nw'], function (name) {
    var el = cover.childOfName(name);
    var globalDir = getGlobalDirection(controller, name);
    el && el.attr({
      silent: !transformable,
      invisible: !transformable,
      cursor: transformable ? CURSOR_MAP[globalDir] + '-resize' : null
    });
  });
}

function updateRectShape(controller, cover, name, x, y, w, h) {
  var el = cover.childOfName(name);
  el && el.setShape(pointsToRect(clipByPanel(controller, cover, [[x, y], [x + w, y + h]])));
}

function makeStyle(brushOption) {
  return zrUtil.defaults({
    strokeNoScale: true
  }, brushOption.brushStyle);
}

function formatRectRange(x, y, x2, y2) {
  var min = [mathMin(x, x2), mathMin(y, y2)];
  var max = [mathMax(x, x2), mathMax(y, y2)];
  return [[min[0], max[0]], // x range
  [min[1], max[1]] // y range
  ];
}

function getTransform(controller) {
  return graphic.getTransform(controller.group);
}

function getGlobalDirection(controller, localDirection) {
  if (localDirection.length > 1) {
    localDirection = localDirection.split('');
    var globalDir = [getGlobalDirection(controller, localDirection[0]), getGlobalDirection(controller, localDirection[1])];
    (globalDir[0] === 'e' || globalDir[0] === 'w') && globalDir.reverse();
    return globalDir.join('');
  } else {
    var map = {
      w: 'left',
      e: 'right',
      n: 'top',
      s: 'bottom'
    };
    var inverseMap = {
      left: 'w',
      right: 'e',
      top: 'n',
      bottom: 's'
    };
    var globalDir = graphic.transformDirection(map[localDirection], getTransform(controller));
    return inverseMap[globalDir];
  }
}

function driftRect(toRectRange, fromRectRange, controller, cover, name, dx, dy, e) {
  var brushOption = cover.__brushOption;
  var rectRange = toRectRange(brushOption.range);
  var localDelta = toLocalDelta(controller, dx, dy);
  each(name.split(''), function (namePart) {
    var ind = DIRECTION_MAP[namePart];
    rectRange[ind[0]][ind[1]] += localDelta[ind[0]];
  });
  brushOption.range = fromRectRange(formatRectRange(rectRange[0][0], rectRange[1][0], rectRange[0][1], rectRange[1][1]));
  updateCoverAfterCreation(controller, cover);
  trigger(controller, {
    isEnd: false
  });
}

function driftPolygon(controller, cover, dx, dy, e) {
  var range = cover.__brushOption.range;
  var localDelta = toLocalDelta(controller, dx, dy);
  each(range, function (point) {
    point[0] += localDelta[0];
    point[1] += localDelta[1];
  });
  updateCoverAfterCreation(controller, cover);
  trigger(controller, {
    isEnd: false
  });
}

function toLocalDelta(controller, dx, dy) {
  var thisGroup = controller.group;
  var localD = thisGroup.transformCoordToLocal(dx, dy);
  var localZero = thisGroup.transformCoordToLocal(0, 0);
  return [localD[0] - localZero[0], localD[1] - localZero[1]];
}

function clipByPanel(controller, cover, data) {
  var panel = getPanelByCover(controller, cover);
  return panel && panel !== true ? panel.clipPath(data, controller._transform) : zrUtil.clone(data);
}

function pointsToRect(points) {
  var xmin = mathMin(points[0][0], points[1][0]);
  var ymin = mathMin(points[0][1], points[1][1]);
  var xmax = mathMax(points[0][0], points[1][0]);
  var ymax = mathMax(points[0][1], points[1][1]);
  return {
    x: xmin,
    y: ymin,
    width: xmax - xmin,
    height: ymax - ymin
  };
}

function resetCursor(controller, e, localCursorPoint) {
  // Check active
  if (!controller._brushType) {
    return;
  }

  var zr = controller._zr;
  var covers = controller._covers;
  var currPanel = getPanelByPoint(controller, e, localCursorPoint); // Check whether in covers.

  if (!controller._dragging) {
    for (var i = 0; i < covers.length; i++) {
      var brushOption = covers[i].__brushOption;

      if (currPanel && (currPanel === true || brushOption.panelId === currPanel.panelId) && coverRenderers[brushOption.brushType].contain(covers[i], localCursorPoint[0], localCursorPoint[1])) {
        // Use cursor style set on cover.
        return;
      }
    }
  }

  currPanel && zr.setCursorStyle('crosshair');
}

function preventDefault(e) {
  var rawE = e.event;
  rawE.preventDefault && rawE.preventDefault();
}

function mainShapeContain(cover, x, y) {
  return cover.childOfName('main').contain(x, y);
}

function updateCoverByMouse(controller, e, localCursorPoint, isEnd) {
  var creatingCover = controller._creatingCover;
  var panel = controller._creatingPanel;
  var thisBrushOption = controller._brushOption;
  var eventParams;

  controller._track.push(localCursorPoint.slice());

  if (shouldShowCover(controller) || creatingCover) {
    if (panel && !creatingCover) {
      thisBrushOption.brushMode === 'single' && clearCovers(controller);
      var brushOption = zrUtil.clone(thisBrushOption);
      brushOption.brushType = determineBrushType(brushOption.brushType, panel);
      brushOption.panelId = panel === true ? null : panel.panelId;
      creatingCover = controller._creatingCover = createCover(controller, brushOption);

      controller._covers.push(creatingCover);
    }

    if (creatingCover) {
      var coverRenderer = coverRenderers[determineBrushType(controller._brushType, panel)];
      var coverBrushOption = creatingCover.__brushOption;
      coverBrushOption.range = coverRenderer.getCreatingRange(clipByPanel(controller, creatingCover, controller._track));

      if (isEnd) {
        endCreating(controller, creatingCover);
        coverRenderer.updateCommon(controller, creatingCover);
      }

      updateCoverShape(controller, creatingCover);
      eventParams = {
        isEnd: isEnd
      };
    }
  } else if (isEnd && thisBrushOption.brushMode === 'single' && thisBrushOption.removeOnClick) {
    // Help user to remove covers easily, only by a tiny drag, in 'single' mode.
    // But a single click do not clear covers, because user may have casual
    // clicks (for example, click on other component and do not expect covers
    // disappear).
    // Only some cover removed, trigger action, but not every click trigger action.
    if (getPanelByPoint(controller, e, localCursorPoint) && clearCovers(controller)) {
      eventParams = {
        isEnd: isEnd,
        removeOnClick: true
      };
    }
  }

  return eventParams;
}

function determineBrushType(brushType, panel) {
  if (brushType === 'auto') {
    return panel.defaultBrushType;
  }

  return brushType;
}

var mouseHandlers = {
  mousedown: function (e) {
    if (this._dragging) {
      // In case some browser do not support globalOut,
      // and release mose out side the browser.
      handleDragEnd(this, e);
    } else if (!e.target || !e.target.draggable) {
      preventDefault(e);
      var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);
      this._creatingCover = null;
      var panel = this._creatingPanel = getPanelByPoint(this, e, localCursorPoint);

      if (panel) {
        this._dragging = true;
        this._track = [localCursorPoint.slice()];
      }
    }
  },
  mousemove: function (e) {
    var lastPoint = this._lastMouseMovePoint;
    lastPoint.x = e.offsetX;
    lastPoint.y = e.offsetY;
    var localCursorPoint = this.group.transformCoordToLocal(lastPoint.x, lastPoint.y);
    resetCursor(this, e, localCursorPoint);

    if (this._dragging) {
      preventDefault(e);
      var eventParams = updateCoverByMouse(this, e, localCursorPoint, false);
      eventParams && trigger(this, eventParams);
    }
  },
  mouseup: function (e) {
    handleDragEnd(this, e);
  },
  globalout: function (e) {
    handleDragEnd(this, e, true);
  }
};

function handleDragEnd(controller, e, isGlobalOut) {
  if (controller._dragging) {
    // Just be worried about bring some side effect to the world
    // out of echarts, we do not `preventDefault` for globalout.
    !isGlobalOut && preventDefault(e);
    var pointerX = e.offsetX;
    var pointerY = e.offsetY;
    var lastPoint = controller._lastMouseMovePoint;

    if (isGlobalOut) {
      pointerX = lastPoint.x;
      pointerY = lastPoint.y;
    }

    var localCursorPoint = controller.group.transformCoordToLocal(pointerX, pointerY); // FIXME
    // Here `e` is used only in `onIrrelevantElement` finally. And it's OK
    // that pass the `e` of `globalout` to `onIrrelevantElement`. But it is
    // not a good design of these interfaces. However, we do not refactor
    // these code now because the implementation of `onIrrelevantElement`
    // need to be discussed and probably be changed in future, becuase it
    // slows down the performance of zrender in some cases.

    var eventParams = updateCoverByMouse(controller, e, localCursorPoint, true);
    controller._dragging = false;
    controller._track = [];
    controller._creatingCover = null; // trigger event shoule be at final, after procedure will be nested.

    eventParams && trigger(controller, eventParams);
  }
}
/**
 * key: brushType
 * @type {Object}
 */


var coverRenderers = {
  lineX: getLineRenderer(0),
  lineY: getLineRenderer(1),
  rect: {
    createCover: function (controller, brushOption) {
      return createBaseRectCover(curry(driftRect, function (range) {
        return range;
      }, function (range) {
        return range;
      }), controller, brushOption, ['w', 'e', 'n', 's', 'se', 'sw', 'ne', 'nw']);
    },
    getCreatingRange: function (localTrack) {
      var ends = getTrackEnds(localTrack);
      return formatRectRange(ends[1][0], ends[1][1], ends[0][0], ends[0][1]);
    },
    updateCoverShape: function (controller, cover, localRange, brushOption) {
      updateBaseRect(controller, cover, localRange, brushOption);
    },
    updateCommon: updateCommon,
    contain: mainShapeContain
  },
  polygon: {
    createCover: function (controller, brushOption) {
      var cover = new graphic.Group(); // Do not use graphic.Polygon because graphic.Polyline do not close the
      // border of the shape when drawing, which is a better experience for user.

      cover.add(new graphic.Polyline({
        name: 'main',
        style: makeStyle(brushOption),
        silent: true
      }));
      return cover;
    },
    getCreatingRange: function (localTrack) {
      return localTrack;
    },
    endCreating: function (controller, cover) {
      cover.remove(cover.childAt(0)); // Use graphic.Polygon close the shape.

      cover.add(new graphic.Polygon({
        name: 'main',
        draggable: true,
        drift: curry(driftPolygon, controller, cover),
        ondragend: curry(trigger, controller, {
          isEnd: true
        })
      }));
    },
    updateCoverShape: function (controller, cover, localRange, brushOption) {
      cover.childAt(0).setShape({
        points: clipByPanel(controller, cover, localRange)
      });
    },
    updateCommon: updateCommon,
    contain: mainShapeContain
  }
};

function getLineRenderer(xyIndex) {
  return {
    createCover: function (controller, brushOption) {
      return createBaseRectCover(curry(driftRect, function (range) {
        var rectRange = [range, [0, 100]];
        xyIndex && rectRange.reverse();
        return rectRange;
      }, function (rectRange) {
        return rectRange[xyIndex];
      }), controller, brushOption, [['w', 'e'], ['n', 's']][xyIndex]);
    },
    getCreatingRange: function (localTrack) {
      var ends = getTrackEnds(localTrack);
      var min = mathMin(ends[0][xyIndex], ends[1][xyIndex]);
      var max = mathMax(ends[0][xyIndex], ends[1][xyIndex]);
      return [min, max];
    },
    updateCoverShape: function (controller, cover, localRange, brushOption) {
      var otherExtent; // If brushWidth not specified, fit the panel.

      var panel = getPanelByCover(controller, cover);

      if (panel !== true && panel.getLinearBrushOtherExtent) {
        otherExtent = panel.getLinearBrushOtherExtent(xyIndex, controller._transform);
      } else {
        var zr = controller._zr;
        otherExtent = [0, [zr.getWidth(), zr.getHeight()][1 - xyIndex]];
      }

      var rectRange = [localRange, otherExtent];
      xyIndex && rectRange.reverse();
      updateBaseRect(controller, cover, rectRange, brushOption);
    },
    updateCommon: updateCommon,
    contain: mainShapeContain
  };
}

export default BrushController;