/*
 * Copyright 2022 Rive
 */

#include "rive/pls/pls_renderer.hpp"

#include "pls_paint.hpp"
#include "pls_path.hpp"
#include "rive/math/math_types.hpp"
#include "rive/math/simd.hpp"
#include "rive/pls/pls_image.hpp"
#include "shaders/constants.glsl"

namespace rive::pls
{
bool PLSRenderer::IsAABB(const RawPath& path, AABB* result)
{
    // Any quadrilateral begins with a move plus 3 lines.
    constexpr static size_t kAABBVerbCount = 4;
    constexpr static PathVerb aabbVerbs[kAABBVerbCount] = {PathVerb::move,
                                                           PathVerb::line,
                                                           PathVerb::line,
                                                           PathVerb::line};
    Span<const PathVerb> verbs = path.verbs();
    if (verbs.count() < kAABBVerbCount || memcmp(verbs.data(), aabbVerbs, sizeof(aabbVerbs)) != 0)
    {
        return false;
    }

    // Only accept extra verbs and points if every point after the quadrilateral is equal to p0.
    Span<const Vec2D> pts = path.points();
    for (size_t i = 4; i < pts.count(); ++i)
    {
        if (pts[i] != pts[0])
        {
            return false;
        }
    }

    // We have a quadrilateral! Now check if it is an axis-aligned rectangle.
    float4 corners = {pts[0].x, pts[0].y, pts[2].x, pts[2].y};
    float4 oppositeCorners = {pts[1].x, pts[1].y, pts[3].x, pts[3].y};
    if (simd::all(corners == oppositeCorners.zyxw) || simd::all(corners == oppositeCorners.xwzy))
    {
        float4 r = simd::join(simd::min(corners.xy, corners.zw), simd::max(corners.xy, corners.zw));
        simd::store(result, r);
        return true;
    }
    return false;
}

PLSRenderer::ClipElement::ClipElement(const Mat2D& matrix_,
                                      const PLSPath* path_,
                                      FillRule fillRule_)
{
    reset(matrix_, path_, fillRule_);
}

PLSRenderer::ClipElement::~ClipElement() {}

void PLSRenderer::ClipElement::reset(const Mat2D& matrix_, const PLSPath* path_, FillRule fillRule_)
{
    matrix = matrix_;
    rawPathMutationID = path_->getRawPathMutationID();
    pathBounds = path_->getBounds();
    path = ref_rcp(path_);
    fillRule = fillRule_;
    clipID = 0; // This gets initialized lazily.
}

bool PLSRenderer::ClipElement::isEquivalent(const Mat2D& matrix_, const PLSPath* path_) const
{
    return matrix_ == matrix && path_->getRawPathMutationID() == rawPathMutationID &&
           path_->getFillRule() == fillRule;
}

PLSRenderer::PLSRenderer(PLSRenderContext* context) : m_context(context) {}

PLSRenderer::~PLSRenderer() {}

void PLSRenderer::save()
{
    // Copy the back of the stack before pushing, in case the vector grows and invalidates the
    // reference.
    RenderState copy = m_stack.back();
    m_stack.push_back(copy);
}

void PLSRenderer::restore()
{
    assert(m_stack.size() > 1);
    assert(m_stack.back().clipStackHeight >= m_stack[m_stack.size() - 2].clipStackHeight);
    m_stack.pop_back();
}

void PLSRenderer::transform(const Mat2D& matrix)
{
    m_stack.back().matrix = m_stack.back().matrix * matrix;
}

void PLSRenderer::drawPath(RenderPath* renderPath, RenderPaint* renderPaint)
{
    LITE_RTTI_CAST_OR_RETURN(path, PLSPath*, renderPath);
    LITE_RTTI_CAST_OR_RETURN(paint, PLSPaint*, renderPaint);

    bool stroked = paint->getIsStroked();

    if (stroked && m_context->frameDescriptor().strokesDisabled)
    {
        return;
    }
    if (!stroked && m_context->frameDescriptor().fillsDisabled)
    {
        return;
    }
    if (stroked && !(paint->getThickness() > 0)) // Use inverse logic to ensure we abort when stroke
    {                                            // thickness is NaN.
        return;
    }

    clipAndPushDraw(PLSPathDraw::Make(m_context,
                                      m_stack.back().matrix,
                                      ref_rcp(path),
                                      path->getFillRule(),
                                      paint,
                                      &m_scratchPath));
}

void PLSRenderer::clipPath(RenderPath* renderPath)
{
    LITE_RTTI_CAST_OR_RETURN(path, PLSPath*, renderPath);

    // First try to handle axis-aligned rectangles using the "ENABLE_CLIP_RECT" shader feature.
    // Multiple axis-aligned rectangles can be intersected into a single rectangle if their matrices
    // are compatible.
    AABB clipRectCandidate;
    if (m_context->frameSupportsClipRects() && IsAABB(path->getRawPath(), &clipRectCandidate))
    {
        clipRectImpl(clipRectCandidate, path);
    }
    else
    {
        clipPathImpl(path);
    }
}

// Finds a new rect, if such a rect exists, such that:
//
//     currentMatrix * rect == newMatrix * newRect
//
// Returns true if *rect was replaced with newRect.
static bool transform_rect_to_new_space(AABB* rect,
                                        const Mat2D& currentMatrix,
                                        const Mat2D& newMatrix)
{
    if (currentMatrix == newMatrix)
    {
        return true;
    }
    Mat2D currentToNew;
    if (!newMatrix.invert(&currentToNew))
    {
        return false;
    }
    currentToNew = currentToNew * currentMatrix;
    float maxSkew = std::max(fabsf(currentToNew.xy()), fabsf(currentToNew.yx()));
    float maxScale = std::max(fabsf(currentToNew.xx()), fabsf(currentToNew.yy()));
    if (maxSkew > math::EPSILON && maxScale > math::EPSILON)
    {
        // Transforming this rect to the new view matrix would turn it into something that isn't a
        // rect.
        return false;
    }
    Vec2D pts[2] = {{rect->left(), rect->top()}, {rect->right(), rect->bottom()}};
    currentToNew.mapPoints(pts, pts, 2);
    float4 p = simd::load4f(pts);
    float2 topLeft = simd::min(p.xy, p.zw);
    float2 botRight = simd::max(p.xy, p.zw);
    *rect = {topLeft.x, topLeft.y, botRight.x, botRight.y};
    return true;
}

void PLSRenderer::clipRectImpl(AABB rect, const PLSPath* originalPath)
{
    bool hasClipRect = m_stack.back().clipRectInverseMatrix != nullptr;
    if (rect.isEmptyOrNaN())
    {
        m_stack.back().clipIsEmpty = true;
        return;
    }

    // If there already is a clipRect, we can only accept another one by intersecting it with the
    // existing one. This means the new rect must be axis-aligned with the existing clipRect.
    if (hasClipRect &&
        !transform_rect_to_new_space(&rect, m_stack.back().matrix, m_stack.back().clipRectMatrix))
    {
        // 'rect' is not axis-aligned with the existing clipRect. Fall back to clipPath.
        clipPathImpl(originalPath);
        return;
    }

    if (!hasClipRect)
    {
        // There wasn't an existing clipRect. This is the one!
        m_stack.back().clipRect = rect;
        m_stack.back().clipRectMatrix = m_stack.back().matrix;
    }
    else
    {
        // Both rects are in the same space now. Intersect the two geometrically.
        float4 a = simd::load4f(&m_stack.back().clipRect);
        float4 b = simd::load4f(&rect);
        float4 intersection = simd::join(simd::max(a.xy, b.xy), simd::min(a.zw, b.zw));
        simd::store(&m_stack.back().clipRect, intersection);
    }

    m_stack.back().clipRectInverseMatrix =
        m_context->make<pls::ClipRectInverseMatrix>(m_stack.back().clipRectMatrix,
                                                    m_stack.back().clipRect);
}

void PLSRenderer::clipPathImpl(const PLSPath* path)
{
    if (path->getBounds().isEmptyOrNaN())
    {
        m_stack.back().clipIsEmpty = true;
        return;
    }
    // Only write a new clip element if this path isn't already on the stack from before. e.g.:
    //
    //     clipPath(samePath);
    //     restore();
    //     save();
    //     clipPath(samePath); // <-- reuse the ClipElement (and clipID!) already in m_clipStack.
    //
    const size_t clipStackHeight = m_stack.back().clipStackHeight;
    assert(m_clipStack.size() >= clipStackHeight);
    if (m_clipStack.size() == clipStackHeight ||
        !m_clipStack[clipStackHeight].isEquivalent(m_stack.back().matrix, path))
    {
        m_clipStack.resize(clipStackHeight);
        m_clipStack.emplace_back(m_stack.back().matrix, path, path->getFillRule());
    }
    m_stack.back().clipStackHeight = clipStackHeight + 1;
}

void PLSRenderer::drawImage(const RenderImage* renderImage, BlendMode blendMode, float opacity)
{
    LITE_RTTI_CAST_OR_RETURN(image, const PLSImage*, renderImage);

    // Scale the view matrix so we can draw this image as the rect [0, 0, 1, 1].
    save();
    scale(image->width(), image->height());

    if (!m_context->frameSupportsImagePaintForPaths())
    {
        // Fall back on ImageRectDraw if the current frame doesn't support drawing paths with image
        // paints.
        const Mat2D& m = m_stack.back().matrix;
        auto plsImage = static_cast<const PLSImage*>(renderImage);
        clipAndPushDraw(PLSDrawUniquePtr(
            m_context->make<ImageRectDraw>(m_context,
                                           m.mapBoundingBox(AABB{0, 0, 1, 1}).roundOut(),
                                           m,
                                           blendMode,
                                           plsImage->refTexture(),
                                           opacity)));
    }
    else
    {
        // Implement drawImage() as drawPath() with a rectangular path and an image paint.
        if (m_unitRectPath == nullptr)
        {
            m_unitRectPath = make_rcp<PLSPath>();
            m_unitRectPath->line({1, 0});
            m_unitRectPath->line({1, 1});
            m_unitRectPath->line({0, 1});
        }

        PLSPaint paint;
        paint.image(image->refTexture(), opacity);
        paint.blendMode(blendMode);
        drawPath(m_unitRectPath.get(), &paint);
    }

    restore();
}

void PLSRenderer::drawImageMesh(const RenderImage* renderImage,
                                rcp<RenderBuffer> vertices_f32,
                                rcp<RenderBuffer> uvCoords_f32,
                                rcp<RenderBuffer> indices_u16,
                                uint32_t vertexCount,
                                uint32_t indexCount,
                                BlendMode blendMode,
                                float opacity)
{
    LITE_RTTI_CAST_OR_RETURN(image, const PLSImage*, renderImage);
    const PLSTexture* plsTexture = image->getTexture();

    assert(vertices_f32);
    assert(uvCoords_f32);
    assert(indices_u16);

    clipAndPushDraw(PLSDrawUniquePtr(m_context->make<ImageMeshDraw>(PLSDraw::kFullscreenPixelBounds,
                                                                    m_stack.back().matrix,
                                                                    blendMode,
                                                                    ref_rcp(plsTexture),
                                                                    std::move(vertices_f32),
                                                                    std::move(uvCoords_f32),
                                                                    std::move(indices_u16),
                                                                    indexCount,
                                                                    opacity)));
}

void PLSRenderer::clipAndPushDraw(PLSDrawUniquePtr draw)
{
    if (m_stack.back().clipIsEmpty)
    {
        return;
    }
    if (m_context->isOutsideCurrentFrame(draw->pixelBounds()))
    {
        return;
    }

    // Make two attempts to issue the draw: once on the context as-is and once with a clean flush.
    for (int i = 0; i < 2; ++i)
    {
        // Always make sure we begin this loop with the internal draw batch empty, and clear it when
        // we're done.
        struct AutoResetInternalDrawBatch
        {
        public:
            AutoResetInternalDrawBatch(PLSRenderer* renderer) : m_renderer(renderer)
            {
                assert(m_renderer->m_internalDrawBatch.empty());
            }
            ~AutoResetInternalDrawBatch() { m_renderer->m_internalDrawBatch.clear(); }

        private:
            PLSRenderer* m_renderer;
        };

        AutoResetInternalDrawBatch aridb(this);

        if (!applyClip(draw.get()))
        {
            // There wasn't room in the GPU buffers for this path draw. Flush and try again.
            m_context->logicalFlush();
            continue;
        }

        m_internalDrawBatch.push_back(std::move(draw));
        if (!m_context->pushDrawBatch(m_internalDrawBatch.data(), m_internalDrawBatch.size()))
        {
            // There wasn't room in the GPU buffers for this path draw. Flush and try again.
            m_context->logicalFlush();
            // Reclaim "draw" because we will use it again on the next iteration.
            draw = std::move(m_internalDrawBatch.back());
            assert(draw != nullptr);
            m_internalDrawBatch.pop_back();
            continue;
        }

        // Success!
        return;
    }

    // We failed to process the draw. Release its refs.
    fprintf(stderr,
            "PLSRenderer::clipAndPushDraw failed. The draw and/or clip stack are too complex.\n");
}

bool PLSRenderer::applyClip(PLSDraw* draw)
{
    draw->setClipRect(m_stack.back().clipRectInverseMatrix);

    const size_t clipStackHeight = m_stack.back().clipStackHeight;
    if (clipStackHeight == 0)
    {
        assert(draw->clipID() == 0);
        return true;
    }

    // Find which clip element in the stack (if any) is currently rendered to the clip buffer.
    size_t clipIdxCurrentlyInClipBuffer = -1; // i.e., "none".
    if (m_context->getClipContentID() != 0)
    {
        for (size_t i = clipStackHeight - 1; i != -1; --i)
        {
            if (m_clipStack[i].clipID == m_context->getClipContentID())
            {
                clipIdxCurrentlyInClipBuffer = i;
                break;
            }
        }
    }

    // Draw the necessary updates to the clip buffer (i.e., draw every clip element after
    // clipIdxCurrentlyInClipBuffer).
    uint32_t lastClipID = clipIdxCurrentlyInClipBuffer == -1
                              ? 0 // The next clip to be drawn is not nested.
                              : m_clipStack[clipIdxCurrentlyInClipBuffer].clipID;
    if (m_context->frameInterlockMode() == pls::InterlockMode::depthStencil)
    {
        if (lastClipID == 0 && m_context->getClipContentID() != 0)
        {
            // Time for a new stencil clip! Erase the clip currently in the stencil buffer before we
            // draw the new one.
            auto stencilClipClear = PLSDrawUniquePtr(m_context->make<StencilClipReset>(
                m_context,
                m_context->getClipContentID(),
                StencilClipReset::ResetAction::clearPreviousClip));
            if (!m_context->isOutsideCurrentFrame(stencilClipClear->pixelBounds()))
            {
                m_internalDrawBatch.push_back(std::move(stencilClipClear));
            }
        }
    }

    for (size_t i = clipIdxCurrentlyInClipBuffer + 1; i < clipStackHeight; ++i)
    {
        ClipElement& clip = m_clipStack[i];
        assert(clip.pathBounds == clip.path->getBounds());

        IAABB clipDrawBounds;
        {
            PLSPaint clipUpdatePaint;
            clipUpdatePaint.clipUpdate(/*clip THIS clipDraw against:*/ lastClipID);
            auto clipDraw = PLSPathDraw::Make(m_context,
                                              clip.matrix,
                                              clip.path,
                                              clip.fillRule,
                                              &clipUpdatePaint,
                                              &m_scratchPath);
            clipDrawBounds = clipDraw->pixelBounds();
            // Generate a new clipID every time we (re-)render an element to the clip buffer.
            // (Each embodiment of the element needs its own separate readBounds.)
            clip.clipID = m_context->generateClipID(clipDrawBounds);
            assert(clip.clipID != m_context->getClipContentID());
            if (clip.clipID == 0)
            {
                return false; // The context is out of clipIDs. We will flush and try again.
            }
            clipDraw->setClipID(clip.clipID);
            if (!m_context->isOutsideCurrentFrame(clipDrawBounds))
            {
                m_internalDrawBatch.push_back(std::move(clipDraw));
            }
        }

        if (lastClipID != 0)
        {
            m_context->addClipReadBounds(lastClipID, clipDrawBounds);
            if (m_context->frameInterlockMode() == pls::InterlockMode::depthStencil)
            {
                // When drawing nested stencil clips, we need to intersect them, which involves
                // erasing the region of the current clip in the stencil buffer that is outside the
                // the one we just drew.
                auto stencilClipIntersect = PLSDrawUniquePtr(m_context->make<StencilClipReset>(
                    m_context,
                    lastClipID,
                    StencilClipReset::ResetAction::intersectPreviousClip));
                if (!m_context->isOutsideCurrentFrame(stencilClipIntersect->pixelBounds()))
                {
                    m_internalDrawBatch.push_back(std::move(stencilClipIntersect));
                }
            }
        }

        lastClipID = clip.clipID; // Nest the next clip (if any) inside the one we just rendered.
    }
    assert(lastClipID == m_clipStack[clipStackHeight - 1].clipID);
    draw->setClipID(lastClipID);
    m_context->addClipReadBounds(lastClipID, draw->pixelBounds());
    m_context->setClipContentID(lastClipID);
    return true;
}
} // namespace rive::pls
