import DataUtils from '../utils/DataUtils';
import SimpleMarkerLayer from './SimpleMarkerLayer';
import SimpleLineLayer from './SimpleLineLayer';

/**
 * 定义动态流向图层
 * @alias FlowLayer
 *
 * @summary <用于追溯分析>
 */
export default class FlowLayer {
  /**
   * 构造函数
   * @param {Object} options -图层选项
   */
  constructor(options) {
    /**
     * 地图对象
     * @type {Object}
     */
    this._map = options.map;

    /**
     * 最小缩放层级
     * @type {Number}
     */
    this._minzoom = DataUtils.default(options.minzoom, 10);

    /**
     * 管线颜色
     * @type {String}
     */
    this._lineColor = DataUtils.default(options.color, '#2E8B57');

    /**
     * 线宽
     * @type {Number}
     */
    this._lineWidth = DataUtils.default(options.width, 4.5);

    /**
     * 是否固定(线宽)
     * @type {Boolean}
     */
    this._fixed = DataUtils.default(options.fixed, true);

    /**
     * 数据源ID
     * @type {String}
     */
    this._sourceId = DataUtils.default(options.sourceId, 'pipenet_flow');

    /**
     * 图层ID
     * @type {String}
     */
    this._layerId = DataUtils.default(options.layerId, this._sourceId);
    this._lineDashLayerId = this._layerId + '-dash';
    this._directionLayerId = this._layerId + '-direction';

    this._state = 'stop'; // 状态(play、stop)
    this._frameId = null;

    /** 图层 **/
    this._lineLayer = null; // 线图层
    this._lineDashLayer = null; // 虚线图层
    this._directionLayer = null; // 方向点图层

    // 初始化图层
    this._initLayers();
  }

  /** 公有方法 **/
  /**
   * 设置颜色
   * @param {String} color -16进制颜色字符串
   */
  setColor(color) {
    this._lineColor = color;
  }

  /**
   * 设置数据
   * @param {Object} data -GeoJSON要素/要素集
   */
  setData(data) {
    // 线数据
    this._lineLayer.setData(data);
    this._lineDashLayer.setData(data);

    // 点数据
    this._directionLayer.setData(data);
  }

  /**
   * 显示/隐藏图层
   * @param {Boolean} show -是否显示
   */
  showLayer(show) {
    // 线图层
    this._lineLayer.showLayer(show);
    this._lineDashLayer.showLayer(show);
    // 点图层
    this._directionLayer.showLayer(show);
  }

  /**
   * 移除图层(and数据源)
   */
  removeLayer() {
    // 线图层
    this._lineLayer.removeLayer();
    this._lineDashLayer.removeLayer();
    // 点图层
    this._directionLayer.removeLayer();

    // 数据源
    this._lineLayer.removeSource();
  }

  /**
   * 开始
   */
  start() {
    this._state = 'play'; // 开始播放

    const that = this;
    // technique based on https://jsfiddle.net/2mws8y3q/
    // an array of valid line-dasharray values, specifying the lengths of the alternating dashes and gaps that form the dash pattern
    const dashArraySequence = [
      [0, 4, 3],
      [0.5, 4, 2.5],
      [1, 4, 2],
      [1.5, 4, 1.5],
      [2, 4, 1],
      [2.5, 4, 0.5],
      [3, 4, 0],
      [0, 0.5, 3, 3.5],
      [0, 1, 3, 3],
      [0, 1.5, 3, 2.5],
      [0, 2, 3, 2],
      [0, 2.5, 3, 1.5],
      [0, 3, 3, 1],
      [0, 3.5, 3, 0.5],
    ];

    let step = 0;
    function _animateDashArray(timestamp) {
      if (that._state === 'play') {
        // Update line-dasharray using the next value in dashArraySequence. The
        // divisor in the expression `timestamp / 50` controls the animation speed.
        const newStep = parseInt(
          (timestamp / 200) % dashArraySequence.length
        );

        if (newStep !== step) {
          that._lineDashLayer.setPaintProperty('line-dasharray', dashArraySequence[step]);
          step = newStep;
        }

        // Request the next frame of the animation.
        that._frameId = requestAnimationFrame(_animateDashArray);
      }
    }

    // start the animation
    _animateDashArray(0);
  }

  /**
   * 停止
   */
  stop() {
    this._state = 'stop';

    if (this._frameId) {
      cancelAnimationFrame(this._frameId);
    }
  }

  /** 私有方法 **/
  /**
   * 初始化图层
   */
  _initLayers() {
    const map = this._map;
    const minZoom = this._minzoom

    // 线图层
    this._lineLayer = new SimpleLineLayer({
      map: map,
      minzoom: minZoom,
      color: this._lineColor,
      width: this._lineWidth,
      opacity: 0.45,
      fixed: this._fixed,
      metrics: true,
      sourceId: this._sourceId,
      layerId: this._layerId
    });

    // 虚线图层
    this._lineDashLayer = new SimpleLineLayer({
      map: map,
      minzoom: minZoom,
      color: this._lineColor,
      width: this._lineWidth,
      opacity: 0.95,
      dasharray: [0, 4, 3],
      fixed: this._fixed,
      metrics: true,
      sourceId: this._sourceId,
      layerId: this._lineDashLayerId
    });

    // 方向点图层
    this._directionLayer = new SimpleMarkerLayer({
      map: map,
      minzoom: minZoom,
      icon: 'busi_arrow',
      sourceId: this._sourceId,
      layerId: this._directionLayerId
    });
    // 设置自定义样式
    this._directionLayer.setLayoutProperty('symbol-placement', 'line');
    this._directionLayer.setLayoutProperty('symbol-spacing', [
      "interpolate",
      ["linear"],
      ["zoom"],
      10, 150,
      18, 250
    ]);
  }
}
