/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 * Copyright (C) 2019 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.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "Color.h"
#include "FloatLine.h"
#include "FloatQuad.h"
#include "FloatRect.h"
#include "Path.h"
#include "Timer.h"
#include <wtf/Deque.h>
#include <wtf/MonotonicTime.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
#include <wtf/WeakPtr.h>
#include <wtf/text/WTFString.h>

namespace Inspector {
using ErrorString = String;

template <typename T>
using ErrorStringOr = Expected<T, ErrorString>;
}

namespace WebCore {

class FontCascade;
class FloatPoint;
class GraphicsContext;
class InspectorClient;
class Node;
class NodeList;
class Page;

class InspectorOverlay {
    WTF_MAKE_FAST_ALLOCATED;
public:
    InspectorOverlay(Page&, InspectorClient*);
    ~InspectorOverlay();

    enum class LabelArrowDirection {
        None,
        Down,
        Up,
        Left,
        Right,
    };

    enum class LabelArrowEdgePosition {
        None,
        Leading, // Positioned at the left/top side of edge.
        Middle, // Positioned at the center on the edge.
        Trailing, // Positioned at the right/bottom side of the edge.
    };

    struct Highlight {
        WTF_MAKE_STRUCT_FAST_ALLOCATED;

        enum class Type {
            None, // Provides only non-quad information, including grid overlays.
            Node, // Provides 4 quads: margin, border, padding, content.
            NodeList, // Provides a list of nodes.
            Rects, // Provides a list of quads.
        };

        struct Config {
            WTF_MAKE_STRUCT_FAST_ALLOCATED;
            Color content;
            Color contentOutline;
            Color padding;
            Color border;
            Color margin;
            bool showInfo;
            bool usePageCoordinates;
        };

        struct GridHighlightOverlay {
            WTF_MAKE_STRUCT_FAST_ALLOCATED;

            struct Label {
                WTF_MAKE_STRUCT_FAST_ALLOCATED;
                String text;
                FloatPoint location;
                Color backgroundColor;
                LabelArrowDirection arrowDirection;
                LabelArrowEdgePosition arrowEdgePosition;

#if PLATFORM(IOS_FAMILY)
                template<class Encoder> void encode(Encoder&) const;
                template<class Decoder> static std::optional<InspectorOverlay::Highlight::GridHighlightOverlay::Label> decode(Decoder&);
#endif
            };

            struct Area {
                WTF_MAKE_STRUCT_FAST_ALLOCATED;
                String name;
                FloatQuad quad;

#if PLATFORM(IOS_FAMILY)
                template<class Encoder> void encode(Encoder&) const;
                template<class Decoder> static std::optional<InspectorOverlay::Highlight::GridHighlightOverlay::Area> decode(Decoder&);
#endif
            };

            Color color;
            Vector<FloatLine> gridLines;
            Vector<FloatQuad> gaps;
            Vector<Area> areas;
            Vector<Label> labels;

#if PLATFORM(IOS_FAMILY)
            template<class Encoder> void encode(Encoder&) const;
            template<class Decoder> static std::optional<InspectorOverlay::Highlight::GridHighlightOverlay> decode(Decoder&);
#endif
        };

        void setDataFromConfig(const Config& config)
        {
            contentColor = config.content;
            contentOutlineColor = config.contentOutline;
            paddingColor = config.padding;
            borderColor = config.border;
            marginColor = config.margin;
            usePageCoordinates = config.usePageCoordinates;
        }

        Color contentColor;
        Color contentOutlineColor;
        Color paddingColor;
        Color borderColor;
        Color marginColor;

        Type type {Type::Node};
        Vector<FloatQuad> quads;
        Vector<GridHighlightOverlay> gridHighlightOverlays;
        bool usePageCoordinates {true};

        using Bounds = FloatRect;
    };

    struct Grid {
        WTF_MAKE_STRUCT_FAST_ALLOCATED;

        struct Config {
            WTF_MAKE_STRUCT_FAST_ALLOCATED;

            Color gridColor;
            bool showLineNames;
            bool showLineNumbers;
            bool showExtendedGridLines;
            bool showTrackSizes;
            bool showAreaNames;
        };

        WeakPtr<Node> gridNode;
        Config config;
    };

    enum class CoordinateSystem {
        View, // Adjusts for the main frame's scroll offset.
        Document, // Does not adjust for the main frame's scroll offset.
    };

    void update();
    void paint(GraphicsContext&);
    void getHighlight(Highlight&, CoordinateSystem);
    bool shouldShowOverlay() const;

    void hideHighlight();
    void highlightNodeList(RefPtr<NodeList>&&, const Highlight::Config&);
    void highlightNode(Node*, const Highlight::Config&);
    void highlightQuad(std::unique_ptr<FloatQuad>, const Highlight::Config&);

    void setShowPaintRects(bool);
    void showPaintRect(const FloatRect&);
    unsigned paintRectCount() const { return m_paintRects.size(); }

    void setShowRulers(bool);
    void setShowRulersDuringElementSelection(bool enabled) { m_showRulersDuringElementSelection = enabled; }

    Node* highlightedNode() const;
    unsigned gridOverlayCount() const { return m_activeGridOverlays.size(); }

    void didSetSearchingForNode(bool enabled);

    void setIndicating(bool indicating);

    // Multiple grid overlays can be active at the same time. These methods
    // will fail if the node is not a grid or if the node has been GC'd.
    Inspector::ErrorStringOr<void> setGridOverlayForNode(Node&, const InspectorOverlay::Grid::Config&);
    Inspector::ErrorStringOr<void> clearGridOverlayForNode(Node&);
    void clearAllGridOverlays();

    WEBCORE_EXPORT static FontCascade fontForLayoutLabel();
    WEBCORE_EXPORT static Path backgroundPathForLayoutLabel(float, float, InspectorOverlay::LabelArrowDirection, InspectorOverlay::LabelArrowEdgePosition, float arrowSize);
private:
    using TimeRectPair = std::pair<MonotonicTime, FloatRect>;

    struct RulerExclusion {
        Highlight::Bounds bounds;
        Path titlePath;
    };

    RulerExclusion drawNodeHighlight(GraphicsContext&, Node&);
    RulerExclusion drawQuadHighlight(GraphicsContext&, const FloatQuad&);
    void drawPaintRects(GraphicsContext&, const Deque<TimeRectPair>&);
    void drawBounds(GraphicsContext&, const Highlight::Bounds&);
    void drawRulers(GraphicsContext&, const RulerExclusion&);

    Path drawElementTitle(GraphicsContext&, Node&, const Highlight::Bounds&);
    
    void drawLayoutHatching(GraphicsContext&, FloatQuad);
    void drawLayoutLabel(GraphicsContext&, String, FloatPoint, LabelArrowDirection, InspectorOverlay::LabelArrowEdgePosition, Color backgroundColor = Color::white, float maximumWidth = 0);

    void drawGridOverlay(GraphicsContext&, const InspectorOverlay::Highlight::GridHighlightOverlay&);
    std::optional<InspectorOverlay::Highlight::GridHighlightOverlay> buildGridOverlay(const InspectorOverlay::Grid&, bool offsetBoundsByScroll = false);

    void updatePaintRectsTimerFired();

    bool removeGridOverlayForNode(Node&);

    Page& m_page;
    InspectorClient* m_client;

    RefPtr<Node> m_highlightNode;
    RefPtr<NodeList> m_highlightNodeList;
    Highlight::Config m_nodeHighlightConfig;

    std::unique_ptr<FloatQuad> m_highlightQuad;
    Highlight::Config m_quadHighlightConfig;

    Deque<TimeRectPair> m_paintRects;
    Timer m_paintRectUpdateTimer;

    Vector<InspectorOverlay::Grid> m_activeGridOverlays;

    bool m_indicating { false };
    bool m_showPaintRects { false };
    bool m_showRulers { false };
    bool m_showRulersDuringElementSelection { false };
};

#if PLATFORM(IOS_FAMILY)

template<class Encoder> void InspectorOverlay::Highlight::GridHighlightOverlay::encode(Encoder& encoder) const
{
    encoder << color;
    encoder << gridLines;
    encoder << gaps;
    encoder << areas;
    encoder << labels;
}

template<class Decoder> std::optional<InspectorOverlay::Highlight::GridHighlightOverlay> InspectorOverlay::Highlight::GridHighlightOverlay::decode(Decoder& decoder)
{
    InspectorOverlay::Highlight::GridHighlightOverlay gridHighlightOverlay;
    if (!decoder.decode(gridHighlightOverlay.color))
        return { };
    if (!decoder.decode(gridHighlightOverlay.gridLines))
        return { };
    if (!decoder.decode(gridHighlightOverlay.gaps))
        return { };
    if (!decoder.decode(gridHighlightOverlay.areas))
        return { };
    if (!decoder.decode(gridHighlightOverlay.labels))
        return { };
    return { gridHighlightOverlay };
}

template<class Encoder> void InspectorOverlay::Highlight::GridHighlightOverlay::Label::encode(Encoder& encoder) const
{
    encoder << text;
    encoder << location;
    encoder << backgroundColor;
    encoder << static_cast<uint32_t>(arrowDirection);
    encoder << static_cast<uint32_t>(arrowEdgePosition);
}

template<class Decoder> std::optional<InspectorOverlay::Highlight::GridHighlightOverlay::Label> InspectorOverlay::Highlight::GridHighlightOverlay::Label::decode(Decoder& decoder)
{
    InspectorOverlay::Highlight::GridHighlightOverlay::Label label;
    if (!decoder.decode(label.text))
        return { };
    if (!decoder.decode(label.location))
        return { };
    if (!decoder.decode(label.backgroundColor))
        return { };

    uint32_t arrowDirection;
    if (!decoder.decode(arrowDirection))
        return { };
    label.arrowDirection = (InspectorOverlay::LabelArrowDirection)arrowDirection;

    uint32_t arrowEdgePosition;
    if (!decoder.decode(arrowEdgePosition))
        return { };
    label.arrowEdgePosition = (InspectorOverlay::LabelArrowEdgePosition)arrowEdgePosition;

    return { label };
}

template<class Encoder> void InspectorOverlay::Highlight::GridHighlightOverlay::Area::encode(Encoder& encoder) const
{
    encoder << name;
    encoder << quad;
}

template<class Decoder> std::optional<InspectorOverlay::Highlight::GridHighlightOverlay::Area> InspectorOverlay::Highlight::GridHighlightOverlay::Area::decode(Decoder& decoder)
{
    InspectorOverlay::Highlight::GridHighlightOverlay::Area area;
    if (!decoder.decode(area.name))
        return { };
    if (!decoder.decode(area.quad))
        return { };
    return { area };
}

#endif

} // namespace WebCore
