/**
 * Copyright (c) Nicolas Gallagher.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * 
 */
import * as React from 'react';
import { forwardRef, useRef } from 'react';
import StyleSheet from '../StyleSheet';
import View from '../View';

function normalizeScrollEvent(e) {
  return {
    nativeEvent: {
      contentOffset: {
        get x() {
          return e.target.scrollLeft;
        },

        get y() {
          return e.target.scrollTop;
        }

      },
      contentSize: {
        get height() {
          return e.target.scrollHeight;
        },

        get width() {
          return e.target.scrollWidth;
        }

      },
      layoutMeasurement: {
        get height() {
          return e.target.offsetHeight;
        },

        get width() {
          return e.target.offsetWidth;
        }

      }
    },
    timeStamp: Date.now()
  };
}

function shouldEmitScrollEvent(lastTick, eventThrottle) {
  var timeSinceLastTick = Date.now() - lastTick;
  return eventThrottle > 0 && timeSinceLastTick >= eventThrottle;
}
/**
 * Encapsulates the Web-specific scroll throttling and disabling logic
 */


var ScrollViewBase = forwardRef(function (props, forwardedRef) {
  var accessibilityLabel = props.accessibilityLabel,
      accessibilityRole = props.accessibilityRole,
      accessibilityState = props.accessibilityState,
      children = props.children,
      importantForAccessibility = props.importantForAccessibility,
      nativeID = props.nativeID,
      onLayout = props.onLayout,
      onScroll = props.onScroll,
      onTouchMove = props.onTouchMove,
      onWheel = props.onWheel,
      pointerEvents = props.pointerEvents,
      _props$scrollEnabled = props.scrollEnabled,
      scrollEnabled = _props$scrollEnabled === void 0 ? true : _props$scrollEnabled,
      _props$scrollEventThr = props.scrollEventThrottle,
      scrollEventThrottle = _props$scrollEventThr === void 0 ? 0 : _props$scrollEventThr,
      showsHorizontalScrollIndicator = props.showsHorizontalScrollIndicator,
      showsVerticalScrollIndicator = props.showsVerticalScrollIndicator,
      style = props.style,
      dataSet = props.dataSet,
      testID = props.testID;
  var scrollState = useRef({
    isScrolling: false,
    scrollLastTick: 0
  });
  var scrollTimeout = useRef(null);

  function createPreventableScrollHandler(handler) {
    return function (e) {
      if (scrollEnabled) {
        if (handler) {
          handler(e);
        }
      }
    };
  }

  function handleScroll(e) {
    e.persist();
    e.stopPropagation(); // A scroll happened, so the scroll resets the scrollend timeout.

    if (scrollTimeout.current != null) {
      clearTimeout(scrollTimeout.current);
    }

    scrollTimeout.current = setTimeout(function () {
      handleScrollEnd(e);
    }, 100);

    if (scrollState.current.isScrolling) {
      // Scroll last tick may have changed, check if we need to notify
      if (shouldEmitScrollEvent(scrollState.current.scrollLastTick, scrollEventThrottle)) {
        handleScrollTick(e);
      }
    } else {
      // Weren't scrolling, so we must have just started
      handleScrollStart(e);
    }
  }

  function handleScrollStart(e) {
    scrollState.current.isScrolling = true;
    scrollState.current.scrollLastTick = Date.now();
  }

  function handleScrollTick(e) {
    scrollState.current.scrollLastTick = Date.now();

    if (onScroll) {
      onScroll(normalizeScrollEvent(e));
    }
  }

  function handleScrollEnd(e) {
    scrollState.current.isScrolling = false;

    if (onScroll) {
      onScroll(normalizeScrollEvent(e));
    }
  }

  var hideScrollbar = showsHorizontalScrollIndicator === false || showsVerticalScrollIndicator === false;
  return React.createElement(View, {
    accessibilityLabel: accessibilityLabel,
    accessibilityRole: accessibilityRole,
    accessibilityState: accessibilityState,
    children: children,
    dataSet: dataSet,
    importantForAccessibility: importantForAccessibility,
    nativeID: nativeID,
    onLayout: onLayout,
    onScroll: handleScroll,
    onTouchMove: createPreventableScrollHandler(onTouchMove),
    onWheel: createPreventableScrollHandler(onWheel),
    pointerEvents: pointerEvents,
    ref: forwardedRef,
    style: [style, !scrollEnabled && styles.scrollDisabled, hideScrollbar && styles.hideScrollbar],
    testID: testID
  });
}); // Chrome doesn't support e.preventDefault in this case; touch-action must be
// used to disable scrolling.
// https://developers.google.com/web/updates/2017/01/scrolling-intervention

var styles = StyleSheet.create({
  scrollDisabled: {
    overflowX: 'hidden',
    overflowY: 'hidden',
    touchAction: 'none'
  },
  hideScrollbar: {
    scrollbarWidth: 'none'
  }
});
export default ScrollViewBase;