/*
 * Copyright (C) 2013, 2014 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 "MessageReceiver.h"
#include "SameDocumentNavigationType.h"
#include <WebCore/Color.h>
#include <WebCore/FloatRect.h>
#include <wtf/MonotonicTime.h>
#include <wtf/RetainPtr.h>
#include <wtf/RunLoop.h>
#include <wtf/WeakPtr.h>

#if PLATFORM(COCOA)
#include <wtf/BlockPtr.h>
#endif

#if PLATFORM(GTK)
#include <WebCore/CairoUtilities.h>
#include <gtk/gtk.h>
#endif

#if PLATFORM(COCOA)
OBJC_CLASS CALayer;

#if PLATFORM(IOS_FAMILY)
OBJC_CLASS UIGestureRecognizer;
OBJC_CLASS UIView;
OBJC_CLASS WKSwipeTransitionController;
OBJC_CLASS _UINavigationInteractiveTransitionBase;
OBJC_CLASS _UIViewControllerOneToOneTransitionContext;
OBJC_CLASS _UIViewControllerTransitionContext;
#else
OBJC_CLASS CAGradientLayer;
OBJC_CLASS NSEvent;
OBJC_CLASS NSView;
OBJC_CLASS WKSwipeCancellationTracker;
#endif

namespace WebCore {
class IOSurface;
}
#endif

#if PLATFORM(MAC)
typedef NSEvent* PlatformScrollEvent;
#elif PLATFORM(GTK)
typedef struct _GdkEventScroll GdkEventScroll;
typedef GdkEventScroll* PlatformScrollEvent;
#endif

namespace WebKit {

class ViewSnapshot;
class WebBackForwardListItem;
class WebPageProxy;
class WebProcessProxy;

class ViewGestureController : private IPC::MessageReceiver {
    WTF_MAKE_FAST_ALLOCATED;
    WTF_MAKE_NONCOPYABLE(ViewGestureController);
public:
    ViewGestureController(WebPageProxy&);
    ~ViewGestureController();
    void platformTeardown();

    void disconnectFromProcess();
    void connectToProcess();

    enum class ViewGestureType {
        None,
#if PLATFORM(MAC)
        Magnification,
        SmartMagnification,
#endif
        Swipe
    };

    enum class SwipeDirection {
        Back,
        Forward
    };

    typedef uint64_t GestureID;

#if !PLATFORM(IOS_FAMILY)
    bool handleScrollWheelEvent(PlatformScrollEvent);
    void wheelEventWasNotHandledByWebCore(PlatformScrollEvent event) { m_pendingSwipeTracker.eventWasNotHandledByWebCore(event); }

    bool shouldIgnorePinnedState() { return m_pendingSwipeTracker.shouldIgnorePinnedState(); }
    void setShouldIgnorePinnedState(bool ignore) { m_pendingSwipeTracker.setShouldIgnorePinnedState(ignore); }

    bool isPhysicallySwipingLeft(SwipeDirection) const;
#endif

#if PLATFORM(MAC)
    double magnification() const;

    void handleMagnificationGestureEvent(PlatformScrollEvent, WebCore::FloatPoint origin);

    bool hasActiveMagnificationGesture() const { return m_activeGestureType == ViewGestureType::Magnification; }

    void handleSmartMagnificationGesture(WebCore::FloatPoint origin);

    void gestureEventWasNotHandledByWebCore(PlatformScrollEvent, WebCore::FloatPoint origin);

    void setCustomSwipeViews(Vector<RetainPtr<NSView>> views) { m_customSwipeViews = WTFMove(views); }
    void setCustomSwipeViewsTopContentInset(float topContentInset) { m_customSwipeViewsTopContentInset = topContentInset; }
    WebCore::FloatRect windowRelativeBoundsForCustomSwipeViews() const;
    void setDidMoveSwipeSnapshotCallback(BlockPtr<void (CGRect)>&& callback) { m_didMoveSwipeSnapshotCallback = WTFMove(callback); }
#elif PLATFORM(IOS_FAMILY)
    bool isNavigationSwipeGestureRecognizer(UIGestureRecognizer *) const;
    void installSwipeHandler(UIView *gestureRecognizerView, UIView *swipingView);
    void beginSwipeGesture(_UINavigationInteractiveTransitionBase *, SwipeDirection);
    void endSwipeGesture(WebBackForwardListItem* targetItem, _UIViewControllerTransitionContext *, bool cancelled);
    void willCommitPostSwipeTransitionLayerTree(bool);
    void setRenderTreeSize(uint64_t);
#endif

    void setAlternateBackForwardListSourcePage(WebPageProxy*);

    bool canSwipeInDirection(SwipeDirection) const;

    WebCore::Color backgroundColorForCurrentSnapshot() const { return m_backgroundColorForCurrentSnapshot; }

    void didStartProvisionalLoadForMainFrame();
    void didFinishLoadForMainFrame() { didReachMainFrameLoadTerminalState(); }
    void didFailLoadForMainFrame() { didReachMainFrameLoadTerminalState(); }
    void didFirstVisuallyNonEmptyLayoutForMainFrame();
    void didRepaintAfterNavigation();
    void didHitRenderTreeSizeThreshold();
    void didRestoreScrollPosition();
    void didReachMainFrameLoadTerminalState();
    void didSameDocumentNavigationForMainFrame(SameDocumentNavigationType);

    void checkForActiveLoads();

    void removeSwipeSnapshot();

    void setSwipeGestureEnabled(bool enabled) { m_swipeGestureEnabled = enabled; }
    bool isSwipeGestureEnabled() { return m_swipeGestureEnabled; }

#if PLATFORM(GTK)
    void draw(cairo_t*, cairo_pattern_t*);
#endif

    // Testing
    bool beginSimulatedSwipeInDirectionForTesting(SwipeDirection);
    bool completeSimulatedSwipeInDirectionForTesting(SwipeDirection);

private:
    // IPC::MessageReceiver.
    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;

    static ViewGestureController* controllerForGesture(uint64_t pageID, GestureID);

    static GestureID takeNextGestureID();
    void willBeginGesture(ViewGestureType);
    void didEndGesture();

    void didStartProvisionalOrSameDocumentLoadForMainFrame();

    class SnapshotRemovalTracker {
    public:
        enum Event : uint8_t {
            VisuallyNonEmptyLayout = 1 << 0,
            RenderTreeSizeThreshold = 1 << 1,
            RepaintAfterNavigation = 1 << 2,
            MainFrameLoad = 1 << 3,
            SubresourceLoads = 1 << 4,
            ScrollPositionRestoration = 1 << 5
        };
        typedef uint8_t Events;

        SnapshotRemovalTracker();

        void start(Events, WTF::Function<void()>&&);
        void reset();

        void pause() { m_paused = true; }
        void resume();
        bool isPaused() const { return m_paused; }
        bool hasRemovalCallback() const { return !!m_removalCallback; }

        bool eventOccurred(Events);
        bool cancelOutstandingEvent(Events);
        bool hasOutstandingEvent(Event);

        void startWatchdog(Seconds);

        uint64_t renderTreeSizeThreshold() const { return m_renderTreeSizeThreshold; }
        void setRenderTreeSizeThreshold(uint64_t threshold) { m_renderTreeSizeThreshold = threshold; }

    private:
        static String eventsDescription(Events);
        void log(const String&) const;

        void fireRemovalCallbackImmediately();
        void fireRemovalCallbackIfPossible();
        void watchdogTimerFired();

        bool stopWaitingForEvent(Events, const String& logReason);

        Events m_outstandingEvents { 0 };
        WTF::Function<void()> m_removalCallback;
        MonotonicTime m_startTime;

        uint64_t m_renderTreeSizeThreshold { 0 };

        RunLoop::Timer<SnapshotRemovalTracker> m_watchdogTimer;

        bool m_paused { true };
    };

#if PLATFORM(MAC)
    // Message handlers.
    void didCollectGeometryForMagnificationGesture(WebCore::FloatRect visibleContentBounds, bool frameHandlesMagnificationGesture);
    void didCollectGeometryForSmartMagnificationGesture(WebCore::FloatPoint origin, WebCore::FloatRect renderRect, WebCore::FloatRect visibleContentBounds, bool fitEntireRect, double viewportMinimumScale, double viewportMaximumScale);

    void endMagnificationGesture();

    WebCore::FloatPoint scaledMagnificationOrigin(WebCore::FloatPoint origin, double scale);
#endif

#if !PLATFORM(IOS_FAMILY)
    void startSwipeGesture(PlatformScrollEvent, SwipeDirection);
    void trackSwipeGesture(PlatformScrollEvent, SwipeDirection, RefPtr<WebBackForwardListItem>);

    void beginSwipeGesture(WebBackForwardListItem* targetItem, SwipeDirection);
    void handleSwipeGesture(WebBackForwardListItem* targetItem, double progress, SwipeDirection);

    void willEndSwipeGesture(WebBackForwardListItem& targetItem, bool cancelled);
    void endSwipeGesture(WebBackForwardListItem* targetItem, bool cancelled);
    bool shouldUseSnapshotForSize(ViewSnapshot&, WebCore::FloatSize swipeLayerSize, float topContentInset);

#if PLATFORM(MAC)
    CALayer* determineSnapshotLayerParent() const;
    CALayer* determineLayerAdjacentToSnapshotForParent(SwipeDirection, CALayer* snapshotLayerParent) const;
    void applyDebuggingPropertiesToSwipeViews();
    void didMoveSwipeSnapshotLayer();
#endif

    void requestRenderTreeSizeNotificationIfNeeded();
    void forceRepaintIfNeeded();

    class PendingSwipeTracker {
    public:
        PendingSwipeTracker(WebPageProxy&, ViewGestureController&);
        bool handleEvent(PlatformScrollEvent);
        void eventWasNotHandledByWebCore(PlatformScrollEvent);

        void reset(const char* resetReasonForLogging);

        bool shouldIgnorePinnedState() { return m_shouldIgnorePinnedState; }
        void setShouldIgnorePinnedState(bool ignore) { m_shouldIgnorePinnedState = ignore; }

    private:
        bool tryToStartSwipe(PlatformScrollEvent);
        bool scrollEventCanBecomeSwipe(PlatformScrollEvent, SwipeDirection&);

        bool scrollEventCanStartSwipe(PlatformScrollEvent);
        bool scrollEventCanEndSwipe(PlatformScrollEvent);
        bool scrollEventCanInfluenceSwipe(PlatformScrollEvent);
        WebCore::FloatSize scrollEventGetScrollingDeltas(PlatformScrollEvent);

        enum class State {
            None,
            WaitingForWebCore,
            InsufficientMagnitude
        };

        State m_state { State::None };
        SwipeDirection m_direction;
        WebCore::FloatSize m_cumulativeDelta;

        bool m_shouldIgnorePinnedState { false };

        ViewGestureController& m_viewGestureController;
        WebPageProxy& m_webPageProxy;
    };
#endif

    WebPageProxy& m_webPageProxy;
    ViewGestureType m_activeGestureType { ViewGestureType::None };

    bool m_swipeGestureEnabled { true };

    RunLoop::Timer<ViewGestureController> m_swipeActiveLoadMonitoringTimer;

    WebCore::Color m_backgroundColorForCurrentSnapshot;

    WeakPtr<WebPageProxy> m_alternateBackForwardListSourcePage;
    RefPtr<WebPageProxy> m_webPageProxyForBackForwardListForCurrentSwipe;

    GestureID m_currentGestureID;

#if !PLATFORM(IOS_FAMILY)
    RefPtr<ViewSnapshot> m_currentSwipeSnapshot;

    PendingSwipeTracker m_pendingSwipeTracker;

    bool m_hasOutstandingRepaintRequest { false };
#endif

#if PLATFORM(MAC)
    double m_magnification;
    WebCore::FloatPoint m_magnificationOrigin;

    WebCore::FloatRect m_lastSmartMagnificationUnscaledTargetRect;
    bool m_lastMagnificationGestureWasSmartMagnification { false };
    WebCore::FloatPoint m_lastSmartMagnificationOrigin;

    WebCore::FloatRect m_visibleContentRect;
    bool m_visibleContentRectIsValid { false };
    bool m_frameHandlesMagnificationGesture { false };

    RetainPtr<WKSwipeCancellationTracker> m_swipeCancellationTracker;
    RetainPtr<CALayer> m_swipeLayer;
    RetainPtr<CALayer> m_swipeSnapshotLayer;
    RetainPtr<CAGradientLayer> m_swipeShadowLayer;
    RetainPtr<CALayer> m_swipeDimmingLayer;
    Vector<RetainPtr<CALayer>> m_currentSwipeLiveLayers;

    Vector<RetainPtr<NSView>> m_customSwipeViews;
    float m_customSwipeViewsTopContentInset { 0 };
    WebCore::FloatRect m_currentSwipeCustomViewBounds;

    BlockPtr<void (CGRect)> m_didMoveSwipeSnapshotCallback;
#elif PLATFORM(IOS_FAMILY)
    UIView* m_liveSwipeView { nullptr };
    RetainPtr<UIView> m_liveSwipeViewClippingView;
    RetainPtr<UIView> m_snapshotView;
    RetainPtr<UIView> m_transitionContainerView;
    RetainPtr<WKSwipeTransitionController> m_swipeInteractiveTransitionDelegate;
    RetainPtr<_UIViewControllerOneToOneTransitionContext> m_swipeTransitionContext;
    uint64_t m_snapshotRemovalTargetRenderTreeSize { 0 };
#endif

#if PLATFORM(GTK)
    class SwipeProgressTracker {
    public:
        SwipeProgressTracker(WebPageProxy&, ViewGestureController&);
        void startTracking(RefPtr<WebBackForwardListItem>&&, SwipeDirection);
        void reset();
        bool handleEvent(PlatformScrollEvent);
        float progress() const { return m_progress; }
        SwipeDirection direction() const { return m_direction; }

    private:
        enum class State {
            None,
            Pending,
            Scrolling,
            Animating,
            Finishing
        };

        bool shouldCancel();

        void startAnimation();
        gboolean onAnimationTick(GdkFrameClock*);
        void endAnimation();

        State m_state { State::None };

        SwipeDirection m_direction;
        RefPtr<WebBackForwardListItem> m_targetItem;
        unsigned m_tickCallbackID { 0 };

        Seconds m_prevTime;
        double m_velocity { 0 };

        Seconds m_startTime;
        Seconds m_endTime;

        float m_progress { 0 };
        float m_startProgress { 0 };
        float m_endProgress { 0 };
        bool m_cancelled { false };

        ViewGestureController& m_viewGestureController;
        WebPageProxy& m_webPageProxy;
    };

    SwipeProgressTracker m_swipeProgressTracker;

    RefPtr<cairo_pattern_t> m_currentSwipeSnapshotPattern;
#endif

    bool m_isConnectedToProcess { false };

    SnapshotRemovalTracker m_snapshotRemovalTracker;
    WTF::Function<void()> m_loadCallback;
};

} // namespace WebKit
