/**
 * DevExtreme (renovation/ui/scroll_view/animated_scrollbar.js)
 * Version: 21.2.0 (build 21200-0321)
 * Build date: Mon Jul 19 2021
 *
 * Copyright (c) 2012 - 2021 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
"use strict";
exports.AnimatedScrollbar = exports.AnimatedScrollbarProps = exports.viewFunction = exports.BOUNCE_ACCELERATION_SUM = exports.BOUNCE_MIN_VELOCITY_LIMIT = exports.MIN_VELOCITY_LIMIT = exports.ACCELERATION = exports.OUT_BOUNDS_ACCELERATION = void 0;
var _inferno = require("inferno");
var _vdom = require("@devextreme/vdom");
var _type = require("../../../core/utils/type");
var _scrollbar = require("./scrollbar");
var _frame = require("../../../animation/frame");
var _scrollbar_props = require("./scrollbar_props");
var _scrollable_simulated_props = require("./scrollable_simulated_props");
var _scrollable_props = require("./scrollable_props");
var _math = require("../../../core/utils/math");
var _excluded = ["activeStateEnabled", "bottomPocketSize", "bounceEnabled", "containerSize", "contentPaddingBottom", "contentSize", "contentTranslateOffsetChange", "direction", "forceGeneratePockets", "forceVisibility", "hoverStateEnabled", "inertiaEnabled", "isScrollableHovered", "onAnimatorCancel", "onAnimatorStart", "onBounce", "onEnd", "onLock", "onPullDown", "onReachBottom", "onRelease", "onScroll", "onUnlock", "pocketState", "pocketStateChange", "pullDownEnabled", "reachBottomEnabled", "rtlEnabled", "scrollByThumb", "scrollLocation", "scrollLocationChange", "scrollableOffset", "showScrollbar", "topPocketSize"];

function _objectWithoutProperties(source, excluded) {
    if (null == source) {
        return {}
    }
    var target = _objectWithoutPropertiesLoose(source, excluded);
    var key, i;
    if (Object.getOwnPropertySymbols) {
        var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
        for (i = 0; i < sourceSymbolKeys.length; i++) {
            key = sourceSymbolKeys[i];
            if (excluded.indexOf(key) >= 0) {
                continue
            }
            if (!Object.prototype.propertyIsEnumerable.call(source, key)) {
                continue
            }
            target[key] = source[key]
        }
    }
    return target
}

function _objectWithoutPropertiesLoose(source, excluded) {
    if (null == source) {
        return {}
    }
    var target = {};
    var sourceKeys = Object.keys(source);
    var key, i;
    for (i = 0; i < sourceKeys.length; i++) {
        key = sourceKeys[i];
        if (excluded.indexOf(key) >= 0) {
            continue
        }
        target[key] = source[key]
    }
    return target
}

function _defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) {
            descriptor.writable = true
        }
        Object.defineProperty(target, descriptor.key, descriptor)
    }
}

function _createClass(Constructor, protoProps, staticProps) {
    if (protoProps) {
        _defineProperties(Constructor.prototype, protoProps)
    }
    if (staticProps) {
        _defineProperties(Constructor, staticProps)
    }
    return Constructor
}

function _assertThisInitialized(self) {
    if (void 0 === self) {
        throw new ReferenceError("this hasn't been initialised - super() hasn't been called")
    }
    return self
}

function _inheritsLoose(subClass, superClass) {
    subClass.prototype = Object.create(superClass.prototype);
    subClass.prototype.constructor = subClass;
    _setPrototypeOf(subClass, superClass)
}

function _setPrototypeOf(o, p) {
    _setPrototypeOf = Object.setPrototypeOf || function(o, p) {
        o.__proto__ = p;
        return o
    };
    return _setPrototypeOf(o, p)
}

function _extends() {
    _extends = Object.assign || function(target) {
        for (var i = 1; i < arguments.length; i++) {
            var source = arguments[i];
            for (var key in source) {
                if (Object.prototype.hasOwnProperty.call(source, key)) {
                    target[key] = source[key]
                }
            }
        }
        return target
    };
    return _extends.apply(this, arguments)
}
var OUT_BOUNDS_ACCELERATION = .5;
exports.OUT_BOUNDS_ACCELERATION = OUT_BOUNDS_ACCELERATION;
var ACCELERATION = .92;
exports.ACCELERATION = ACCELERATION;
var MIN_VELOCITY_LIMIT = 1;
exports.MIN_VELOCITY_LIMIT = MIN_VELOCITY_LIMIT;
var BOUNCE_MIN_VELOCITY_LIMIT = MIN_VELOCITY_LIMIT / 5;
exports.BOUNCE_MIN_VELOCITY_LIMIT = BOUNCE_MIN_VELOCITY_LIMIT;
var FRAME_DURATION = 17;
var BOUNCE_DURATION = 400;
var BOUNCE_FRAMES = BOUNCE_DURATION / FRAME_DURATION;
var BOUNCE_ACCELERATION_SUM = (1 - Math.pow(ACCELERATION, BOUNCE_FRAMES)) / (1 - ACCELERATION);
exports.BOUNCE_ACCELERATION_SUM = BOUNCE_ACCELERATION_SUM;
var viewFunction = function(viewModel) {
    var cancel = viewModel.cancel,
        _viewModel$props = viewModel.props,
        bottomPocketSize = _viewModel$props.bottomPocketSize,
        bounceEnabled = _viewModel$props.bounceEnabled,
        containerSize = _viewModel$props.containerSize,
        contentPaddingBottom = _viewModel$props.contentPaddingBottom,
        contentSize = _viewModel$props.contentSize,
        contentTranslateOffsetChange = _viewModel$props.contentTranslateOffsetChange,
        direction = _viewModel$props.direction,
        forceGeneratePockets = _viewModel$props.forceGeneratePockets,
        isScrollableHovered = _viewModel$props.isScrollableHovered,
        onEnd = _viewModel$props.onEnd,
        onLock = _viewModel$props.onLock,
        onPullDown = _viewModel$props.onPullDown,
        onReachBottom = _viewModel$props.onReachBottom,
        onRelease = _viewModel$props.onRelease,
        onScroll = _viewModel$props.onScroll,
        onUnlock = _viewModel$props.onUnlock,
        pocketState = _viewModel$props.pocketState,
        pocketStateChange = _viewModel$props.pocketStateChange,
        pullDownEnabled = _viewModel$props.pullDownEnabled,
        reachBottomEnabled = _viewModel$props.reachBottomEnabled,
        rtlEnabled = _viewModel$props.rtlEnabled,
        scrollByThumb = _viewModel$props.scrollByThumb,
        scrollLocation = _viewModel$props.scrollLocation,
        scrollLocationChange = _viewModel$props.scrollLocationChange,
        scrollableOffset = _viewModel$props.scrollableOffset,
        showScrollbar = _viewModel$props.showScrollbar,
        topPocketSize = _viewModel$props.topPocketSize,
        scrollbarRef = viewModel.scrollbarRef,
        start = viewModel.start;
    return (0, _inferno.createComponentVNode)(2, _scrollbar.Scrollbar, {
        direction: direction,
        onAnimatorStart: start,
        onAnimatorCancel: cancel,
        scrollableOffset: scrollableOffset,
        contentSize: contentSize,
        containerSize: containerSize,
        isScrollableHovered: isScrollableHovered,
        scrollLocation: scrollLocation,
        scrollLocationChange: scrollLocationChange,
        contentTranslateOffsetChange: contentTranslateOffsetChange,
        scrollByThumb: scrollByThumb,
        bounceEnabled: bounceEnabled,
        showScrollbar: showScrollbar,
        onScroll: onScroll,
        onEnd: onEnd,
        rtlEnabled: rtlEnabled,
        forceGeneratePockets: forceGeneratePockets,
        topPocketSize: topPocketSize,
        bottomPocketSize: bottomPocketSize,
        contentPaddingBottom: contentPaddingBottom,
        onPullDown: onPullDown,
        onRelease: onRelease,
        onReachBottom: onReachBottom,
        pullDownEnabled: pullDownEnabled,
        reachBottomEnabled: reachBottomEnabled,
        pocketState: pocketState,
        pocketStateChange: pocketStateChange,
        onLock: onLock,
        onUnlock: onUnlock
    }, null, scrollbarRef)
};
exports.viewFunction = viewFunction;
var AnimatedScrollbarProps = _extends({}, _scrollbar_props.ScrollbarProps);
exports.AnimatedScrollbarProps = AnimatedScrollbarProps;
var AnimatedScrollbarPropsType = {
    activeStateEnabled: AnimatedScrollbarProps.activeStateEnabled,
    containerSize: AnimatedScrollbarProps.containerSize,
    contentSize: AnimatedScrollbarProps.contentSize,
    topPocketSize: AnimatedScrollbarProps.topPocketSize,
    bottomPocketSize: AnimatedScrollbarProps.bottomPocketSize,
    contentPaddingBottom: AnimatedScrollbarProps.contentPaddingBottom,
    scrollableOffset: AnimatedScrollbarProps.scrollableOffset,
    isScrollableHovered: AnimatedScrollbarProps.isScrollableHovered,
    forceVisibility: AnimatedScrollbarProps.forceVisibility,
    scrollLocation: AnimatedScrollbarProps.scrollLocation,
    pocketState: AnimatedScrollbarProps.pocketState,
    direction: _scrollable_props.ScrollableProps.direction,
    showScrollbar: _scrollable_props.ScrollableProps.showScrollbar,
    scrollByThumb: _scrollable_props.ScrollableProps.scrollByThumb,
    pullDownEnabled: _scrollable_props.ScrollableProps.pullDownEnabled,
    reachBottomEnabled: _scrollable_props.ScrollableProps.reachBottomEnabled,
    forceGeneratePockets: _scrollable_props.ScrollableProps.forceGeneratePockets,
    inertiaEnabled: _scrollable_simulated_props.ScrollableSimulatedProps.inertiaEnabled,
    bounceEnabled: _scrollable_simulated_props.ScrollableSimulatedProps.bounceEnabled
};
var AnimatedScrollbar = function(_InfernoComponent) {
    _inheritsLoose(AnimatedScrollbar, _InfernoComponent);

    function AnimatedScrollbar(props) {
        var _this;
        _this = _InfernoComponent.call(this, props) || this;
        _this.state = {};
        _this.scrollbarRef = (0, _inferno.createRef)();
        _this.stepAnimationFrame = 0;
        _this.finished = true;
        _this.stopped = false;
        _this.velocity = 0;
        _this.animator = "inertia";
        _this.getLocationWithinRange = _this.getLocationWithinRange.bind(_assertThisInitialized(_this));
        _this.getMinOffset = _this.getMinOffset.bind(_assertThisInitialized(_this));
        _this.validateEvent = _this.validateEvent.bind(_assertThisInitialized(_this));
        _this.isThumb = _this.isThumb.bind(_assertThisInitialized(_this));
        _this.reachedMin = _this.reachedMin.bind(_assertThisInitialized(_this));
        _this.reachedMax = _this.reachedMax.bind(_assertThisInitialized(_this));
        _this.initHandler = _this.initHandler.bind(_assertThisInitialized(_this));
        _this.startHandler = _this.startHandler.bind(_assertThisInitialized(_this));
        _this.moveHandler = _this.moveHandler.bind(_assertThisInitialized(_this));
        _this.endHandler = _this.endHandler.bind(_assertThisInitialized(_this));
        _this.stopHandler = _this.stopHandler.bind(_assertThisInitialized(_this));
        _this.scrollByHandler = _this.scrollByHandler.bind(_assertThisInitialized(_this));
        _this.releaseHandler = _this.releaseHandler.bind(_assertThisInitialized(_this));
        _this.disposeAnimationFrame = _this.disposeAnimationFrame.bind(_assertThisInitialized(_this));
        _this.start = _this.start.bind(_assertThisInitialized(_this));
        _this.cancel = _this.cancel.bind(_assertThisInitialized(_this));
        _this.stepCore = _this.stepCore.bind(_assertThisInitialized(_this));
        _this.getStepAnimationFrame = _this.getStepAnimationFrame.bind(_assertThisInitialized(_this));
        _this.step = _this.step.bind(_assertThisInitialized(_this));
        _this.setupBounce = _this.setupBounce.bind(_assertThisInitialized(_this));
        _this.complete = _this.complete.bind(_assertThisInitialized(_this));
        _this.suppressInertia = _this.suppressInertia.bind(_assertThisInitialized(_this));
        _this.crossBoundOnNextStep = _this.crossBoundOnNextStep.bind(_assertThisInitialized(_this));
        _this.getMaxOffset = _this.getMaxOffset.bind(_assertThisInitialized(_this));
        _this.scrollStep = _this.scrollStep.bind(_assertThisInitialized(_this));
        _this.moveTo = _this.moveTo.bind(_assertThisInitialized(_this));
        _this.stopAnimator = _this.stopAnimator.bind(_assertThisInitialized(_this));
        return _this
    }
    var _proto = AnimatedScrollbar.prototype;
    _proto.createEffects = function() {
        return [new _vdom.InfernoEffect(this.disposeAnimationFrame, [])]
    };
    _proto.disposeAnimationFrame = function() {
        var _this2 = this;
        return function() {
            _this2.cancel()
        }
    };
    _proto.start = function(animatorName, receivedVelocity, thumbScrolling, crossThumbScrolling) {
        this.animator = animatorName;
        if (this.isBounceAnimator) {
            var _this$props$onBounce, _this$props;
            null === (_this$props$onBounce = (_this$props = this.props).onBounce) || void 0 === _this$props$onBounce ? void 0 : _this$props$onBounce.call(_this$props);
            this.setupBounce()
        } else {
            if (!thumbScrolling && crossThumbScrolling) {
                this.velocity = 0
            } else {
                this.velocity = null !== receivedVelocity && void 0 !== receivedVelocity ? receivedVelocity : 0
            }
            this.suppressInertia(thumbScrolling)
        }
        this.stopped = false;
        this.finished = false;
        this.stepCore()
    };
    _proto.cancel = function() {
        this.stopped = true;
        (0, _frame.cancelAnimationFrame)(this.stepAnimationFrame)
    };
    _proto.stepCore = function() {
        if (this.stopped) {
            return
        }
        if (this.isFinished) {
            this.finished = true;
            this.complete();
            return
        }
        this.step();
        this.stepAnimationFrame = this.getStepAnimationFrame()
    };
    _proto.getStepAnimationFrame = function() {
        return (0, _frame.requestAnimationFrame)(this.stepCore.bind(this))
    };
    _proto.step = function() {
        if (!this.props.bounceEnabled && (this.reachedMin() || this.reachedMax())) {
            this.velocity = 0
        }
        this.scrollStep(this.velocity);
        this.velocity *= this.acceleration
    };
    _proto.setupBounce = function() {
        var scrollLocation = this.props.scrollLocation;
        var bounceDistance = this.getLocationWithinRange(scrollLocation) - scrollLocation;
        this.velocity = bounceDistance / BOUNCE_ACCELERATION_SUM
    };
    _proto.complete = function() {
        if (this.isBounceAnimator) {
            var boundaryLocation = this.getLocationWithinRange(this.props.scrollLocation);
            this.moveTo(boundaryLocation);
            this.stopAnimator("bounce")
        } else {
            this.stopAnimator("inertia")
        }
    };
    _proto.suppressInertia = function(thumbScrolling) {
        if (!this.props.inertiaEnabled || thumbScrolling) {
            this.velocity = 0
        }
    };
    _proto.crossBoundOnNextStep = function() {
        var location = this.props.scrollLocation;
        var nextLocation = location + this.velocity;
        var minOffset = this.getMinOffset();
        var maxOffset = this.getMaxOffset();
        return location < minOffset && nextLocation >= minOffset || location > maxOffset && nextLocation <= maxOffset
    };
    _proto.getMaxOffset = function() {
        return this.scrollbar.getMaxOffset()
    };
    _proto.scrollStep = function(delta) {
        this.scrollbar.scrollStep(delta)
    };
    _proto.moveTo = function(location) {
        this.scrollbar.moveTo(location)
    };
    _proto.stopAnimator = function(animator) {
        this.scrollbar.stopAnimator(animator)
    };
    _proto.getLocationWithinRange = function(value) {
        return this.scrollbar.getLocationWithinRange(value)
    };
    _proto.getMinOffset = function() {
        return this.scrollbar.getMinOffset()
    };
    _proto.validateEvent = function(event) {
        return this.scrollbar.validateEvent(event)
    };
    _proto.isThumb = function(element) {
        return this.scrollbar.isThumb(element)
    };
    _proto.reachedMin = function() {
        return this.props.scrollLocation <= this.getMinOffset()
    };
    _proto.reachedMax = function() {
        return this.props.scrollLocation >= this.getMaxOffset()
    };
    _proto.initHandler = function(event, crossThumbScrolling) {
        this.scrollbar.initHandler(event, crossThumbScrolling)
    };
    _proto.startHandler = function() {
        this.scrollbar.startHandler()
    };
    _proto.moveHandler = function(delta) {
        this.scrollbar.moveHandler(delta)
    };
    _proto.endHandler = function(velocity, needRiseEnd) {
        this.scrollbar.endHandler(velocity, needRiseEnd)
    };
    _proto.stopHandler = function() {
        this.scrollbar.stopHandler()
    };
    _proto.scrollByHandler = function(delta) {
        this.scrollbar.scrollByHandler(delta)
    };
    _proto.releaseHandler = function() {
        this.scrollbar.releaseHandler()
    };
    _proto.render = function() {
        var props = this.props;
        return viewFunction({
            props: _extends({}, props),
            scrollbarRef: this.scrollbarRef,
            start: this.start,
            cancel: this.cancel,
            stepCore: this.stepCore,
            getStepAnimationFrame: this.getStepAnimationFrame,
            step: this.step,
            setupBounce: this.setupBounce,
            complete: this.complete,
            isBounceAnimator: this.isBounceAnimator,
            isFinished: this.isFinished,
            inProgress: this.inProgress,
            acceleration: this.acceleration,
            suppressInertia: this.suppressInertia,
            crossBoundOnNextStep: this.crossBoundOnNextStep,
            getMaxOffset: this.getMaxOffset,
            scrollStep: this.scrollStep,
            moveTo: this.moveTo,
            stopAnimator: this.stopAnimator,
            scrollbar: this.scrollbar,
            restAttributes: this.restAttributes
        })
    };
    _createClass(AnimatedScrollbar, [{
        key: "isBounceAnimator",
        get: function() {
            return "bounce" === this.animator
        }
    }, {
        key: "isFinished",
        get: function() {
            if (this.isBounceAnimator) {
                return this.crossBoundOnNextStep() || Math.abs(this.velocity) <= BOUNCE_MIN_VELOCITY_LIMIT
            }
            return Math.abs(this.velocity) <= MIN_VELOCITY_LIMIT
        }
    }, {
        key: "inProgress",
        get: function() {
            return !(this.stopped || this.finished)
        }
    }, {
        key: "acceleration",
        get: function() {
            var _this$scrollbarRef;
            if (!(0, _type.isDefined)(null === (_this$scrollbarRef = this.scrollbarRef) || void 0 === _this$scrollbarRef ? void 0 : _this$scrollbarRef.current)) {
                return 0
            }
            return this.isBounceAnimator || (0, _math.inRange)(this.props.scrollLocation, this.getMinOffset(), this.getMaxOffset()) ? ACCELERATION : OUT_BOUNDS_ACCELERATION
        }
    }, {
        key: "scrollbar",
        get: function() {
            return this.scrollbarRef.current
        }
    }, {
        key: "restAttributes",
        get: function() {
            var _this$props2 = this.props,
                restProps = (_this$props2.activeStateEnabled, _this$props2.bottomPocketSize, _this$props2.bounceEnabled, _this$props2.containerSize, _this$props2.contentPaddingBottom, _this$props2.contentSize, _this$props2.contentTranslateOffsetChange, _this$props2.direction, _this$props2.forceGeneratePockets, _this$props2.forceVisibility, _this$props2.hoverStateEnabled, _this$props2.inertiaEnabled, _this$props2.isScrollableHovered, _this$props2.onAnimatorCancel, _this$props2.onAnimatorStart, _this$props2.onBounce, _this$props2.onEnd, _this$props2.onLock, _this$props2.onPullDown, _this$props2.onReachBottom, _this$props2.onRelease, _this$props2.onScroll, _this$props2.onUnlock, _this$props2.pocketState, _this$props2.pocketStateChange, _this$props2.pullDownEnabled, _this$props2.reachBottomEnabled, _this$props2.rtlEnabled, _this$props2.scrollByThumb, _this$props2.scrollLocation, _this$props2.scrollLocationChange, _this$props2.scrollableOffset, _this$props2.showScrollbar, _this$props2.topPocketSize, _objectWithoutProperties(_this$props2, _excluded));
            return restProps
        }
    }]);
    return AnimatedScrollbar
}(_vdom.InfernoComponent);
exports.AnimatedScrollbar = AnimatedScrollbar;
AnimatedScrollbar.defaultProps = _extends({}, AnimatedScrollbarPropsType);
