'use strict';

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

var _index = require('../index.js');

var _index2 = _interopRequireDefault(_index);

var _viewhint = require('../viewhint.js');

var _viewhint2 = _interopRequireDefault(_viewhint);

var _coordinate = require('../coordinate.js');

var _coordinate2 = _interopRequireDefault(_coordinate);

var _easing = require('../easing.js');

var _easing2 = _interopRequireDefault(_easing);

var _condition = require('../events/condition.js');

var _condition2 = _interopRequireDefault(_condition);

var _functions = require('../functions.js');

var _functions2 = _interopRequireDefault(_functions);

var _pointer = require('../interaction/pointer.js');

var _pointer2 = _interopRequireDefault(_pointer);

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

/**
 * @classdesc
 * Allows the user to pan the map by dragging the map.
 *
 * @constructor
 * @extends {ol.interaction.Pointer}
 * @param {olx.interaction.DragPanOptions=} opt_options Options.
 * @api
 */
var _ol_interaction_DragPan_ = function (opt_options) {

  _pointer2.default.call(this, {
    handleDownEvent: _ol_interaction_DragPan_.handleDownEvent_,
    handleDragEvent: _ol_interaction_DragPan_.handleDragEvent_,
    handleUpEvent: _ol_interaction_DragPan_.handleUpEvent_
  });

  var options = opt_options ? opt_options : {};

  /**
   * @private
   * @type {ol.Kinetic|undefined}
   */
  this.kinetic_ = options.kinetic;

  /**
   * @type {ol.Pixel}
   */
  this.lastCentroid = null;

  /**
   * @type {number}
   */
  this.lastPointersCount_;

  /**
   * @private
   * @type {ol.EventsConditionType}
   */
  this.condition_ = options.condition ? options.condition : _condition2.default.noModifierKeys;

  /**
   * @private
   * @type {boolean}
   */
  this.noKinetic_ = false;
};

_index2.default.inherits(_ol_interaction_DragPan_, _pointer2.default);

/**
 * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
 * @this {ol.interaction.DragPan}
 * @private
 */
_ol_interaction_DragPan_.handleDragEvent_ = function (mapBrowserEvent) {
  var targetPointers = this.targetPointers;
  var centroid = _pointer2.default.centroid(targetPointers);
  if (targetPointers.length == this.lastPointersCount_) {
    if (this.kinetic_) {
      this.kinetic_.update(centroid[0], centroid[1]);
    }
    if (this.lastCentroid) {
      var deltaX = this.lastCentroid[0] - centroid[0];
      var deltaY = centroid[1] - this.lastCentroid[1];
      var map = mapBrowserEvent.map;
      var view = map.getView();
      var viewState = view.getState();
      var center = [deltaX, deltaY];
      _coordinate2.default.scale(center, viewState.resolution);
      _coordinate2.default.rotate(center, viewState.rotation);
      _coordinate2.default.add(center, viewState.center);
      center = view.constrainCenter(center);
      view.setCenter(center);
    }
  } else if (this.kinetic_) {
    // reset so we don't overestimate the kinetic energy after
    // after one finger down, tiny drag, second finger down
    this.kinetic_.begin();
  }
  this.lastCentroid = centroid;
  this.lastPointersCount_ = targetPointers.length;
};

/**
 * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
 * @return {boolean} Stop drag sequence?
 * @this {ol.interaction.DragPan}
 * @private
 */
_ol_interaction_DragPan_.handleUpEvent_ = function (mapBrowserEvent) {
  var map = mapBrowserEvent.map;
  var view = map.getView();
  if (this.targetPointers.length === 0) {
    if (!this.noKinetic_ && this.kinetic_ && this.kinetic_.end()) {
      var distance = this.kinetic_.getDistance();
      var angle = this.kinetic_.getAngle();
      var center = /** @type {!ol.Coordinate} */view.getCenter();
      var centerpx = map.getPixelFromCoordinate(center);
      var dest = map.getCoordinateFromPixel([centerpx[0] - distance * Math.cos(angle), centerpx[1] - distance * Math.sin(angle)]);
      view.animate({
        center: view.constrainCenter(dest),
        duration: 500,
        easing: _easing2.default.easeOut
      });
    }
    view.setHint(_viewhint2.default.INTERACTING, -1);
    return false;
  } else {
    if (this.kinetic_) {
      // reset so we don't overestimate the kinetic energy after
      // after one finger up, tiny drag, second finger up
      this.kinetic_.begin();
    }
    this.lastCentroid = null;
    return true;
  }
};

/**
 * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
 * @return {boolean} Start drag sequence?
 * @this {ol.interaction.DragPan}
 * @private
 */
_ol_interaction_DragPan_.handleDownEvent_ = function (mapBrowserEvent) {
  if (this.targetPointers.length > 0 && this.condition_(mapBrowserEvent)) {
    var map = mapBrowserEvent.map;
    var view = map.getView();
    this.lastCentroid = null;
    if (!this.handlingDownUpSequence) {
      view.setHint(_viewhint2.default.INTERACTING, 1);
    }
    // stop any current animation
    if (view.getAnimating()) {
      view.setCenter(mapBrowserEvent.frameState.viewState.center);
    }
    if (this.kinetic_) {
      this.kinetic_.begin();
    }
    // No kinetic as soon as more than one pointer on the screen is
    // detected. This is to prevent nasty pans after pinch.
    this.noKinetic_ = this.targetPointers.length > 1;
    return true;
  } else {
    return false;
  }
};

/**
 * @inheritDoc
 */
_ol_interaction_DragPan_.prototype.shouldStopEvent = _functions2.default.FALSE;
exports.default = _ol_interaction_DragPan_;
module.exports = exports['default'];