'use strict';

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

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require('babel-runtime/helpers/createClass');

var _createClass3 = _interopRequireDefault(_createClass2);

var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _inherits2 = require('babel-runtime/helpers/inherits');

var _inherits3 = _interopRequireDefault(_inherits2);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

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

var _propTypes2 = _interopRequireDefault(_propTypes);

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

var MTouch = function (_Component) {
	(0, _inherits3.default)(MTouch, _Component);

	function MTouch(props) {
		(0, _classCallCheck3.default)(this, MTouch);

		var _this = (0, _possibleConstructorReturn3.default)(this, (MTouch.__proto__ || Object.getPrototypeOf(MTouch)).call(this, props));

		_this.handleStart = _this.handleStart.bind(_this);
		_this.handleMove = _this.handleMove.bind(_this);
		_this.handleCancel = _this.handleCancel.bind(_this);
		_this.handleEnd = _this.handleEnd.bind(_this);
		_this.emitEvent = _this.emitEvent.bind(_this);
		_this.startX = _this.startY = _this.moveX = _this.moveY = null;
		_this.previousPinchScale = 1;
		_this.longTapTimeout = null;

		_this.maxTapAbsX = 60;
		_this.maxTapAbsY = 60;
		return _this;
	}

	(0, _createClass3.default)(MTouch, [{
		key: 'emitEvent',
		value: function emitEvent(eventType, e) {
			var eventHandler = this.props[eventType];
			if (!eventHandler) return;
			eventHandler(e);
		}
	}, {
		key: 'getTime',
		value: function getTime() {
			return new Date().getTime();
		}
	}, {
		key: 'getDistance',
		value: function getDistance(xLen, yLen) {
			return Math.sqrt(xLen * xLen + yLen * yLen);
		}
		/**
   * 获取向量的旋转方向
   */

	}, {
		key: 'getRotateDirection',
		value: function getRotateDirection(vector1, vector2) {
			return vector1.x * vector2.y - vector2.x * vector1.y;
		}
	}, {
		key: 'getRotateAngle',
		value: function getRotateAngle(vector1, vector2) {
			var direction = this.getRotateDirection(vector1, vector2);
			direction = direction > 0 ? -1 : 1;
			var len1 = this.getDistance(vector1.x, vector1.y);
			var len2 = this.getDistance(vector2.x, vector2.y);
			var mr = len1 * len2;
			if (mr === 0) return 0;
			var dot = vector1.x * vector2.x + vector1.y * vector2.y;
			var r = dot / mr;
			if (r > 1) r = 1;
			if (r < -1) r = -1;
			return Math.acos(r) * direction * 180 / Math.PI;
		}
	}, {
		key: 'handleStart',
		value: function handleStart(event) {
			var _this2 = this;

			var point = event.touches ? event.touches[0] : event;
			this.startX = point.pageX;
			this.startY = point.pageY;
			clearTimeout(this.longTapTimeout);
			// 两点接触
			if (event.touches.length > 1) {
				var point2 = event.touches[1];
				var xLen = Math.abs(point2.pageX - this.startX);
				var yLen = Math.abs(point2.pageY - this.startY);
				this.touchDistance = this.getDistance(xLen, yLen);
				this.touchVector = {
					x: point2.pageX - this.startX,
					y: point2.pageY - this.startY
				};
			} else {
				this.startTime = this.getTime();
				this.longTapTimeout = setTimeout(function () {
					_this2.emitEvent('onLongTap', event);
				}, 800);
				if (this.previousTouchPoint) {
					if (Math.abs(this.startX - this.previousTouchPoint.startX) < this.maxTapAbsX && Math.abs(this.startY - this.previousTouchPoint.startY) < this.maxTapAbsY && Math.abs(this.startTime - this.previousTouchTime) < 300) {
						this.emitEvent('onDoubleTap', event);
					}
				}
				this.previousTouchTime = this.startTime;
				this.previousTouchPoint = {
					startX: this.startX,
					startY: this.startY
				};
			}
		}
	}, {
		key: 'handleMove',
		value: function handleMove(event) {
			var timestamp = this.getTime();
			if (event.touches.length > 1) {
				var xLen = Math.abs(event.touches[0].pageX - event.touches[1].pageX);
				var yLen = Math.abs(event.touches[1].pageY - event.touches[1].pageY);
				var touchDistance = this.getDistance(xLen, yLen);
				if (this.touchDistance) {
					var pinchScale = touchDistance / this.touchDistance;
					this.emitEvent('onPinch', {
						scale: pinchScale - this.previousPinchScale,
						_scale: pinchScale
					});
					this.previousPinchScale = pinchScale;
				}
				if (this.touchVector) {
					var vector = {
						x: event.touches[1].pageX - event.touches[0].pageX,
						y: event.touches[1].pageY - event.touches[0].pageY
					};
					var angle = this.getRotateAngle(vector, this.touchVector);
					this.emitEvent('onRotate', {
						angle: angle
					});
					this.touchVector.x = vector.x;
					this.touchVector.y = vector.y;
				}
			} else {
				clearTimeout(this.longTapTimeout);
				var point = event.touches ? event.touches[0] : event;
				var deltaX = this.moveX === null ? 0 : point.pageX - this.moveX;
				var deltaY = this.moveY === null ? 0 : point.pageY - this.moveY;

				this.emitEvent('onMove', {
					deltaX: deltaX,
					deltaY: deltaY
				});
				this.moveX = point.pageX;
				this.moveY = point.pageY;
			}
			event.preventDefault();
		}
	}, {
		key: 'handleCancel',
		value: function handleCancel(event) {
			this.handleEnd();
		}
	}, {
		key: 'handleEnd',
		value: function handleEnd(event) {
			/**
    * 在X轴或Y轴发生过移动
    */
			clearTimeout(this.longTapTimeout);
			var isDouble = event.changedTouches.length > 1;
			var timestamp = this.getTime();
			var absX = Math.abs(this.moveX - this.startX);
			var deltaX = this.moveX - this.startX;
			var absY = Math.abs(this.moveY - this.startY);
			var deltaY = this.moveY - this.startY;
			/**
    * 每毫秒的运动轨迹px/ms*1000
    * 默认要1秒超过600像素
    */
			var time = timestamp - this.startTime;
			var velocity = this.getDistance(absX, absY) / time;
			var isFlick = velocity > this.props.flickThreshold;
			// 在x轴滑动大于maxTapAbsX ， Y轴下于maxTapAbsY 视为滑动
			if ((this.moveX !== null && absX > this.maxTapAbsX || this.moveY !== null && absY > this.maxTapAbsY) && !isDouble && isFlick) {
				this.emitEvent('onSwipe', { deltaX: deltaX, deltaY: deltaY, isFlick: isFlick });
				if (absX > absY) {
					if (deltaX > 0) {
						this.emitEvent('onSwipeLeft', { deltaX: deltaX, isFlick: isFlick });
					} else {
						this.emitEvent('onSwipeRight', { deltaX: deltaX, isFlick: isFlick });
					}
				} else {
					if (deltaY > 0) {
						this.emitEvent('onSwipeUp', { deltaY: deltaY, isFlick: isFlick });
					} else {
						this.emitEvent('onSwipeDown', { deltaY: deltaY, isFlick: isFlick });
					}
				}
			} else if (timestamp - this.startTime < 2000) {
				if (timestamp - this.startTime < 500) {
					this.emitEvent('onTap', event);
				}
				if (timestamp - this.startTime > 500) {
					// this.emitEvent('onLongTap');
				}
			}
			this.startX = this.startY = this.moveX = this.moveY = null;
			this.previousPinchScale = 1;
		}
	}, {
		key: 'setDefault',
		value: function setDefault() {
			this.previousPinchScale = 1;
		}
	}, {
		key: 'render',
		value: function render() {
			// const { tag: Tag } = this.props;
			return _react2.default.cloneElement(_react2.default.Children.only(this.props.children), {
				onTouchStart: this.handleStart,
				onTouchMove: this.handleMove,
				// onTouchCancel: this.handleCancel,
				onTouchEnd: this.handleEnd
			});
		}
	}]);
	return MTouch;
}(_react.Component);

MTouch.propTypes = {
	// tag: PropTypes.oneOfType([
	// 	PropTypes.string,
	// 	PropTypes.func,
	// ]),
	/**
  * 单击执行
  */
	onTap: _propTypes2.default.func,
	/**
  * 双击执行
  */
	onDoubleTap: _propTypes2.default.func,
	/**
  * 长按执行
  */
	onLongTap: _propTypes2.default.func,
	/**
  * 只要滑动都会执行
  */
	onSwipe: _propTypes2.default.func,
	/**
  * 上滑
  */
	onSwipeUp: _propTypes2.default.func,
	/**
  * 右滑
  */
	onSwipeRight: _propTypes2.default.func,
	/**
  * 下滑
  */
	onSwipeDown: _propTypes2.default.func,
	/**
  * 左滑
  */
	onSwipeLeft: _propTypes2.default.func,
	/**
  * 滑动执行的函数
  */
	onMove: _propTypes2.default.func,
	/**
  * 缩放
  */
	onPinch: _propTypes2.default.func,
	/**
  * 旋转
  */
	onRotate: _propTypes2.default.func
};
MTouch.defaultProps = {
	flickThreshold: 0.6
};
exports.default = MTouch;