'use strict';

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

var _extends2 = require('babel-runtime/helpers/extends');

var _extends3 = _interopRequireDefault(_extends2);

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 _class, _temp, _initialiseProps; /**
                                      * 待开发，未完成
                                      */


var _react = require('react');

var _react2 = _interopRequireDefault(_react);

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

var _propTypes2 = _interopRequireDefault(_propTypes);

require('./Swiper.scss');

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

var Swiper = (_temp = _class = function (_Component) {
	(0, _inherits3.default)(Swiper, _Component);

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

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

		_initialiseProps.call(_this);

		var _this$props = _this.props,
		    children = _this$props.children,
		    width = _this$props.width;

		var len = children ? children.length : 1;
		var curIndex = 0;
		var lefts = children.map(function (ele, index) {
			if (index - curIndex >= -1) {
				return index * width;
			} else {
				return (index + len) * width;
			}
		});
		var curTransLateX = -1 * curIndex * width;

		_this.state = {
			width: width,
			lefts: lefts,
			// 位移
			curTransLateX: curTransLateX,
			// 当前的正在展示的序列号
			curIndex: curIndex,
			// 父容器
			contentStyle: {
				width: len * 100 + '%',
				height: '100%',
				transform: 'translate3d(' + curTransLateX + 'px, 0, 0)',
				position: 'relative',
				top: 0,
				left: 0
			}
		};

		// 
		_this.timer = null;
		_this.clickSafe = {
			allowClicked: true,
			allowSlided: true
		};
		_this.touchObject = {};

		return _this;
	}

	/**
  * 只有上一次的点击事件执行完，才能点击下一个
  * 下面生命周期的操作
  */


	(0, _createClass3.default)(Swiper, [{
		key: 'componentDidMount',
		value: function componentDidMount() {
			// 根据this.props.autoPlay 来决定是否自动播放
			var autoPlay = this.props.autoPlay;

			!!autoPlay && this.autoPlaySlide();
		}

		/**
   * 上面是生命周期的操作
   * 自动播放
   */

	}, {
		key: 'autoPlaySlide',
		value: function autoPlaySlide() {
			var _this2 = this;

			var autoPlay = this.props.autoPlay;

			this.timer = setInterval(function () {
				return _this2.nextSlide();
			}, autoPlay);
		}

		/**
   * 点击事件
   * arg 变量就是 当前的curIndex 减去 下一个的将要被展示的 curIndex
   * 这里为什么是1 ， 因为他要向左移动一个单位，当前的curIndex 
   * 减去 下一个的将要被展示的 curIndex 所以是正1
   */

	}, {
		key: 'animateSlide',

		/**
   * 父容器滚动
   * arg 为 1，那么就向左走， 为 -1 就向右走。
   * nextIndex 是下一个将要被展示的slide
   * 这个 nextIndex 是个很有意思的东西，
   * 当 arg = -1 和 arg = 1的的时候，nextIndex 都是等于 targetIndex 的，
   * 如果 arg 不等于 1 或者 -1， 那么 就是下一个sldie的index了。 
   */
		value: function animateSlide(arg) {
			var _this3 = this;

			var _state = this.state,
			    curIndex = _state.curIndex,
			    curTransLateX = _state.curTransLateX,
			    data = _state.data;
			var _props = this.props,
			    children = _props.children,
			    width = _props.width;

			var len = children.length;

			// 这个 nextIndex 是处理 多个单位位移的 精髓所在
			var nextIndex = curIndex + arg - arg / Math.abs(arg);

			/**
    *  因为加入了 移动端 的touch事件， 所以， 这里的 targetTranslateX 要重新写
    */
			var targetTranslateX = nextIndex === -1 ? 0 : -curIndex * width;
			var doet = function doet() {
				var _state2 = _this3.state,
				    curTransLateX = _state2.curTransLateX,
				    contentStyle = _state2.contentStyle,
				    lefts = _state2.lefts;

				var nextTransLateX = 0;
				var step = (targetTranslateX - curTransLateX) / 8;

				step = arg > 0 ? Math.ceil(step) : Math.floor(step);
				nextTransLateX = curTransLateX + step;

				// 下面这个if还是要多加个判断，用来处理 dots 的点击情况。
				if (curTransLateX > targetTranslateX && arg < 0 || // 点击右边的按钮
				curTransLateX < targetTranslateX && arg > 0 // 点击左边的按钮
				) {
						/**
       * Math.abs(arg) > 1 则表示，是 多单位位移
       * Math.abs(curTransLateX) < lefts[nextIndex]
       * && lefts[nextIndex] < Math.abs(nextTransLateX)  表示，向左多个单位的临界 
       * Math.abs(curTransLateX) > lefts[nextIndex] 
       * && lefts[nextIndex] > Math.abs(nextTransLateX)  表示， 向右多个单位的临界
       */
						if (Math.abs(arg) > 1 && Math.abs(curTransLateX) < lefts[nextIndex] && lefts[nextIndex] < Math.abs(nextTransLateX) || Math.abs(curTransLateX) > lefts[nextIndex] && lefts[nextIndex] > Math.abs(nextTransLateX)) {
							// 临界进入这里
							_this3.getTargetLeft(nextIndex);
							nextIndex -= arg / Math.abs(arg);
						} else {
							// 处理左右点击按钮，只位移一个单位的 情况。
							contentStyle.transform = 'translate3d(' + nextTransLateX + 'px, 0, 0)';
							_this3.setState({
								curTransLateX: nextTransLateX,
								contentStyle: contentStyle
							});
						}

						window.requestAnimationFrame(doet);
					} else {
					/**
      * 这里要对 curIndex 做判断，当 curIndex === length  时，
      * 重新设置 curIndex , 并且执行 回调里的getTargetLeft()
      */
					var _width = _this3.state.width;

					_this3.clickSafe.allowClicked = true;

					if (curIndex === len && arg < 0) {
						curIndex = 0;
						_this3.criticalityTime(curIndex, len);
						return;
					} else if (curIndex === -1 && arg > 0) {
						curIndex = len - 1;
						_this3.criticalityTime(curIndex, len);
						return;
					}

					_this3.criticalityTime(curIndex, len);
				}
			};

			window.requestAnimationFrame(doet);
		}
		/**
   * 返回移动端的 touch事件
   */


		/**
   * 判断 touch 的方向，
   * 1 : right To left
   * -1: left To right	
   * 把这个 作为参数 传到 animateSlide,
   */

	}, {
		key: 'getTargetLeft',


		/**
   * 根据参数，或者当前的 curIndex 来重新设置
   */
		value: function getTargetLeft(nextIndex) {
			var _state3 = this.state,
			    curTransLateX = _state3.curTransLateX,
			    contentStyle = _state3.contentStyle,
			    data = _state3.data,
			    curIndex = _state3.curIndex;
			var _props2 = this.props,
			    children = _props2.children,
			    width = _props2.width;

			var len = children.length;

			curIndex = typeof nextIndex === 'undefined' ? curIndex : nextIndex;
			var lefts = children.map(function (ele, index) {
				if (curIndex !== -1) {
					if (index - curIndex >= -1) {
						return index * parseInt(width);
					} else {
						return (index + len) * parseInt(width);
					}
				} else {
					if (index - curIndex >= 1 && index - curIndex < len) {
						return (index - curIndex) * parseInt(width);
					} else {
						return 0;
					}
				}
			});

			curTransLateX = curIndex !== -1 ? -1 * curIndex * width : curIndex * width;
			contentStyle.transform = 'translate3d(' + curTransLateX + 'px, 0, 0)';

			this.setState({
				lefts: lefts,
				curTransLateX: curTransLateX,
				contentStyle: contentStyle,
				curIndex: curIndex
			});
		}

		/**
   * 点击不同索引的li，进行相应的位移。
   */


		/**
   * 点击按钮时，判断 是否存在定时器，以及 不允许 短时间内 多次点击
   */


		/**
   * 临界点，执行它, 根据 参数， 进而确认 是否改变
   * 他就是以前的 回调函数
   */

	}, {
		key: 'getDotsActiveStyle',
		value: function getDotsActiveStyle(i) {
			var curIndex = this.state.curIndex;


			if (i === curIndex) {
				return true;
			}
			return false;
		}
	}, {
		key: 'renderContents',
		value: function renderContents() {
			var width = this.props.width;
			var lefts = this.state.lefts;

			return this.props.children.map(function (Item, index) {
				return _react2.default.createElement(
					'div',
					{
						className: '__content-child',
						style: { left: lefts[index] + 'px', width: width },
						key: index
					},
					Item
				);
			});
		}
	}, {
		key: 'render',
		value: function render() {
			var contentStyle = this.state.contentStyle;
			var _props3 = this.props,
			    width = _props3.width,
			    height = _props3.height;

			return _react2.default.createElement(
				'div',
				{ className: 'rc-swiper', style: { width: width, height: height } },
				_react2.default.createElement(
					'div',
					(0, _extends3.default)({
						className: '__content',
						style: (0, _extends3.default)({}, contentStyle)
					}, this.getTouchedEvent()),
					this.renderContents()
				),
				this.renderDots(),
				_react2.default.createElement(
					'span',
					{ className: '__arrow __arrow-left', onClick: this.preSlide },
					'\u276E'
				),
				_react2.default.createElement(
					'span',
					{ className: '__arrow __arrow-right', onClick: this.nextSlide },
					'\u276F'
				)
			);
		}
	}]);
	return Swiper;
}(_react.Component), _initialiseProps = function _initialiseProps() {
	var _this4 = this;

	this.preSlide = function () {
		var curIndex = _this4.state.curIndex;
		var _props4 = _this4.props,
		    autoPlay = _props4.autoPlay,
		    children = _props4.children;

		var len = children.length;
		var arg = 1;

		// 判断 是否 设置 autoplay
		if (!_this4.hasInterval()) {
			return;
		}

		curIndex -= arg;

		// 当第一个的子元素的left为0 并且父容器的translateX ==0 时，
		// 我们
		if (curIndex === -1) {
			_this4.getTargetLeft(curIndex);
		}
		_this4.setState({
			curIndex: curIndex
		}, function () {
			_this4.animateSlide(arg);
		});
	};

	this.nextSlide = function () {
		var curIndex = _this4.state.curIndex;
		var _props5 = _this4.props,
		    autoPlay = _props5.autoPlay,
		    children = _props5.children;

		var len = children.length;
		var arg = -1;

		if (!_this4.hasInterval()) {
			return;
		}
		curIndex -= arg;
		// 这里的curIndex 就是下一个将要被展示出的slide的序号了，
		// 不过加了 nextIndex ，这个curIndex 叫做 targerIndex 更合适

		_this4.setState({
			curIndex: curIndex
		}, function () {
			_this4.animateSlide(arg);
		});
	};

	this.getTouchedEvent = function () {
		var mode = _this4.props.mode;

		if (mode === 'pc') return null;
		return {
			// 触碰开始， 停止 定时器
			onTouchStart: function onTouchStart(e) {
				if (!_this4.hasInterval()) {
					return;
				}
				// console.log('开始咯');
				_this4.touchObject = (0, _extends3.default)({}, _this4.touchObject, {
					startX: e.touches[0].pageX,
					startY: e.touches[0].pageY
				});
			},
			// 触碰移动, 
			onTouchMove: function onTouchMove(e) {
				var _state4 = _this4.state,
				    nextTransLateX = _state4.curTransLateX,
				    contentStyle = _state4.contentStyle,
				    curIndex = _state4.curIndex;

				var preLength = _this4.touchObject.preLength || 0;
				var direction = _this4.swipeDirection(_this4.touchObject.startX, e.touches[0].pageX, _this4.touchObject.startY, e.touches[0].pageY);
				if (direction !== 0) {
					// e.preventDefault();
				}
				var length = Math.round(Math.sqrt(Math.pow(e.touches[0].pageX - _this4.touchObject.startX, 2)));
				_this4.touchObject = {
					startX: _this4.touchObject.startX,
					startY: _this4.touchObject.startY,
					endX: e.touches[0].pageX,
					endY: e.touches[0].pageY,
					length: length,
					direction: direction,
					preLength: length

				};
				/**
     * length - preLength 
     * 就是 这次的 位移 
     * 而且 有个特殊的情况，就是当 curIndex === 0,并且我们向左转时，我们要重新设置一下定位。
     * 
     */
				if (curIndex === 0 && direction === -1 && length - preLength < 20) {
					_this4.setState({
						curIndex: -1
					}, function () {
						_this4.getTargetLeft(-1);
					});
				}

				nextTransLateX -= direction * (length - preLength);

				contentStyle.transform = 'translate3d(' + nextTransLateX + 'px, 0, 0)';
				_this4.setState({
					curTransLateX: nextTransLateX,
					contentStyle: (0, _extends3.default)({}, contentStyle)
				});

				// 在这里，对 length进行判断。
			},
			// 触碰结束， 将touchObject初始化为空对象 ，定时器存在的话， 就恢复定时器
			onTouchEnd: function onTouchEnd(e) {
				var _touchObject = _this4.touchObject,
				    length = _touchObject.length,
				    direction = _touchObject.direction;
				var curIndex = _this4.state.curIndex;
				var autoPlay = _this4.props.autoPlay;

				var arg = -1 * direction;
				/**
     * 根据 length 的大小， 来决定 是否运动。或者 复位
     */
				// console.log('结束了');
				if (length >= 20) {

					if (curIndex === -1) {
						_this4.animateSlide(arg);
					} else {
						curIndex -= arg;
						_this4.setState({
							curIndex: curIndex
						}, function () {
							_this4.animateSlide(arg);
						});
					}
				} else {
					/**
      * length < 20,不进行轮播。图片复位,同时，恢复定时器。
      */
					_this4.getTargetLeft();
					_this4.clickSafe.allowClicked = true;
					!!autoPlay && _this4.autoPlaySlide();
				}

				_this4.touchObject = {
					preLength: 0
				};
			},
			onTouchCancel: function onTouchCancel(e) {}
		};
	};

	this.swipeDirection = function (x1, x2, y1, y2) {
		var xDist = x1 - x2;
		var yDist = y1 - y2;
		var r = Math.atan2(yDist, xDist);
		var swipeAngle = Math.round(r * 180 / Math.PI);

		if (swipeAngle < 0) {
			swipeAngle = 360 - Math.abs(swipeAngle);
		}
		if (swipeAngle <= 45 && swipeAngle >= 0) {
			return 1;
		}
		if (swipeAngle <= 360 && swipeAngle >= 315) {
			return 1;
		}
		if (swipeAngle >= 135 && swipeAngle <= 225) {
			return -1;
		}
		if (_this4.props.vertical === true) {
			if (swipeAngle >= 35 && swipeAngle <= 135) {
				return 1;
			} else {
				return -1;
			}
		}
		return 0;
	};

	this.handleDotsClick = function (num) {
		var curIndex = _this4.state.curIndex;
		var autoPlay = _this4.props.autoPlay;

		var arg = curIndex - num;
		console.log(autoPlay);
		if (!_this4.hasInterval()) return;

		// 这里的curIndex 就是下一个将要被展示出的slide的序号了
		curIndex -= arg;

		_this4.setState({
			curIndex: num
		}, function () {
			_this4.animateSlide(arg);
		});
	};

	this.hasInterval = function () {
		if (!!_this4.timer) {
			clearInterval(_this4.timer);
		}
		/**
   * 主要目的还是 阻止多次点击
   */

		if (!_this4.clickSafe.allowClicked) {
			return false;
		} else {
			_this4.clickSafe.allowClicked = false;
			return true;
		}
	};

	this.criticalityTime = function (curIndex, len) {
		var autoPlay = _this4.props.autoPlay;

		if (curIndex === len) {
			curIndex = 0;
		} else if (curIndex === -1) {
			curIndex = len - 1;
		}
		!!autoPlay && _this4.autoPlaySlide();
		_this4.getTargetLeft(curIndex);
	};

	this.renderDots = function () {
		var _props6 = _this4.props,
		    dots = _props6.dots,
		    children = _props6.children;

		return dots && _react2.default.createElement(
			'ul',
			{ className: '__dots' },
			children.map(function (Item, i) {
				return _react2.default.createElement('li', {
					key: i,
					className: _this4.getDotsActiveStyle(i) ? '__dots-active' : '',
					onClick: function onClick() {
						return _this4.handleDotsClick(i);
					}
				});
			})
		);
	};
}, _temp);

Swiper.propTypes = {
	/**
  * mdoe 表明 使用 mobile端模式， 还是 pc端模式
  * 
  */
	mode: _propTypes2.default.oneOf(['mobile', 'pc']),
	/**
  * 轮播容器 的宽度
  */
	width: _propTypes2.default.number,
	height: _propTypes2.default.number,
	/**
  * 是否自动播放
  */
	autoPlay: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.bool]),
	/**
  * 是否显示小点点
  */
	dots: _propTypes2.default.bool
};
Swiper.defaultProps = {
	mode: 'pc',
	width: document.documentElement.clientWidth || document.body.clientWidth,
	height: 300,
	dots: true
};
exports.default = Swiper;