var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

import { CompositeLayer, ScatterplotLayer, COORDINATE_SYSTEM } from 'deck.gl';
import PathOutlineLayer from '../path-outline-layer/path-outline-layer';
import MeshLayer from '../mesh-layer/mesh-layer';
import Arrow2DGeometry from './arrow-2d-geometry';

import createPathMarkers from './create-path-markers';
import { getClosestPointOnPolyline } from './polyline';

const DISTANCE_FOR_MULTI_ARROWS = 0.1;
const ARROW_HEAD_SIZE = 0.2;
const ARROW_TAIL_WIDTH = 0.05;
// const ARROW_CENTER_ADJUST = -0.8;

const DEFAULT_MARKER_LAYER = MeshLayer;

const DEFAULT_MARKER_LAYER_PROPS = {
  mesh: new Arrow2DGeometry({ headSize: ARROW_HEAD_SIZE, tailWidth: ARROW_TAIL_WIDTH })
};

const defaultProps = Object.assign({}, PathOutlineLayer.defaultProps, {
  MarkerLayer: DEFAULT_MARKER_LAYER,
  markerLayerProps: DEFAULT_MARKER_LAYER_PROPS,

  sizeScale: 100,
  fp64: false,

  hightlightIndex: -1,
  highlightPoint: null,

  getPath: x => x.path,
  getColor: x => x.color,
  getMarkerColor: x => [0, 0, 0, 255],
  getDirection: x => x.direction,
  getMarkerPercentages: (object, { lineLength }) => lineLength > DISTANCE_FOR_MULTI_ARROWS ? [0.25, 0.5, 0.75] : [0.5]
});

export default class PathMarkerLayer extends CompositeLayer {
  initializeState() {
    this.state = {
      markers: [],
      mesh: new Arrow2DGeometry({ headSize: ARROW_HEAD_SIZE, tailWidth: ARROW_TAIL_WIDTH }),
      closestPoint: null
    };
  }

  projectFlat(xyz, viewport, coordinateSystem, coordinateOrigin) {
    if (coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS) {
      var _viewport$metersToLng = viewport.metersToLngLatDelta(xyz),
          _viewport$metersToLng2 = _slicedToArray(_viewport$metersToLng, 2);

      const dx = _viewport$metersToLng2[0],
            dy = _viewport$metersToLng2[1];

      var _coordinateOrigin = _slicedToArray(coordinateOrigin, 2);

      const x = _coordinateOrigin[0],
            y = _coordinateOrigin[1];

      return viewport.projectFlat([x - dx, dy + y]);
    } else if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT_OFFSETS) {
      var _xyz = _slicedToArray(xyz, 2);

      const dx = _xyz[0],
            dy = _xyz[1];

      var _coordinateOrigin2 = _slicedToArray(coordinateOrigin, 2);

      const x = _coordinateOrigin2[0],
            y = _coordinateOrigin2[1];

      return viewport.projectFlat([x - dx, dy + y]);
    }

    return viewport.projectFlat(xyz);
  }

  updateState({ props, oldProps, changeFlags }) {
    if (changeFlags.dataChanged || changeFlags.updateTriggersChanged) {
      var _props = this.props;
      const data = _props.data,
            getPath = _props.getPath,
            getDirection = _props.getDirection,
            getMarkerColor = _props.getMarkerColor,
            getMarkerPercentages = _props.getMarkerPercentages,
            coordinateSystem = _props.coordinateSystem,
            coordinateOrigin = _props.coordinateOrigin;
      const viewport = this.context.viewport;

      const projectFlat = o => this.projectFlat(o, viewport, coordinateSystem, coordinateOrigin);
      this.state.markers = createPathMarkers({
        data,
        getPath,
        getDirection,
        getColor: getMarkerColor,
        getMarkerPercentages,
        projectFlat
      });
      this._recalculateClosestPoint();
    }
    if (changeFlags.propsChanged) {
      if (props.point !== oldProps.point) {
        this._recalculateClosestPoint();
      }
    }
  }

  _recalculateClosestPoint() {
    var _props2 = this.props;
    const highlightPoint = _props2.highlightPoint,
          highlightIndex = _props2.highlightIndex;

    if (highlightPoint && highlightIndex >= 0) {
      const object = this.props.data[highlightIndex];
      const points = this.props.getPath(object);

      var _getClosestPointOnPol = getClosestPointOnPolyline({ points, p: highlightPoint });

      const point = _getClosestPointOnPol.point;

      this.state.closestPoints = [{
        position: point
      }];
    } else {
      this.state.closestPoints = [];
    }
  }

  getPickingInfo({ info }) {
    return Object.assign(info, {
      // override object with picked feature
      object: info.object && info.object.path || info.object
    });
  }

  renderLayers() {
    return [new PathOutlineLayer(this.getSubLayerProps(Object.assign({}, this.props, {
      id: 'paths',
      fp64: this.props.fp64
    }))), new this.props.MarkerLayer(this.getSubLayerProps(Object.assign({}, this.props.markerLayerProps, {
      id: 'markers',
      data: this.state.markers,
      sizeScale: this.props.sizeScale,
      fp64: this.props.fp64,
      pickable: false,
      parameters: {
        blend: false,
        depthTest: false
      }
    }))), this.state.closestPoints && new ScatterplotLayer({
      id: `${this.props.id}-highlight`,
      data: this.state.closestPoints,
      fp64: this.props.fp64
    })];
  }
}

PathMarkerLayer.layerName = 'PathMarkerLayer';
PathMarkerLayer.defaultProps = defaultProps;
//# sourceMappingURL=path-marker-layer.js.map