/*
 * Copyright 2024 Rive
 */

#include "gm.hpp"
#include "gmutils.hpp"
#include "common/testing_window.hpp"
#include "common/offscreen_render_target.hpp"
#include "rive/renderer/render_context.hpp"
#include "rive/renderer/rive_renderer.hpp"

#ifdef RIVE_TOOLS_NO_GL
using GLuint = uint32_t;
#else
#include "rive/renderer/gl/render_context_gl_impl.hpp"
#include "rive/renderer/gl/render_target_gl.hpp"
#endif

#include "assets/nomoon.png.hpp"

using namespace rivegm;
using namespace rive;
using namespace rive::gpu;

// Most gms render directly to the framebuffer. This GM checks that texture
// targets work in GL.
class OffscreenRenderTarget : public GM
{
public:
    OffscreenRenderTarget(BlendMode blendMode,
                          bool riveRenderable,
                          ColorInt clearColor = 0xffff00ff) :
        GM(256, 256),
        m_blendMode(blendMode),
        m_riveRenderable(riveRenderable),
        m_clearColor(clearColor)
    {}

    ColorInt clearColor() const override { return 0xffff0000; }

    void onDraw(rive::Renderer* originalRenderer) override
    {
        if (rcp<rive_tests::OffscreenRenderTarget> renderImageTarget =
                TestingWindow::Get()
                    ->makeOffscreenRenderTarget(256, 256, m_riveRenderable))
        {
            // Intercept the current frameDescriptor and end the PLS frame.
            auto renderContext = TestingWindow::Get()->renderContext();
            auto originalFrameDescriptor = renderContext->frameDescriptor();
            TestingWindow::Get()->flushPLSContext();

            // Draw to the offscreen texture. Declare the frame dimensions
            // explicitly so Rive sizes its PLS buffers for the 256x256
            // offscreen render target we are about to flush into — otherwise,
            // on backends where the testing window's main frame descriptor is
            // larger than the logical GM size (e.g. wagyu where the surface
            // exceeds 256x256), the later flushPLSContext(renderImageTarget)
            // call trips the flushResources.renderTarget->width() ==
            // m_frameDescriptor.renderTargetWidth assertion in
            // RenderContext::flush.
            auto textureFrameDescriptor = originalFrameDescriptor;
            textureFrameDescriptor.renderTargetWidth = 256;
            textureFrameDescriptor.renderTargetHeight = 256;
            textureFrameDescriptor.clearColor = m_clearColor;
            renderContext->beginFrame(std::move(textureFrameDescriptor));
            RiveRenderer renderer(renderContext);
            drawInternal(&renderer, renderImageTarget->asRenderTarget());
            TestingWindow::Get()->flushPLSContext(
                renderImageTarget->asRenderTarget());

            // Copy the offscreen texture back to the destination framebuffer.
            RenderImage* renderImage = renderImageTarget->asRenderImage();
            auto copyFrameDescriptor = originalFrameDescriptor;
            copyFrameDescriptor.loadAction =
                gpu::LoadAction::preserveRenderTarget;
            copyFrameDescriptor.clearColor = 0xffff0000;
            renderContext->beginFrame(std::move(copyFrameDescriptor));
            renderer.save();
            if (renderContext->platformFeatures().framebufferBottomUp)
            {
                renderer.translate(0, 256);
                renderer.scale(1, -1);
            }
            renderer.drawImage(renderImage,
                               {.filter = ImageFilter::nearest},
                               BlendMode::srcOver,
                               1);
            renderer.restore();
        }
        else
        {
            drawInternal(originalRenderer, nullptr);
        }
    }

    virtual void drawInternal(Renderer* renderer, RenderTarget*)
    {
        Paint paint5(0x8000ffff);
        paint5->blendMode(m_blendMode);
        drawStar5(renderer, paint5);

        Paint paint13(0x80ffff00);
        paint13->blendMode(m_blendMode);
        drawStar13(renderer, paint13);
    }

    void drawStar5(Renderer* renderer,
                   RenderPaint* paint,
                   FillRule fillRule = FillRule::nonZero)
    {
        PathBuilder builder;
        float theta = -math::PI / 7;
        builder.moveTo(cosf(theta), sinf(theta));
        for (int i = 0; i <= 7; ++i)
        {
            theta += 2 * math::PI * 2 / 7;
            builder.lineTo(cosf(theta), sinf(theta));
        }
        builder.fillRule(fillRule);
        renderer->save();
        renderer->translate(100, 100);
        renderer->scale(80, 80);
        renderer->drawPath(builder.detach(), paint);
        renderer->restore();
    }

    void drawStar13(Renderer* renderer,
                    RenderPaint* paint,
                    FillRule fillRule = FillRule::evenOdd)
    {
        PathBuilder builder;
        float theta = 0;
        for (int i = 0; i <= 13; ++i)
        {
            theta += 2 * math::PI * 3 / 13;
            builder.lineTo(cosf(theta), sinf(theta));
        }
        builder.fillRule(fillRule);
        renderer->save();
        renderer->translate(256 - 100, 256 - 100);
        renderer->scale(80, 80);
        renderer->drawPath(builder.detach(), paint);
        renderer->restore();
    }

protected:
    const BlendMode m_blendMode;
    const bool m_riveRenderable;
    const ColorInt m_clearColor;
};

GMREGISTER(offscreen_render_target,
           return new OffscreenRenderTarget(BlendMode::srcOver, true))
GMREGISTER(offscreen_render_target_nonrenderable,
           return new OffscreenRenderTarget(BlendMode::srcOver, false))
GMREGISTER(offscreen_render_target_lum,
           return new OffscreenRenderTarget(BlendMode::luminosity, true))
GMREGISTER(offscreen_render_target_lum_nonrenderable,
           return new OffscreenRenderTarget(BlendMode::luminosity, false))

GMREGISTER(offscreen_render_target_transparent_clear,
           return new OffscreenRenderTarget(BlendMode::srcOver,
                                            true,
                                            0x7fff00ff))
GMREGISTER(offscreen_render_target_nonrenderable_transparent_clear,
           return new OffscreenRenderTarget(BlendMode::srcOver,
                                            false,
                                            0x7fff00ff))
GMREGISTER(offscreen_render_target_lum_transparent_clear,
           return new OffscreenRenderTarget(BlendMode::luminosity,
                                            true,
                                            0x7fff00ff))
GMREGISTER(offscreen_render_target_lum_nonrenderable_transparent_clear,
           return new OffscreenRenderTarget(BlendMode::luminosity,
                                            false,
                                            0x7fff00ff))

// This GM checks that texture targets (including MSAA targets) work with
// LoadAction::preserveRenderTarget.
class OffscreenRenderTargetPreserve : public OffscreenRenderTarget
{
public:
    OffscreenRenderTargetPreserve(BlendMode blendMode, bool riveRenderable) :
        OffscreenRenderTarget(blendMode, riveRenderable)
    {}
    OffscreenRenderTargetPreserve(bool riveRenderable) :
        OffscreenRenderTargetPreserve(BlendMode::srcOver, riveRenderable)
    {}

    virtual void drawInternal(Renderer* renderer, RenderTarget* renderTarget)
    {
        ColorInt colors[2];
        float stops[2];
        colors[0] = 0xff000000;
        stops[0] = 0;
        colors[1] = 0xffff00ff;
        stops[1] = 1;
        Paint paint;
        paint->shader(TestingWindow::Get()
                          ->factory()
                          ->makeLinearGradient(0, 0, 250, 0, colors, stops, 2));
        renderer->drawPath(PathBuilder::Rect({0, 0, 256, 256}), paint);

        colors[0] = 0x80000000;
        stops[0] = 0;
        colors[1] = 0x8000ffff;
        stops[1] = 1;
        Paint paint2;
        paint2->shader(
            TestingWindow::Get()
                ->factory()
                ->makeLinearGradient(0, 0, 0, 250, colors, stops, 2));
        renderer->drawPath(PathBuilder::Rect({0, 0, 256, 256}), paint2);

        if (auto renderContext = TestingWindow::Get()->renderContext())
        {
            auto frameDescriptor = renderContext->frameDescriptor();
#ifndef RIVE_TOOLS_NO_GL
            if (auto plsImplGL = TestingWindow::Get()->renderContextGLImpl())
            {
                assert(renderTarget);
                TestingWindow::Get()->flushPLSContext(renderTarget);
                if (int sampleCount = frameDescriptor.msaaSampleCount)
                {
                    // If the MSAA framebuffer target is not the target texture,
                    // wipe it to red behind the scenes in order to make sure
                    // our preservation codepath works. (It shouldn't appear red
                    // in the end -- this should get preserved instead.)
                    if (!plsImplGL->capabilities()
                             .EXT_multisampled_render_to_texture)
                    {
                        auto renderTextureTargetGL =
                            static_cast<RenderTargetGL*>(renderTarget);
                        renderTextureTargetGL
                            ->bindFramebufferForDepthStencilMode(plsImplGL,
                                                                 sampleCount,
                                                                 nullptr,
                                                                 nullptr);
                        glClearColor(1, 0, 0, 1);
                        glClear(GL_COLOR_BUFFER_BIT);
                    }
                }
            }
            else
#endif
            {
                TestingWindow::Get()->flushPLSContext(renderTarget);
            }
            frameDescriptor.loadAction = gpu::LoadAction::preserveRenderTarget;
            renderContext->beginFrame(std::move(frameDescriptor));
        }
        Paint paint5(0x8000ffff);
        paint5->blendMode(m_blendMode);
        drawStar5(renderer, paint5);

        if (auto renderContext = TestingWindow::Get()->renderContext())
        {
            auto frameDescriptor = renderContext->frameDescriptor();
#ifndef RIVE_TOOLS_NO_GL
            if (auto plsImplGL = TestingWindow::Get()->renderContextGLImpl())
            {
                assert(renderTarget);
                TestingWindow::Get()->flushPLSContext(renderTarget);
                if (int sampleCount = frameDescriptor.msaaSampleCount)
                {
                    // If the MSAA framebuffer target is not the target texture,
                    // wipe it to red behind the scenes in order to make sure
                    // our preservation codepath works. (It shouldn't appear red
                    // in the end -- this should get preserved instead.)
                    if (!plsImplGL->capabilities()
                             .EXT_multisampled_render_to_texture)
                    {
                        auto renderTextureTargetGL =
                            static_cast<RenderTargetGL*>(renderTarget);
                        renderTextureTargetGL
                            ->bindFramebufferForDepthStencilMode(plsImplGL,
                                                                 sampleCount,
                                                                 nullptr,
                                                                 nullptr);
                        glClearColor(1, 0, 0, 1);
                        glClear(GL_COLOR_BUFFER_BIT);
                    }
                }
            }
            else
#endif
            {
                TestingWindow::Get()->flushPLSContext(renderTarget);
            }
            frameDescriptor.loadAction = gpu::LoadAction::preserveRenderTarget;
            renderContext->beginFrame(std::move(frameDescriptor));
        }
        Paint paint13(0x80ffff00);
        paint13->blendMode(m_blendMode);
        drawStar13(renderer, paint13);
    }
};
GMREGISTER(offscreen_render_target_preserve,
           return new OffscreenRenderTargetPreserve(true))
GMREGISTER(offscreen_render_target_preserve_nonrenderable,
           return new OffscreenRenderTargetPreserve(false))

// ...And verify that blend modes work on a texture target.
class OffscreenRenderTargetPreserveLum : public OffscreenRenderTargetPreserve
{
public:
    OffscreenRenderTargetPreserveLum(bool riveRenderable) :
        OffscreenRenderTargetPreserve(BlendMode::luminosity, riveRenderable)
    {}
};
GMREGISTER(offscreen_render_target_preserve_lum,
           return new OffscreenRenderTargetPreserveLum(true))
GMREGISTER(offscreen_render_target_preserve_lum_nonrenderable,
           return new OffscreenRenderTargetPreserveLum(false))

// This GM checks that virtual tiles work with various types of render targets.
class OffscreenVirtualTiles : public OffscreenRenderTarget
{
public:
    OffscreenVirtualTiles(gpu::LoadAction loadAction, BlendMode blendMode) :
        OffscreenRenderTarget(blendMode, /*riveRenderable=*/false),
        m_loadAction(loadAction)
    {}

    virtual void drawInternal(Renderer* renderer, RenderTarget* renderTarget)
    {
        ColorInt colors[2];
        float stops[2];
        colors[0] = 0xff000000;
        stops[0] = 0;
        colors[1] = 0xffff00ff;
        stops[1] = 1;
        Paint paint;
        paint->shader(TestingWindow::Get()
                          ->factory()
                          ->makeLinearGradient(0, 0, 250, 0, colors, stops, 2));
        renderer->drawPath(PathBuilder::Rect({0, 0, 256, 256}), paint);

        colors[0] = 0x80000000;
        stops[0] = 0;
        colors[1] = 0x8000ffff;
        stops[1] = 1;
        Paint paint2;
        paint2->shader(
            TestingWindow::Get()
                ->factory()
                ->makeLinearGradient(0, 0, 0, 250, colors, stops, 2));
        renderer->drawPath(PathBuilder::Rect({0, 0, 256, 256}), paint2);

        if (auto renderContext = TestingWindow::Get()->renderContext())
        {
            auto frameDescriptor = renderContext->frameDescriptor();
            TestingWindow::Get()->flushPLSContext(renderTarget);
            frameDescriptor.loadAction = m_loadAction;
            frameDescriptor.virtualTileWidth = 37;
            frameDescriptor.virtualTileHeight = 23;
            renderContext->beginFrame(std::move(frameDescriptor));
        }

        Path largePathThatUsesInteriorTriangles;
        Paint transWhite;
        transWhite->color(0x80ffffff);
        transWhite->blendMode(m_blendMode);
        largePathThatUsesInteriorTriangles->addRect(0, 0, 1000, 1000);
        renderer->drawPath(largePathThatUsesInteriorTriangles.get(),
                           transWhite.get());

        Paint paint5(0x8000ffff);
        paint5->blendMode(m_blendMode);
        drawStar5(renderer, paint5, FillRule::clockwise);

        auto img = LoadImage(assets::nomoon_png());

        {
            AutoRestore ar(renderer, true);
            renderer->translate(100, 30);
            renderer->scale(.4f, .4f);
            renderer->drawImage(img.get(),
                                ImageSampler::LinearClamp(),
                                m_blendMode,
                                .5f);
        }

        {
            Factory* factory = TestingWindow::Get()->factory();
            auto pts = factory->makeRenderBuffer(
                RenderBufferType::vertex,
                RenderBufferFlags::mappedOnceAtInitialization,
                4 * sizeof(Vec2D));
            memcpy(pts->map(),
                   std::array<Vec2D, 4>{Vec2D{110, 110},
                                        Vec2D{200, 110},
                                        Vec2D{10, 200},
                                        Vec2D{270, 270}}
                       .data(),
                   pts->sizeInBytes());
            pts->unmap();
            auto uvs = factory->makeRenderBuffer(
                RenderBufferType::vertex,
                RenderBufferFlags::mappedOnceAtInitialization,
                4 * sizeof(Vec2D));
            memcpy(uvs->map(),
                   std::array<Vec2D, 4>{Vec2D{0, 0},
                                        Vec2D{1, 0},
                                        Vec2D{0, 1},
                                        Vec2D{1, 1}}
                       .data(),
                   uvs->sizeInBytes());
            uvs->unmap();
            auto indices = factory->makeRenderBuffer(
                RenderBufferType::index,
                RenderBufferFlags::mappedOnceAtInitialization,
                6 * sizeof(uint16_t));
            memcpy(indices->map(),
                   std::array<uint16_t, 6>{0, 1, 2, 1, 2, 3}.data(),
                   indices->sizeInBytes());
            indices->unmap();
            renderer->drawImageMesh(img.get(),
                                    ImageSampler::LinearClamp(),
                                    pts,
                                    uvs,
                                    indices,
                                    4,
                                    6,
                                    m_blendMode,
                                    .7f);
        }

        Paint paint13(0x80ffff00);
        paint13->blendMode(m_blendMode);
        paint13->feather(1);
        drawStar13(renderer, paint13, FillRule::clockwise);

        Paint white(0xffffffff);
        paint13->blendMode(m_blendMode);
        uint64_t lcg = 12789;
        for (size_t i = 0; i < 2000; ++i)
        {
            AutoRestore ar(renderer, true);
            renderer->translate(lcg & 0xff, (lcg >> 8) & 0xff);
            renderer->scale(.01f, .01f);
            drawStar5(renderer, white, FillRule::clockwise);
            lcg = lcg * 6364136223846793005ULL + 1;
        }
    }

private:
    const gpu::LoadAction m_loadAction;
};
GMREGISTER(offscreen_virtual_tiles_nonrenderable,
           return new OffscreenVirtualTiles(gpu::LoadAction::clear,
                                            BlendMode::srcOver))
GMREGISTER(
    offscreen_virtual_tiles_preserve_nonrenderable,
    return new OffscreenVirtualTiles(gpu::LoadAction::preserveRenderTarget,
                                     BlendMode::srcOver))
GMREGISTER(offscreen_virtual_tiles_lum_nonrenderable,
           return new OffscreenVirtualTiles(gpu::LoadAction::clear,
                                            BlendMode::luminosity))
GMREGISTER(
    offscreen_virtual_tiles_preserve_lum_nonrenderable,
    return new OffscreenVirtualTiles(gpu::LoadAction::preserveRenderTarget,
                                     BlendMode::luminosity))
