/*
 * 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 "WebPageProxyIdentifier.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>
#include <wtf/glib/GRefPtr.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 cancelSwipe();
    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(WebPageProxyIdentifier, 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

#if PLATFORM(GTK)
    GRefPtr<GtkStyleContext> createStyleContext(const char*);
#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 { SwipeDirection::Back };
        RefPtr<WebBackForwardListItem> m_targetItem;
        unsigned m_tickCallbackID { 0 };

        Seconds m_prevTime;
        double m_velocity { 0 };
        double m_distance { 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;
    RefPtr<cairo_pattern_t> m_swipeDimmingPattern;
    RefPtr<cairo_pattern_t> m_swipeShadowPattern;
    RefPtr<cairo_pattern_t> m_swipeBorderPattern;
    RefPtr<cairo_pattern_t> m_swipeOutlinePattern;
    int m_swipeShadowSize;
    int m_swipeBorderSize;
    int m_swipeOutlineSize;
    GRefPtr<GtkCssProvider> m_cssProvider;

    bool m_isSimulatedSwipe { false };
#endif

    bool m_isConnectedToProcess { false };

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

} // namespace WebKit
