/*
 * Copyright (C) 2011, 2014-2015 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "FloatPoint.h"
#include "FloatSize.h"

#include "RectEdges.h"
#include "ScrollAnimation.h"
#include "ScrollSnapAnimatorState.h"
#include "ScrollSnapOffsetsInfo.h"
#include "ScrollTypes.h"
#include "WheelEventTestMonitor.h"
#include <wtf/Deque.h>
#include <wtf/Noncopyable.h>
#include <wtf/RunLoop.h>

namespace WebCore {

class KeyboardScrollingAnimator;
class LayoutSize;
class PlatformWheelEvent;
class ScrollSnapAnimatorState;
class ScrollingEffectsController;
class ScrollableArea;
class WheelEventTestMonitor;
struct ScrollExtents;

class ScrollingEffectsControllerTimer : public RunLoop::TimerBase {
public:
    ScrollingEffectsControllerTimer(RunLoop& runLoop, Function<void()>&& callback)
        : RunLoop::TimerBase(runLoop)
        , m_callback(WTFMove(callback))
    {
    }

    void fired() final
    {
        m_callback();
    }

private:
    Function<void()> m_callback;
};

class ScrollingEffectsControllerClient {
protected:
    virtual ~ScrollingEffectsControllerClient() = default;

public:
    // Only used for non-animation timers.
    virtual std::unique_ptr<ScrollingEffectsControllerTimer> createTimer(Function<void()>&&) = 0;

    virtual void startAnimationCallback(ScrollingEffectsController&) = 0;
    virtual void stopAnimationCallback(ScrollingEffectsController&) = 0;

    virtual void updateKeyboardScrollPosition(MonotonicTime) { }
    virtual KeyboardScrollingAnimator *keyboardScrollingAnimator() const { return nullptr; }

    virtual bool allowsHorizontalScrolling() const = 0;
    virtual bool allowsVerticalScrolling() const = 0;

    virtual void immediateScrollBy(const FloatSize&, ScrollClamping = ScrollClamping::Clamped) = 0;

    // If the current scroll position is within the overhang area, this function will cause
    // the page to scroll to the nearest boundary point.
    virtual void adjustScrollPositionToBoundsIfNecessary() = 0;

#if HAVE(RUBBER_BANDING)
    virtual bool allowsHorizontalStretching(const PlatformWheelEvent&) const = 0;
    virtual bool allowsVerticalStretching(const PlatformWheelEvent&) const = 0;
    virtual IntSize stretchAmount() const = 0;

    // "Pinned" means scrolled at or beyond the edge.
    virtual bool isPinnedOnSide(BoxSide) const = 0;
    virtual RectEdges<bool> edgePinnedState() const = 0;

    virtual bool shouldRubberBandOnSide(BoxSide) const = 0;

    virtual void willStartRubberBandAnimation() { }
    virtual void didStopRubberBandAnimation() { }

    virtual void rubberBandingStateChanged(bool) { }
#endif

    virtual void deferWheelEventTestCompletionForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) const { /* Do nothing */ }
    virtual void removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) const { /* Do nothing */ }

    virtual FloatPoint scrollOffset() const = 0;

    virtual void willStartAnimatedScroll() { }
    virtual void didStopAnimatedScroll() { }

    virtual void willStartScrollSnapAnimation() { }
    virtual void didStopScrollSnapAnimation() { }

    virtual float pageScaleFactor() const = 0;
    virtual ScrollExtents scrollExtents() const = 0;
    virtual bool scrollAnimationEnabled() const { return true; }
};

class ScrollingEffectsController : public ScrollAnimationClient {
    WTF_MAKE_NONCOPYABLE(ScrollingEffectsController);

public:
    explicit ScrollingEffectsController(ScrollingEffectsControllerClient&);
    virtual ~ScrollingEffectsController();

    bool usesScrollSnap() const;
    void stopAllTimers();
    void scrollPositionChanged();

    bool startAnimatedScrollToDestination(FloatPoint startOffset, FloatPoint destinationOffset);
    bool retargetAnimatedScroll(FloatPoint newDestinationOffset);
    bool retargetAnimatedScrollBy(FloatSize);

    void stopAnimatedScroll();
    void stopAnimatedNonRubberbandingScroll();

    void stopKeyboardScrolling();

    bool startMomentumScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatSize& initialVelocity, const FloatSize& initialDelta, const Function<FloatPoint(const FloatPoint&)>& destinationModifier);

    void willBeginKeyboardScrolling();
    void didStopKeyboardScrolling();
    
    // Should be called periodically by the client. Started by startAnimationCallback(), stopped by stopAnimationCallback().
    void animationCallback(MonotonicTime);

    void updateGestureInProgressState(const PlatformWheelEvent&);
    
    void contentsSizeChanged();

    void setSnapOffsetsInfo(const LayoutScrollSnapOffsetsInfo&);
    const LayoutScrollSnapOffsetsInfo* snapOffsetsInfo() const;
    void setActiveScrollSnapIndexForAxis(ScrollEventAxis, std::optional<unsigned>);
    void updateActiveScrollSnapIndexForClientOffset();
    void resnapAfterLayout();

    std::optional<unsigned> activeScrollSnapIndexForAxis(ScrollEventAxis) const;
    float adjustedScrollDestination(ScrollEventAxis, FloatPoint destinationOffset, float velocity, std::optional<float> originalOffset) const;

    bool activeScrollSnapIndexDidChange() const { return m_activeScrollSnapIndexDidChange; }
    // FIXME: This is never called. We never set m_activeScrollSnapIndexDidChange back to false.
    void setScrollSnapIndexDidChange(bool state) { m_activeScrollSnapIndexDidChange = state; }

    // Returns true if handled.
    bool handleWheelEvent(const PlatformWheelEvent&);

    bool isScrollSnapInProgress() const;
    bool isUserScrollInProgress() const;

#if PLATFORM(MAC)
    static FloatSize wheelDeltaBiasingTowardsVertical(const FloatSize&);

    // Returns true if handled.
    bool processWheelEventForScrollSnap(const PlatformWheelEvent&);

    void stopRubberBanding();
    bool isRubberBandInProgress() const;
    RectEdges<bool> rubberBandingEdges() const { return m_rubberBandingEdges; }
#endif

private:
    void updateRubberBandAnimatingState();
    void updateKeyboardScrollingAnimatingState(MonotonicTime);

    void setIsAnimatingRubberBand(bool);
    void setIsAnimatingScrollSnap(bool);
    void setIsAnimatingKeyboardScrolling(bool);

    void startScrollSnapAnimation();
    void stopScrollSnapAnimation();

#if PLATFORM(MAC)
    bool shouldOverrideMomentumScrolling() const;
    void statelessSnapTransitionTimerFired();
    void scheduleStatelessScrollSnap();

    bool modifyScrollDeltaForStretching(const PlatformWheelEvent&, FloatSize&, bool isHorizontallyStretched, bool isVerticallyStretched);
    bool applyScrollDeltaWithStretching(const PlatformWheelEvent&, FloatSize, bool isHorizontallyStretched, bool isVerticallyStretched);

    void startRubberBandAnimationIfNecessary();

    bool startRubberBandAnimation(const FloatSize& initialVelocity, const FloatSize& initialOverscroll);
    void stopRubberBandAnimation();

    void willStartRubberBandAnimation();
    void didStopRubberBandAnimation();

    bool shouldRubberBandOnSide(BoxSide) const;
    bool isRubberBandInProgressInternal() const;
    void updateRubberBandingState();
    void updateRubberBandingEdges(IntSize clientStretch);
#endif

    void startOrStopAnimationCallbacks();

    void startDeferringWheelEventTestCompletion(WheelEventTestMonitor::DeferReason);
    void stopDeferringWheelEventTestCompletion(WheelEventTestMonitor::DeferReason);

    // ScrollAnimationClient
    void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& /* currentOffset */) final;
    void scrollAnimationWillStart(ScrollAnimation&) final;
    void scrollAnimationDidEnd(ScrollAnimation&) final;
    ScrollExtents scrollExtentsForAnimation(ScrollAnimation&) final;
    FloatSize overscrollAmount(ScrollAnimation&) final;
    FloatPoint scrollOffset(ScrollAnimation&) final;

    void adjustDeltaForSnappingIfNeeded(float& deltaX, float& deltaY);

#if ENABLE(KINETIC_SCROLLING) && !PLATFORM(MAC)
    // Returns true if handled.
    bool processWheelEventForKineticScrolling(const PlatformWheelEvent&);

    Deque<PlatformWheelEvent> m_scrollHistory;

    struct {
        MonotonicTime startTime;
        FloatPoint initialOffset;
        FloatSize initialVelocity;
    } m_previousKineticAnimationInfo;
#endif

    ScrollingEffectsControllerClient& m_client;

    std::unique_ptr<ScrollAnimation> m_currentAnimation;

    std::unique_ptr<ScrollSnapAnimatorState> m_scrollSnapState;
    bool m_activeScrollSnapIndexDidChange { false };

    bool m_isRunningAnimatingCallback { false };
    bool m_isAnimatingRubberBand { false };
    bool m_isAnimatingScrollSnap { false };
    bool m_isAnimatingKeyboardScrolling { false };
    bool m_inScrollGesture { false };

#if PLATFORM(MAC)
    WallTime m_lastMomentumScrollTimestamp;
    FloatSize m_unappliedOverscrollDelta;
    FloatSize m_stretchScrollForce;
    FloatSize m_momentumVelocity;

    FloatSize m_scrollingVelocityForScrollSnap;

    bool m_momentumScrollInProgress { false };
    bool m_ignoreMomentumScrolls { false };
    bool m_isRubberBanding { false };

    std::unique_ptr<ScrollingEffectsControllerTimer> m_statelessSnapTransitionTimer;

#if HAVE(RUBBER_BANDING)
    RectEdges<bool> m_rubberBandingEdges;
#endif

#if ASSERT_ENABLED
    bool m_timersWereStopped { false };
#endif
#endif
};

} // namespace WebCore
