"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.MapState = void 0;

var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _core = require("@math.gl/core");

var _controller = _interopRequireDefault(require("./controller"));

var _viewState = _interopRequireDefault(require("./view-state"));

var _webMercator = require("@math.gl/web-mercator");

var _assert = _interopRequireDefault(require("../utils/assert"));

var _linearInterpolator = _interopRequireDefault(require("../transitions/linear-interpolator"));

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }

function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }

var PITCH_MOUSE_THRESHOLD = 5;
var PITCH_ACCEL = 1.2;

var MapState = function (_ViewState) {
  (0, _inherits2.default)(MapState, _ViewState);

  var _super = _createSuper(MapState);

  function MapState(options) {
    var _this;

    (0, _classCallCheck2.default)(this, MapState);
    var width = options.width,
        height = options.height,
        latitude = options.latitude,
        longitude = options.longitude,
        zoom = options.zoom,
        _options$bearing = options.bearing,
        bearing = _options$bearing === void 0 ? 0 : _options$bearing,
        _options$pitch = options.pitch,
        pitch = _options$pitch === void 0 ? 0 : _options$pitch,
        _options$altitude = options.altitude,
        altitude = _options$altitude === void 0 ? 1.5 : _options$altitude,
        _options$position = options.position,
        position = _options$position === void 0 ? [0, 0, 0] : _options$position,
        _options$maxZoom = options.maxZoom,
        maxZoom = _options$maxZoom === void 0 ? 20 : _options$maxZoom,
        _options$minZoom = options.minZoom,
        minZoom = _options$minZoom === void 0 ? 0 : _options$minZoom,
        _options$maxPitch = options.maxPitch,
        maxPitch = _options$maxPitch === void 0 ? 60 : _options$maxPitch,
        _options$minPitch = options.minPitch,
        minPitch = _options$minPitch === void 0 ? 0 : _options$minPitch,
        startPanLngLat = options.startPanLngLat,
        startZoomLngLat = options.startZoomLngLat,
        startRotatePos = options.startRotatePos,
        startBearing = options.startBearing,
        startPitch = options.startPitch,
        startZoom = options.startZoom,
        _options$normalize = options.normalize,
        normalize = _options$normalize === void 0 ? true : _options$normalize;
    (0, _assert.default)(Number.isFinite(longitude));
    (0, _assert.default)(Number.isFinite(latitude));
    (0, _assert.default)(Number.isFinite(zoom));
    _this = _super.call(this, {
      width: width,
      height: height,
      latitude: latitude,
      longitude: longitude,
      zoom: zoom,
      bearing: bearing,
      pitch: pitch,
      altitude: altitude,
      maxZoom: maxZoom,
      minZoom: minZoom,
      maxPitch: maxPitch,
      minPitch: minPitch,
      normalize: normalize,
      position: position
    }, {
      startPanLngLat: startPanLngLat,
      startZoomLngLat: startZoomLngLat,
      startRotatePos: startRotatePos,
      startBearing: startBearing,
      startPitch: startPitch,
      startZoom: startZoom
    });
    _this.makeViewport = void 0;
    _this.makeViewport = options.makeViewport;
    return _this;
  }

  var _proto = MapState.prototype;

  _proto.panStart = function panStart(_ref) {
    var pos = _ref.pos;
    return this._getUpdatedState({
      startPanLngLat: this._unproject(pos)
    });
  };

  _proto.pan = function pan(_ref2) {
    var pos = _ref2.pos,
        startPos = _ref2.startPos;

    var startPanLngLat = this.getState().startPanLngLat || this._unproject(startPos);

    if (!startPanLngLat) {
      return this;
    }

    var viewport = this.makeViewport(this.getViewportProps());
    var newProps = viewport.panByPosition(startPanLngLat, pos);
    return this._getUpdatedState(newProps);
  };

  _proto.panEnd = function panEnd() {
    return this._getUpdatedState({
      startPanLngLat: null
    });
  };

  _proto.rotateStart = function rotateStart(_ref3) {
    var pos = _ref3.pos;
    return this._getUpdatedState({
      startRotatePos: pos,
      startBearing: this.getViewportProps().bearing,
      startPitch: this.getViewportProps().pitch
    });
  };

  _proto.rotate = function rotate(_ref4) {
    var pos = _ref4.pos,
        _ref4$deltaAngleX = _ref4.deltaAngleX,
        deltaAngleX = _ref4$deltaAngleX === void 0 ? 0 : _ref4$deltaAngleX,
        _ref4$deltaAngleY = _ref4.deltaAngleY,
        deltaAngleY = _ref4$deltaAngleY === void 0 ? 0 : _ref4$deltaAngleY;

    var _this$getState = this.getState(),
        startRotatePos = _this$getState.startRotatePos,
        startBearing = _this$getState.startBearing,
        startPitch = _this$getState.startPitch;

    if (!startRotatePos || startBearing === undefined || startPitch === undefined) {
      return this;
    }

    var newRotation;

    if (pos) {
      newRotation = this._getNewRotation(pos, startRotatePos, startPitch, startBearing);
    } else {
      newRotation = {
        bearing: startBearing + deltaAngleX,
        pitch: startPitch + deltaAngleY
      };
    }

    return this._getUpdatedState(newRotation);
  };

  _proto.rotateEnd = function rotateEnd() {
    return this._getUpdatedState({
      startBearing: null,
      startPitch: null
    });
  };

  _proto.zoomStart = function zoomStart(_ref5) {
    var pos = _ref5.pos;
    return this._getUpdatedState({
      startZoomLngLat: this._unproject(pos),
      startZoom: this.getViewportProps().zoom
    });
  };

  _proto.zoom = function zoom(_ref6) {
    var pos = _ref6.pos,
        startPos = _ref6.startPos,
        scale = _ref6.scale;

    var _this$getState2 = this.getState(),
        startZoom = _this$getState2.startZoom,
        startZoomLngLat = _this$getState2.startZoomLngLat;

    if (!startZoomLngLat) {
      startZoom = this.getViewportProps().zoom;
      startZoomLngLat = this._unproject(startPos) || this._unproject(pos);
    }

    if (!startZoomLngLat) {
      return this;
    }

    var _this$getViewportProp = this.getViewportProps(),
        maxZoom = _this$getViewportProp.maxZoom,
        minZoom = _this$getViewportProp.minZoom;

    var zoom = startZoom + Math.log2(scale);
    zoom = (0, _core.clamp)(zoom, minZoom, maxZoom);
    var zoomedViewport = this.makeViewport(_objectSpread(_objectSpread({}, this.getViewportProps()), {}, {
      zoom: zoom
    }));
    return this._getUpdatedState(_objectSpread({
      zoom: zoom
    }, zoomedViewport.panByPosition(startZoomLngLat, pos)));
  };

  _proto.zoomEnd = function zoomEnd() {
    return this._getUpdatedState({
      startZoomLngLat: null,
      startZoom: null
    });
  };

  _proto.zoomIn = function zoomIn() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
    return this._zoomFromCenter(speed);
  };

  _proto.zoomOut = function zoomOut() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
    return this._zoomFromCenter(1 / speed);
  };

  _proto.moveLeft = function moveLeft() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100;
    return this._panFromCenter([speed, 0]);
  };

  _proto.moveRight = function moveRight() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100;
    return this._panFromCenter([-speed, 0]);
  };

  _proto.moveUp = function moveUp() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100;
    return this._panFromCenter([0, speed]);
  };

  _proto.moveDown = function moveDown() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100;
    return this._panFromCenter([0, -speed]);
  };

  _proto.rotateLeft = function rotateLeft() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 15;
    return this._getUpdatedState({
      bearing: this.getViewportProps().bearing - speed
    });
  };

  _proto.rotateRight = function rotateRight() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 15;
    return this._getUpdatedState({
      bearing: this.getViewportProps().bearing + speed
    });
  };

  _proto.rotateUp = function rotateUp() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
    return this._getUpdatedState({
      pitch: this.getViewportProps().pitch + speed
    });
  };

  _proto.rotateDown = function rotateDown() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
    return this._getUpdatedState({
      pitch: this.getViewportProps().pitch - speed
    });
  };

  _proto.shortestPathFrom = function shortestPathFrom(viewState) {
    var fromProps = viewState.getViewportProps();

    var props = _objectSpread({}, this.getViewportProps());

    var bearing = props.bearing,
        longitude = props.longitude;

    if (Math.abs(bearing - fromProps.bearing) > 180) {
      props.bearing = bearing < 0 ? bearing + 360 : bearing - 360;
    }

    if (Math.abs(longitude - fromProps.longitude) > 180) {
      props.longitude = longitude < 0 ? longitude + 360 : longitude - 360;
    }

    return props;
  };

  _proto.applyConstraints = function applyConstraints(props) {
    var maxZoom = props.maxZoom,
        minZoom = props.minZoom,
        zoom = props.zoom;
    props.zoom = (0, _core.clamp)(zoom, minZoom, maxZoom);
    var maxPitch = props.maxPitch,
        minPitch = props.minPitch,
        pitch = props.pitch;
    props.pitch = (0, _core.clamp)(pitch, minPitch, maxPitch);
    var _props$normalize = props.normalize,
        normalize = _props$normalize === void 0 ? true : _props$normalize;

    if (normalize) {
      Object.assign(props, (0, _webMercator.normalizeViewportProps)(props));
    }

    return props;
  };

  _proto._zoomFromCenter = function _zoomFromCenter(scale) {
    var _this$getViewportProp2 = this.getViewportProps(),
        width = _this$getViewportProp2.width,
        height = _this$getViewportProp2.height;

    return this.zoom({
      pos: [width / 2, height / 2],
      scale: scale
    });
  };

  _proto._panFromCenter = function _panFromCenter(offset) {
    var _this$getViewportProp3 = this.getViewportProps(),
        width = _this$getViewportProp3.width,
        height = _this$getViewportProp3.height;

    return this.pan({
      startPos: [width / 2, height / 2],
      pos: [width / 2 + offset[0], height / 2 + offset[1]]
    });
  };

  _proto._getUpdatedState = function _getUpdatedState(newProps) {
    return new this.constructor(_objectSpread(_objectSpread(_objectSpread({
      makeViewport: this.makeViewport
    }, this.getViewportProps()), this.getState()), newProps));
  };

  _proto._unproject = function _unproject(pos) {
    var viewport = this.makeViewport(this.getViewportProps());
    return pos && viewport.unproject(pos);
  };

  _proto._getNewRotation = function _getNewRotation(pos, startPos, startPitch, startBearing) {
    var deltaX = pos[0] - startPos[0];
    var deltaY = pos[1] - startPos[1];
    var centerY = pos[1];
    var startY = startPos[1];

    var _this$getViewportProp4 = this.getViewportProps(),
        width = _this$getViewportProp4.width,
        height = _this$getViewportProp4.height;

    var deltaScaleX = deltaX / width;
    var deltaScaleY = 0;

    if (deltaY > 0) {
      if (Math.abs(height - startY) > PITCH_MOUSE_THRESHOLD) {
        deltaScaleY = deltaY / (startY - height) * PITCH_ACCEL;
      }
    } else if (deltaY < 0) {
      if (startY > PITCH_MOUSE_THRESHOLD) {
        deltaScaleY = 1 - centerY / startY;
      }
    }

    deltaScaleY = (0, _core.clamp)(deltaScaleY, -1, 1);

    var _this$getViewportProp5 = this.getViewportProps(),
        minPitch = _this$getViewportProp5.minPitch,
        maxPitch = _this$getViewportProp5.maxPitch;

    var bearing = startBearing + 180 * deltaScaleX;
    var pitch = startPitch;

    if (deltaScaleY > 0) {
      pitch = startPitch + deltaScaleY * (maxPitch - startPitch);
    } else if (deltaScaleY < 0) {
      pitch = startPitch - deltaScaleY * (minPitch - startPitch);
    }

    return {
      pitch: pitch,
      bearing: bearing
    };
  };

  return MapState;
}(_viewState.default);

exports.MapState = MapState;

var MapController = function (_Controller) {
  (0, _inherits2.default)(MapController, _Controller);

  var _super2 = _createSuper(MapController);

  function MapController() {
    var _this2;

    (0, _classCallCheck2.default)(this, MapController);

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    _this2 = _super2.call.apply(_super2, [this].concat(args));
    _this2.ControllerState = MapState;
    _this2.transition = {
      transitionDuration: 300,
      transitionInterpolator: new _linearInterpolator.default({
        transitionProps: {
          compare: ['longitude', 'latitude', 'zoom', 'bearing', 'pitch', 'position'],
          required: ['longitude', 'latitude', 'zoom']
        }
      })
    };
    _this2.dragMode = 'pan';
    return _this2;
  }

  var _proto2 = MapController.prototype;

  _proto2.setProps = function setProps(props) {
    props.position = props.position || [0, 0, 0];
    var oldProps = this.props;
    (0, _get2.default)((0, _getPrototypeOf2.default)(MapController.prototype), "setProps", this).call(this, props);
    var dimensionChanged = !oldProps || oldProps.height !== props.height;

    if (dimensionChanged) {
      this.updateViewport(new this.ControllerState(_objectSpread(_objectSpread({
        makeViewport: this.makeViewport
      }, props), this.state)));
    }
  };

  return MapController;
}(_controller.default);

exports.default = MapController;
//# sourceMappingURL=map-controller.js.map