"use strict";

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

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.OrbitState = 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 _core = require("@math.gl/core");

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

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

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

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 OrbitState = function (_ViewState) {
  (0, _inherits2.default)(OrbitState, _ViewState);

  var _super = _createSuper(OrbitState);

  function OrbitState(options) {
    var _this;

    (0, _classCallCheck2.default)(this, OrbitState);
    var width = options.width,
        height = options.height,
        _options$rotationX = options.rotationX,
        rotationX = _options$rotationX === void 0 ? 0 : _options$rotationX,
        _options$rotationOrbi = options.rotationOrbit,
        rotationOrbit = _options$rotationOrbi === void 0 ? 0 : _options$rotationOrbi,
        _options$target = options.target,
        target = _options$target === void 0 ? [0, 0, 0] : _options$target,
        _options$zoom = options.zoom,
        zoom = _options$zoom === void 0 ? 0 : _options$zoom,
        _options$minRotationX = options.minRotationX,
        minRotationX = _options$minRotationX === void 0 ? -90 : _options$minRotationX,
        _options$maxRotationX = options.maxRotationX,
        maxRotationX = _options$maxRotationX === void 0 ? 90 : _options$maxRotationX,
        _options$minZoom = options.minZoom,
        minZoom = _options$minZoom === void 0 ? -Infinity : _options$minZoom,
        _options$maxZoom = options.maxZoom,
        maxZoom = _options$maxZoom === void 0 ? Infinity : _options$maxZoom,
        startPanPosition = options.startPanPosition,
        startRotatePos = options.startRotatePos,
        startRotationX = options.startRotationX,
        startRotationOrbit = options.startRotationOrbit,
        startZoomPosition = options.startZoomPosition,
        startZoom = options.startZoom;
    _this = _super.call(this, {
      width: width,
      height: height,
      rotationX: rotationX,
      rotationOrbit: rotationOrbit,
      target: target,
      zoom: zoom,
      minRotationX: minRotationX,
      maxRotationX: maxRotationX,
      minZoom: minZoom,
      maxZoom: maxZoom
    }, {
      startPanPosition: startPanPosition,
      startRotatePos: startRotatePos,
      startRotationX: startRotationX,
      startRotationOrbit: startRotationOrbit,
      startZoomPosition: startZoomPosition,
      startZoom: startZoom
    });
    _this.makeViewport = void 0;
    _this.makeViewport = options.makeViewport;
    return _this;
  }

  var _proto = OrbitState.prototype;

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

  _proto.pan = function pan(_ref2) {
    var pos = _ref2.pos,
        startPosition = _ref2.startPosition;
    var startPanPosition = this.getState().startPanPosition || startPosition;

    if (!startPanPosition) {
      return this;
    }

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

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

  _proto.rotateStart = function rotateStart(_ref3) {
    var pos = _ref3.pos;
    return this._getUpdatedState({
      startRotatePos: pos,
      startRotationX: this.getViewportProps().rotationX,
      startRotationOrbit: this.getViewportProps().rotationOrbit
    });
  };

  _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,
        startRotationX = _this$getState.startRotationX,
        startRotationOrbit = _this$getState.startRotationOrbit;

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

    if (!startRotatePos || startRotationX === undefined || startRotationOrbit === undefined) {
      return this;
    }

    var newRotation;

    if (pos) {
      var deltaScaleX = (pos[0] - startRotatePos[0]) / width;
      var deltaScaleY = (pos[1] - startRotatePos[1]) / height;

      if (startRotationX < -90 || startRotationX > 90) {
        deltaScaleX *= -1;
      }

      newRotation = {
        rotationX: startRotationX + deltaScaleY * 180,
        rotationOrbit: startRotationOrbit + deltaScaleX * 180
      };
    } else {
      newRotation = {
        rotationX: startRotationX + deltaAngleY,
        rotationOrbit: startRotationOrbit + deltaAngleX
      };
    }

    return this._getUpdatedState(newRotation);
  };

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

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

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

    var rotationOrbit = props.rotationOrbit;

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

    return props;
  };

  _proto.zoomStart = function zoomStart(_ref5) {
    var pos = _ref5.pos;
    return this._getUpdatedState({
      startZoomPosition: 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,
        startZoomPosition = _this$getState2.startZoomPosition;

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

    if (!startZoomPosition) {
      return this;
    }

    var newZoom = this._calculateNewZoom({
      scale: scale,
      startZoom: startZoom
    });

    var zoomedViewport = this.makeViewport(_objectSpread(_objectSpread({}, this.getViewportProps()), {}, {
      zoom: newZoom
    }));
    return this._getUpdatedState(_objectSpread({
      zoom: newZoom
    }, zoomedViewport.panByPosition(startZoomPosition, pos)));
  };

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

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

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

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

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

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

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

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

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

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

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

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

  _proto._calculateNewZoom = function _calculateNewZoom(_ref7) {
    var scale = _ref7.scale,
        startZoom = _ref7.startZoom;

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

    if (startZoom === undefined) {
      startZoom = this.getViewportProps().zoom;
    }

    var zoom = startZoom + Math.log2(scale);
    return (0, _core.clamp)(zoom, minZoom, maxZoom);
  };

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

    return this.pan({
      startPosition: target,
      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.applyConstraints = function applyConstraints(props) {
    var maxZoom = props.maxZoom,
        minZoom = props.minZoom,
        zoom = props.zoom,
        maxRotationX = props.maxRotationX,
        minRotationX = props.minRotationX,
        rotationOrbit = props.rotationOrbit;
    props.zoom = Array.isArray(zoom) ? [(0, _core.clamp)(zoom[0], minZoom, maxZoom), (0, _core.clamp)(zoom[1], minZoom, maxZoom)] : (0, _core.clamp)(zoom, minZoom, maxZoom);
    props.rotationX = (0, _core.clamp)(props.rotationX, minRotationX, maxRotationX);

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

    return props;
  };

  return OrbitState;
}(_viewState.default);

exports.OrbitState = OrbitState;

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

  var _super2 = _createSuper(OrbitController);

  function OrbitController() {
    var _this2;

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

    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 = OrbitState;
    _this2.transition = {
      transitionDuration: 300,
      transitionInterpolator: new _linearInterpolator.default({
        transitionProps: {
          compare: ['target', 'zoom', 'rotationX', 'rotationOrbit'],
          required: ['target', 'zoom']
        }
      })
    };
    return _this2;
  }

  return OrbitController;
}(_controller.default);

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