'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var tslib_es6 = require('../../../../../../tslib@2.3.0/node_modules/tslib/tslib.es6.js');
require('../../util/graphic.js');
var Line = require('./Line.js');
var util = require('../../../../../../zrender@6.0.0/node_modules/zrender/lib/core/util.js');
var symbol = require('../../util/symbol.js');
var vector = require('../../../../../../zrender@6.0.0/node_modules/zrender/lib/core/vector.js');
var curve = require('../../../../../../zrender@6.0.0/node_modules/zrender/lib/core/curve.js');
var Group = require('../../../../../../zrender@6.0.0/node_modules/zrender/lib/graphic/Group.js');

var EffectLine = /** @class */function (_super) {
  tslib_es6.__extends(EffectLine, _super);
  function EffectLine(lineData, idx, seriesScope) {
    var _this = _super.call(this) || this;
    _this.add(_this.createLine(lineData, idx, seriesScope));
    _this._updateEffectSymbol(lineData, idx);
    return _this;
  }
  EffectLine.prototype.createLine = function (lineData, idx, seriesScope) {
    return new Line.default(lineData, idx, seriesScope);
  };
  EffectLine.prototype._updateEffectSymbol = function (lineData, idx) {
    var itemModel = lineData.getItemModel(idx);
    var effectModel = itemModel.getModel('effect');
    var size = effectModel.get('symbolSize');
    var symbolType = effectModel.get('symbol');
    if (!util.isArray(size)) {
      size = [size, size];
    }
    var lineStyle = lineData.getItemVisual(idx, 'style');
    var color = effectModel.get('color') || lineStyle && lineStyle.stroke;
    var symbol$1 = this.childAt(1);
    if (this._symbolType !== symbolType) {
      // Remove previous
      this.remove(symbol$1);
      symbol$1 = symbol.createSymbol(symbolType, -0.5, -0.5, 1, 1, color);
      symbol$1.z2 = 100;
      symbol$1.culling = true;
      this.add(symbol$1);
    }
    // Symbol may be removed if loop is false
    if (!symbol$1) {
      return;
    }
    // Shadow color is same with color in default
    symbol$1.setStyle('shadowColor', color);
    symbol$1.setStyle(effectModel.getItemStyle(['color']));
    symbol$1.scaleX = size[0];
    symbol$1.scaleY = size[1];
    symbol$1.setColor(color);
    this._symbolType = symbolType;
    this._symbolScale = size;
    this._updateEffectAnimation(lineData, effectModel, idx);
  };
  EffectLine.prototype._updateEffectAnimation = function (lineData, effectModel, idx) {
    var symbol = this.childAt(1);
    if (!symbol) {
      return;
    }
    var points = lineData.getItemLayout(idx);
    var period = effectModel.get('period') * 1000;
    var loop = effectModel.get('loop');
    var roundTrip = effectModel.get('roundTrip');
    var constantSpeed = effectModel.get('constantSpeed');
    var delayExpr = util.retrieve(effectModel.get('delay'), function (idx) {
      return idx / lineData.count() * period / 3;
    });
    // Ignore when updating
    symbol.ignore = true;
    this._updateAnimationPoints(symbol, points);
    if (constantSpeed > 0) {
      period = this._getLineLength(symbol) / constantSpeed * 1000;
    }
    if (period !== this._period || loop !== this._loop || roundTrip !== this._roundTrip) {
      symbol.stopAnimation();
      var delayNum = void 0;
      if (util.isFunction(delayExpr)) {
        delayNum = delayExpr(idx);
      } else {
        delayNum = delayExpr;
      }
      if (symbol.__t > 0) {
        delayNum = -period * symbol.__t;
      }
      this._animateSymbol(symbol, period, delayNum, loop, roundTrip);
    }
    this._period = period;
    this._loop = loop;
    this._roundTrip = roundTrip;
  };
  EffectLine.prototype._animateSymbol = function (symbol, period, delayNum, loop, roundTrip) {
    if (period > 0) {
      symbol.__t = 0;
      var self_1 = this;
      var animator = symbol.animate('', loop).when(roundTrip ? period * 2 : period, {
        __t: roundTrip ? 2 : 1
      }).delay(delayNum).during(function () {
        self_1._updateSymbolPosition(symbol);
      });
      if (!loop) {
        animator.done(function () {
          self_1.remove(symbol);
        });
      }
      animator.start();
    }
  };
  EffectLine.prototype._getLineLength = function (symbol) {
    // Not so accurate
    return vector.dist(symbol.__p1, symbol.__cp1) + vector.dist(symbol.__cp1, symbol.__p2);
  };
  EffectLine.prototype._updateAnimationPoints = function (symbol, points) {
    symbol.__p1 = points[0];
    symbol.__p2 = points[1];
    symbol.__cp1 = points[2] || [(points[0][0] + points[1][0]) / 2, (points[0][1] + points[1][1]) / 2];
  };
  EffectLine.prototype.updateData = function (lineData, idx, seriesScope) {
    this.childAt(0).updateData(lineData, idx, seriesScope);
    this._updateEffectSymbol(lineData, idx);
  };
  EffectLine.prototype._updateSymbolPosition = function (symbol) {
    var p1 = symbol.__p1;
    var p2 = symbol.__p2;
    var cp1 = symbol.__cp1;
    var t = symbol.__t < 1 ? symbol.__t : 2 - symbol.__t;
    var pos = [symbol.x, symbol.y];
    var lastPos = pos.slice();
    var quadraticAt = curve.quadraticAt;
    var quadraticDerivativeAt = curve.quadraticDerivativeAt;
    pos[0] = quadraticAt(p1[0], cp1[0], p2[0], t);
    pos[1] = quadraticAt(p1[1], cp1[1], p2[1], t);
    // Tangent
    var tx = symbol.__t < 1 ? quadraticDerivativeAt(p1[0], cp1[0], p2[0], t) : quadraticDerivativeAt(p2[0], cp1[0], p1[0], 1 - t);
    var ty = symbol.__t < 1 ? quadraticDerivativeAt(p1[1], cp1[1], p2[1], t) : quadraticDerivativeAt(p2[1], cp1[1], p1[1], 1 - t);
    symbol.rotation = -Math.atan2(ty, tx) - Math.PI / 2;
    // enable continuity trail for 'line', 'rect', 'roundRect' symbolType
    if (this._symbolType === 'line' || this._symbolType === 'rect' || this._symbolType === 'roundRect') {
      if (symbol.__lastT !== undefined && symbol.__lastT < symbol.__t) {
        symbol.scaleY = vector.dist(lastPos, pos) * 1.05;
        // make sure the last segment render within endPoint
        if (t === 1) {
          pos[0] = lastPos[0] + (pos[0] - lastPos[0]) / 2;
          pos[1] = lastPos[1] + (pos[1] - lastPos[1]) / 2;
        }
      } else if (symbol.__lastT === 1) {
        // After first loop, symbol.__t does NOT start with 0, so connect p1 to pos directly.
        symbol.scaleY = 2 * vector.dist(p1, pos);
      } else {
        symbol.scaleY = this._symbolScale[1];
      }
    }
    symbol.__lastT = symbol.__t;
    symbol.ignore = false;
    symbol.x = pos[0];
    symbol.y = pos[1];
  };
  EffectLine.prototype.updateLayout = function (lineData, idx) {
    this.childAt(0).updateLayout(lineData, idx);
    var effectModel = lineData.getItemModel(idx).getModel('effect');
    this._updateEffectAnimation(lineData, effectModel, idx);
  };
  return EffectLine;
}(Group.default);

exports.default = EffectLine;
