'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _mjolnir = require('mjolnir.js');

var _core = require('../../core');

var _cursors = require('./utils/cursors');

var _cursors2 = _interopRequireDefault(_cursors);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var ViewportControls = _core.experimental.ViewportControls,
    TransitionManager = _core.experimental.TransitionManager;


var propTypes = {
  viewportState: _propTypes2.default.func,
  state: _propTypes2.default.object,

  /** Viewport props */
  /** The width of the map. */
  width: _propTypes2.default.number.isRequired,
  /** The height of the map. */
  height: _propTypes2.default.number.isRequired,
  /** The longitude of the center of the map. */
  longitude: _propTypes2.default.number.isRequired,
  /** The latitude of the center of the map. */
  latitude: _propTypes2.default.number.isRequired,
  /** The tile zoom level of the map. */
  zoom: _propTypes2.default.number.isRequired,
  /** Specify the bearing of the viewport */
  bearing: _propTypes2.default.number,
  /** Specify the pitch of the viewport */
  pitch: _propTypes2.default.number,
  /** Altitude of the viewport camera. Default 1.5 "screen heights" */
  // Note: Non-public API, see https://github.com/mapbox/mapbox-gl-js/issues/1137
  altitude: _propTypes2.default.number,
  // Camera position for FirstPersonViewport
  position: _propTypes2.default.array,

  /** Viewport constraints */
  // Max zoom level
  maxZoom: _propTypes2.default.number,
  // Min zoom level
  minZoom: _propTypes2.default.number,
  // Max pitch in degrees
  maxPitch: _propTypes2.default.number,
  // Min pitch in degrees
  minPitch: _propTypes2.default.number,

  /**
   * `onViewportChange` callback is fired when the user interacted with the
   * map. The object passed to the callback contains viewport properties
   * such as `longitude`, `latitude`, `zoom` etc.
   */
  onViewportChange: _propTypes2.default.func,

  /** Viewport transition **/
  // transition duration for viewport change
  transitionDuration: _propTypes2.default.number,
  // an instance of ViewportTransitionInterpolator, can be used to perform custom transitions.
  transitionInterpolator: _propTypes2.default.object,
  // type of interruption of current transition on update.
  transitionInterruption: _propTypes2.default.number,
  // easing function
  transitionEasing: _propTypes2.default.func,
  // transition status update functions
  onTransitionStart: _propTypes2.default.func,
  onTransitionInterrupt: _propTypes2.default.func,
  onTransitionEnd: _propTypes2.default.func,

  /** Enables control event handling */
  // Scroll to zoom
  scrollZoom: _propTypes2.default.bool,
  // Drag to pan
  dragPan: _propTypes2.default.bool,
  // Drag to rotate
  dragRotate: _propTypes2.default.bool,
  // Double click to zoom
  doubleClickZoom: _propTypes2.default.bool,
  // Pinch to zoom / rotate
  touchZoomRotate: _propTypes2.default.bool,

  /** Accessor that returns a cursor style to show interactive state */
  getCursor: _propTypes2.default.func,

  // A map control instance to replace the default map controls
  // The object must expose one property: `events` as an array of subscribed
  // event names; and two methods: `setState(state)` and `handle(event)`
  controls: _propTypes2.default.shape({
    events: _propTypes2.default.arrayOf(_propTypes2.default.string),
    handleEvent: _propTypes2.default.func
  })
};

var getDefaultCursor = function getDefaultCursor(_ref) {
  var isDragging = _ref.isDragging;
  return isDragging ? _cursors2.default.GRABBING : _cursors2.default.GRAB;
};

var defaultProps = Object.assign({}, TransitionManager.defaultProps, {
  onViewportChange: null,

  scrollZoom: true,
  dragPan: true,
  dragRotate: true,
  doubleClickZoom: true,
  touchZoomRotate: true,

  getCursor: getDefaultCursor
});

var ViewportController = function (_Component) {
  _inherits(ViewportController, _Component);

  function ViewportController(props) {
    _classCallCheck(this, ViewportController);

    var _this = _possibleConstructorReturn(this, (ViewportController.__proto__ || Object.getPrototypeOf(ViewportController)).call(this, props));

    _this.state = {
      isDragging: false // Whether the cursor is down
    };
    return _this;
  }

  _createClass(ViewportController, [{
    key: 'componentDidMount',
    value: function componentDidMount() {
      this._eventManager = new _mjolnir.EventManager(this.eventCanvas);

      // If props.controls is not provided, fallback to default MapControls instance
      // Cannot use defaultProps here because it needs to be per map instance
      this._controls = this.props.controls || new ViewportControls(this.props.viewportState);

      this._controls.setOptions(Object.assign({}, this.props, {
        onStateChange: this._onInteractiveStateChange.bind(this),
        eventManager: this._eventManager
      }));

      this._transitionManger = new TransitionManager(this.props);
    }
  }, {
    key: 'shouldComponentUpdate',
    value: function shouldComponentUpdate(nextProps, nextState) {
      if (this._transitionManger) {
        var transitionTriggered = this._transitionManger.processViewportChange(nextProps);
        // Skip this render to avoid jump during viewport transitions.
        return !transitionTriggered;
      }
      return true;
    }
  }, {
    key: 'componentWillUpdate',
    value: function componentWillUpdate(nextProps) {
      if (this._controls) {
        this._controls.setOptions(nextProps);
      }
    }
  }, {
    key: 'componentWillUnmount',
    value: function componentWillUnmount() {
      this._eventManager.destroy();
    }
  }, {
    key: '_onInteractiveStateChange',
    value: function _onInteractiveStateChange(_ref2) {
      var _ref2$isDragging = _ref2.isDragging,
          isDragging = _ref2$isDragging === undefined ? false : _ref2$isDragging;

      if (isDragging !== this.state.isDragging) {
        this.setState({ isDragging: isDragging });
      }
    }
  }, {
    key: 'render',
    value: function render() {
      var _this2 = this;

      var _props = this.props,
          width = _props.width,
          height = _props.height,
          getCursor = _props.getCursor;


      var eventCanvasStyle = {
        width: width,
        height: height,
        position: 'relative',
        cursor: getCursor(this.state)
      };

      return (0, _react.createElement)('div', {
        key: 'map-controls',
        ref: function ref(c) {
          return _this2.eventCanvas = c;
        },
        style: eventCanvasStyle
      }, this.props.children);
    }
  }]);

  return ViewportController;
}(_react.Component);

exports.default = ViewportController;


ViewportController.displayName = 'ViewportController';
ViewportController.propTypes = propTypes;
ViewportController.defaultProps = defaultProps;
//# sourceMappingURL=viewport-controller.js.map