"use strict";

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

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

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 _controller = _interopRequireDefault(require("./controller"));

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

var _mathUtils = require("../utils/math-utils");

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

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

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 MOVEMENT_SPEED = 20;

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

  var _super = _createSuper(FirstPersonState);

  function FirstPersonState(options) {
    (0, _classCallCheck2.default)(this, FirstPersonState);
    var width = options.width,
        height = options.height,
        _options$position = options.position,
        position = _options$position === void 0 ? [0, 0, 0] : _options$position,
        _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$longitude = options.longitude,
        longitude = _options$longitude === void 0 ? null : _options$longitude,
        _options$latitude = options.latitude,
        latitude = _options$latitude === void 0 ? null : _options$latitude,
        _options$maxPitch = options.maxPitch,
        maxPitch = _options$maxPitch === void 0 ? 90 : _options$maxPitch,
        _options$minPitch = options.minPitch,
        minPitch = _options$minPitch === void 0 ? -90 : _options$minPitch,
        startRotatePos = options.startRotatePos,
        startBearing = options.startBearing,
        startPitch = options.startPitch,
        startZoomPosition = options.startZoomPosition;
    return _super.call(this, {
      width: width,
      height: height,
      position: position,
      bearing: bearing,
      pitch: pitch,
      longitude: longitude,
      latitude: latitude,
      maxPitch: maxPitch,
      minPitch: minPitch
    }, {
      startRotatePos: startRotatePos,
      startBearing: startBearing,
      startPitch: startPitch,
      startZoomPosition: startZoomPosition
    });
  }

  var _proto = FirstPersonState.prototype;

  _proto.panStart = function panStart() {
    return this;
  };

  _proto.pan = function pan() {
    return this;
  };

  _proto.panEnd = function panEnd() {
    return this;
  };

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

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

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

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

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

    var newRotation;

    if (pos) {
      var deltaScaleX = (pos[0] - startRotatePos[0]) / width;
      var deltaScaleY = (pos[1] - startRotatePos[1]) / height;
      newRotation = {
        bearing: startBearing - deltaScaleX * 180,
        pitch: startPitch - deltaScaleY * 90
      };
    } else {
      newRotation = {
        bearing: startBearing - deltaAngleX,
        pitch: startPitch - deltaAngleY
      };
    }

    return this._getUpdatedState(newRotation);
  };

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

  _proto.zoomStart = function zoomStart() {
    return this._getUpdatedState({
      startZoomPosition: this.getViewportProps().position
    });
  };

  _proto.zoom = function zoom(_ref3) {
    var scale = _ref3.scale;

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

    if (!startZoomPosition) {
      startZoomPosition = this.getViewportProps().position;
    }

    var direction = this.getDirection();
    return this._move(direction, Math.log2(scale) * MOVEMENT_SPEED, startZoomPosition);
  };

  _proto.zoomEnd = function zoomEnd() {
    return this._getUpdatedState({
      startZoomPosition: null
    });
  };

  _proto.moveLeft = function moveLeft() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MOVEMENT_SPEED;
    var direction = this.getDirection(true);
    return this._move(direction.rotateZ({
      radians: Math.PI / 2
    }), speed);
  };

  _proto.moveRight = function moveRight() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MOVEMENT_SPEED;
    var direction = this.getDirection(true);
    return this._move(direction.rotateZ({
      radians: -Math.PI / 2
    }), speed);
  };

  _proto.moveUp = function moveUp() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MOVEMENT_SPEED;
    var direction = this.getDirection(true);
    return this._move(direction, speed);
  };

  _proto.moveDown = function moveDown() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MOVEMENT_SPEED;
    var direction = this.getDirection(true);
    return this._move(direction.negate(), 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.zoomIn = function zoomIn() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
    return this.zoom({
      scale: speed
    });
  };

  _proto.zoomOut = function zoomOut() {
    var speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
    return this.zoom({
      scale: 1 / 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 (longitude !== null && fromProps.longitude !== null && Math.abs(longitude - fromProps.longitude) > 180) {
      props.longitude = longitude < 0 ? longitude + 360 : longitude - 360;
    }

    return props;
  };

  _proto._move = function _move(direction, speed) {
    var fromPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getViewportProps().position;
    var delta = direction.scale(speed);
    return this._getUpdatedState({
      position: new _core.Vector3(fromPosition).add(delta)
    });
  };

  _proto.getDirection = function getDirection() {
    var use2D = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
    var spherical = new _core._SphericalCoordinates({
      bearing: this.getViewportProps().bearing,
      pitch: use2D ? 90 : 90 + this.getViewportProps().pitch
    });
    var direction = spherical.toVector3().normalize();
    return direction;
  };

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

  _proto.applyConstraints = function applyConstraints(props) {
    var pitch = props.pitch,
        maxPitch = props.maxPitch,
        minPitch = props.minPitch,
        longitude = props.longitude,
        bearing = props.bearing;
    props.pitch = (0, _core.clamp)(pitch, minPitch, maxPitch);

    if (longitude !== null && (longitude < -180 || longitude > 180)) {
      props.longitude = (0, _mathUtils.mod)(longitude + 180, 360) - 180;
    }

    if (bearing < -180 || bearing > 180) {
      props.bearing = (0, _mathUtils.mod)(bearing + 180, 360) - 180;
    }

    return props;
  };

  return FirstPersonState;
}(_viewState.default);

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

  var _super2 = _createSuper(FirstPersonController);

  function FirstPersonController() {
    var _this;

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

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

    _this = _super2.call.apply(_super2, [this].concat(args));
    _this.ControllerState = FirstPersonState;
    _this.transition = {
      transitionDuration: 300,
      transitionInterpolator: new _linearInterpolator.default(['position', 'pitch', 'bearing'])
    };
    return _this;
  }

  return FirstPersonController;
}(_controller.default);

exports.default = FirstPersonController;
//# sourceMappingURL=first-person-controller.js.map