import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
var _excluded = ["tagName", "className", "style", "children", "allowMouseEvents", "onSwipeUp", "onSwipeDown", "onSwipeLeft", "onSwipeRight", "onSwipeStart", "onSwipeMove", "onSwipeEnd", "innerRef", "tolerance"];
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
import React, { Component } from 'react';
import PropTypes from 'prop-types';
var supportsCaptureOption = false;
export function setHasSupportToCaptureOption(hasSupport) {
  supportsCaptureOption = hasSupport;
}
try {
  addEventListener('test', null, Object.defineProperty({}, 'capture', {
    get: function get() {
      setHasSupportToCaptureOption(true);
    }
  }));
} catch (e) {} // eslint-disable-line no-empty

function getSafeEventHandlerOpts() {
  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
    capture: true
  };
  return supportsCaptureOption ? options : false;
}

/**
 * [getPosition returns a position element that works for mouse or touch events]
 * @param  {[Event]} event [the received event]
 * @return {[Object]}      [x and y coords]
 */
function getPosition(event) {
  if ('touches' in event) {
    var _event$touches$ = event.touches[0],
      pageX = _event$touches$.pageX,
      pageY = _event$touches$.pageY;
    return {
      x: pageX,
      y: pageY
    };
  }
  var screenX = event.screenX,
    screenY = event.screenY;
  return {
    x: screenX,
    y: screenY
  };
}
var ReactSwipe = /*#__PURE__*/function (_Component) {
  function ReactSwipe() {
    var _this;
    _classCallCheck(this, ReactSwipe);
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
    _this = _callSuper(this, ReactSwipe, [].concat(args));
    _this._handleSwipeStart = _this._handleSwipeStart.bind(_this);
    _this._handleSwipeMove = _this._handleSwipeMove.bind(_this);
    _this._handleSwipeEnd = _this._handleSwipeEnd.bind(_this);
    _this._onMouseDown = _this._onMouseDown.bind(_this);
    _this._onMouseMove = _this._onMouseMove.bind(_this);
    _this._onMouseUp = _this._onMouseUp.bind(_this);
    _this._setSwiperRef = _this._setSwiperRef.bind(_this);
    return _this;
  }
  _inherits(ReactSwipe, _Component);
  return _createClass(ReactSwipe, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      if (this.swiper) {
        this.swiper.addEventListener('touchmove', this._handleSwipeMove, getSafeEventHandlerOpts({
          capture: true,
          passive: false
        }));
      }
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      if (this.swiper) {
        this.swiper.removeEventListener('touchmove', this._handleSwipeMove, getSafeEventHandlerOpts({
          capture: true,
          passive: false
        }));
      }
    }
  }, {
    key: "_onMouseDown",
    value: function _onMouseDown(event) {
      if (!this.props.allowMouseEvents) {
        return;
      }
      this.mouseDown = true;
      document.addEventListener('mouseup', this._onMouseUp);
      document.addEventListener('mousemove', this._onMouseMove);
      this._handleSwipeStart(event);
    }
  }, {
    key: "_onMouseMove",
    value: function _onMouseMove(event) {
      if (!this.mouseDown) {
        return;
      }
      this._handleSwipeMove(event);
    }
  }, {
    key: "_onMouseUp",
    value: function _onMouseUp(event) {
      this.mouseDown = false;
      document.removeEventListener('mouseup', this._onMouseUp);
      document.removeEventListener('mousemove', this._onMouseMove);
      this._handleSwipeEnd(event);
    }
  }, {
    key: "_handleSwipeStart",
    value: function _handleSwipeStart(event) {
      var _getPosition = getPosition(event),
        x = _getPosition.x,
        y = _getPosition.y;
      this.moveStart = {
        x: x,
        y: y
      };
      this.props.onSwipeStart(event);
    }
  }, {
    key: "_handleSwipeMove",
    value: function _handleSwipeMove(event) {
      if (!this.moveStart) {
        return;
      }
      var _getPosition2 = getPosition(event),
        x = _getPosition2.x,
        y = _getPosition2.y;
      var deltaX = x - this.moveStart.x;
      var deltaY = y - this.moveStart.y;
      this.moving = true;

      // handling the responsability of cancelling the scroll to
      // the component handling the event
      var shouldPreventDefault = this.props.onSwipeMove({
        x: deltaX,
        y: deltaY
      }, event);
      if (shouldPreventDefault && event.cancelable) {
        event.preventDefault();
      }
      this.movePosition = {
        deltaX: deltaX,
        deltaY: deltaY
      };
    }
  }, {
    key: "_handleSwipeEnd",
    value: function _handleSwipeEnd(event) {
      this.props.onSwipeEnd(event);
      var tolerance = this.props.tolerance;
      if (this.moving && this.movePosition) {
        if (this.movePosition.deltaX < -tolerance) {
          this.props.onSwipeLeft(1, event);
        } else if (this.movePosition.deltaX > tolerance) {
          this.props.onSwipeRight(1, event);
        }
        if (this.movePosition.deltaY < -tolerance) {
          this.props.onSwipeUp(1, event);
        } else if (this.movePosition.deltaY > tolerance) {
          this.props.onSwipeDown(1, event);
        }
      }
      this.moveStart = null;
      this.moving = false;
      this.movePosition = null;
    }
  }, {
    key: "_setSwiperRef",
    value: function _setSwiperRef(node) {
      this.swiper = node;
      this.props.innerRef(node);
    }
  }, {
    key: "render",
    value: function render() {
      var _this$props = this.props,
        tagName = _this$props.tagName,
        className = _this$props.className,
        style = _this$props.style,
        children = _this$props.children,
        allowMouseEvents = _this$props.allowMouseEvents,
        onSwipeUp = _this$props.onSwipeUp,
        onSwipeDown = _this$props.onSwipeDown,
        onSwipeLeft = _this$props.onSwipeLeft,
        onSwipeRight = _this$props.onSwipeRight,
        onSwipeStart = _this$props.onSwipeStart,
        onSwipeMove = _this$props.onSwipeMove,
        onSwipeEnd = _this$props.onSwipeEnd,
        innerRef = _this$props.innerRef,
        tolerance = _this$props.tolerance,
        props = _objectWithoutProperties(_this$props, _excluded);
      return /*#__PURE__*/React.createElement(this.props.tagName, _extends({
        ref: this._setSwiperRef,
        onMouseDown: this._onMouseDown,
        onTouchStart: this._handleSwipeStart,
        onTouchEnd: this._handleSwipeEnd,
        className: className,
        style: style
      }, props), children);
    }
  }]);
}(Component);
_defineProperty(ReactSwipe, "displayName", 'ReactSwipe');
_defineProperty(ReactSwipe, "propTypes", {
  tagName: PropTypes.string,
  className: PropTypes.string,
  style: PropTypes.object,
  children: PropTypes.node,
  allowMouseEvents: PropTypes.bool,
  onSwipeUp: PropTypes.func,
  onSwipeDown: PropTypes.func,
  onSwipeLeft: PropTypes.func,
  onSwipeRight: PropTypes.func,
  onSwipeStart: PropTypes.func,
  onSwipeMove: PropTypes.func,
  onSwipeEnd: PropTypes.func,
  innerRef: PropTypes.func,
  tolerance: PropTypes.number.isRequired
});
_defineProperty(ReactSwipe, "defaultProps", {
  tagName: 'div',
  allowMouseEvents: false,
  onSwipeUp: function onSwipeUp() {},
  onSwipeDown: function onSwipeDown() {},
  onSwipeLeft: function onSwipeLeft() {},
  onSwipeRight: function onSwipeRight() {},
  onSwipeStart: function onSwipeStart() {},
  onSwipeMove: function onSwipeMove() {},
  onSwipeEnd: function onSwipeEnd() {},
  innerRef: function innerRef() {},
  tolerance: 0
});
export default ReactSwipe;