text: import updateGeometry from '../update-geometry';
  import updateScroll from '../update-scroll';
  import { env } from '../lib/util';
  
  export default function(i) {
    if (!env.supportsTouch && !env.supportsIePointer) {
      return;
    }
  
    const element = i.element;
  
    function shouldStopOrPrevent(deltaX, deltaY) {
      const scrollTop = element.scrollTop;
      const scrollLeft = element.scrollLeft;
      const magnitudeX = Math.abs(deltaX);
      const magnitudeY = Math.abs(deltaY);
  
      if (magnitudeY > magnitudeX) {
        // user is perhaps trying to swipe up/down the page
  
        if (
          (deltaY < 0 && scrollTop === i.contentHeight - i.containerHeight) ||
          (deltaY > 0 && scrollTop === 0)
        ) {
          // set prevent for mobile Chrome refresh
          return {
            stop: !i.settings.swipePropagation,
            prevent: window.scrollY === 0,
          };
        }
      } else if (magnitudeX > magnitudeY) {
        // user is perhaps trying to swipe left/right across the page
  
        if (
          (deltaX < 0 && scrollLeft === i.contentWidth - i.containerWidth) ||
          (deltaX > 0 && scrollLeft === 0)
        ) {
          return { stop: !i.settings.swipePropagation, prevent: true };
        }
      }
  
      return { stop: true, prevent: true };
    }
  
    function applyTouchMove(differenceX, differenceY) {
      updateScroll(i, 'top', element.scrollTop - differenceY);
      updateScroll(i, 'left', element.scrollLeft - differenceX);
  
      updateGeometry(i);
    }
  
    let startOffset = {};
    let startTime = 0;
    let speed = {};
    let easingLoop = null;
    let inGlobalTouch = false;
    let inLocalTouch = false;
  
    function globalTouchStart() {
      inGlobalTouch = true;
    }
    function globalTouchEnd() {
      inGlobalTouch = false;
    }
  
    function getTouch(e) {
      if (e.targetTouches) {
        return e.targetTouches[0];
      } else {
        // Maybe IE pointer
        return e;
      }
    }
  
    function shouldHandle(e) {
      if (e.pointerType && e.pointerType === 'pen' && e.buttons === 0) {
        return false;
      }
      if (e.targetTouches && e.targetTouches.length === 1) {
        return true;
      }
      if (
        e.pointerType &&
        e.pointerType !== 'mouse' &&
        e.pointerType !== e.MSPOINTER_TYPE_MOUSE
      ) {
        return true;
      }
      return false;
    }
  
    function touchStart(e) {
      if (!shouldHandle(e)) {
        return;
      }
  
      inLocalTouch = true;
  
      const touch = getTouch(e);
  
      startOffset.pageX = touch.pageX;
      startOffset.pageY = touch.pageY;
  
      startTime = new Date().getTime();
  
      if (easingLoop !== null) {
        clearInterval(easingLoop);
      }
  
      e.stopPropagation();
    }
  
    function touchMove(e) {
      if (!inLocalTouch && i.settings.swipePropagation) {
        touchStart(e);
      }
      if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {
        const touch = getTouch(e);
  
        const currentOffset = { pageX: touch.pageX, pageY: touch.pageY };
  
        const differenceX = currentOffset.pageX - startOffset.pageX;
        const differenceY = currentOffset.pageY - startOffset.pageY;
  
        applyTouchMove(differenceX, differenceY);
        startOffset = currentOffset;
  
        const currentTime = new Date().getTime();
  
        const timeGap = currentTime - startTime;
        if (timeGap > 0) {
          speed.x = differenceX / timeGap;
          speed.y = differenceY / timeGap;
          startTime = currentTime;
        }
  
        const { stop, prevent } = shouldStopOrPrevent(differenceX, differenceY);
        if (stop) e.stopPropagation();
        if (prevent) e.preventDefault();
      }
    }
    function touchEnd() {
      if (!inGlobalTouch && inLocalTouch) {
        inLocalTouch = false;
  
        if (i.settings.swipeEasing) {
          clearInterval(easingLoop);
          easingLoop = setInterval(function() {
            if (i.isInitialized) {
              clearInterval(easingLoop);
              return;
            }
  
            if (!speed.x && !speed.y) {
              clearInterval(easingLoop);
              return;
            }
  
            if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
              clearInterval(easingLoop);
              return;
            }
  
            applyTouchMove(speed.x * 30, speed.y * 30);
  
            speed.x *= 0.8;
            speed.y *= 0.8;
          }, 10);
        }
      }
    }
  
    if (env.supportsTouch) {
      i.event.bind(window, 'touchstart', globalTouchStart);
      i.event.bind(window, 'touchend', globalTouchEnd);
      i.event.bind(element, 'touchstart', touchStart);
      i.event.bind(element, 'touchmove', touchMove);
      i.event.bind(element, 'touchend', touchEnd);
    } else if (env.supportsIePointer) {
      if (window.PointerEvent) {
        i.event.bind(window, 'pointerdown', globalTouchStart);
        i.event.bind(window, 'pointerup', globalTouchEnd);
        i.event.bind(element, 'pointerdown', touchStart);
        i.event.bind(element, 'pointermove', touchMove);
        i.event.bind(element, 'pointerup', touchEnd);
      } else if (window.MSPointerEvent) {
        i.event.bind(window, 'MSPointerDown', globalTouchStart);
        i.event.bind(window, 'MSPointerUp', globalTouchEnd);
        i.event.bind(element, 'MSPointerDown', touchStart);
        i.event.bind(element, 'MSPointerMove', touchMove);
        i.event.bind(element, 'MSPointerUp', touchEnd);
      }
    }
  }
  