#include "fiddle_context.hpp"

#ifndef RIVE_DESKTOP_GL

std::unique_ptr<FiddleContext> FiddleContext::MakeGLPLS() { return nullptr; }

#else

#include "path_fiddle.hpp"
#include "rive/pls/gl/gles3.hpp"
#include "rive/pls/pls_renderer.hpp"
#include "rive/pls/gl/pls_render_context_gl_impl.hpp"
#include "rive/pls/gl/pls_render_target_gl.hpp"

#ifdef RIVE_WEBGL
#include <emscripten/emscripten.h>
#include <emscripten/html5.h>
#endif

#define GLFW_INCLUDE_NONE
#include "GLFW/glfw3.h"

using namespace rive;
using namespace rive::pls;

#ifdef RIVE_DESKTOP_GL
#ifdef DEBUG
static void GLAPIENTRY err_msg_callback(GLenum source,
                                        GLenum type,
                                        GLuint id,
                                        GLenum severity,
                                        GLsizei length,
                                        const GLchar* message,
                                        const void* userParam)
{
    if (type == GL_DEBUG_TYPE_ERROR)
    {
        printf("GL ERROR: %s\n", message);
        fflush(stdout);
        // Don't abort if it's a shader compile error; let our internal handlers print the source
        // (for debugging) and exit on their own.
        if (!strstr(message, "SHADER_ID_COMPILE error has been generated"))
        {
            assert(0);
        }
    }
    else if (type == GL_DEBUG_TYPE_PERFORMANCE)
    {
        if (strcmp(message,
                   "API_ID_REDUNDANT_FBO performance warning has been generated. Redundant state "
                   "change in glBindFramebuffer API call, FBO 0, \"\", already bound.") == 0)
        {
            return;
        }
        if (strstr(message, "is being recompiled based on GL state."))
        {
            return;
        }
        printf("GL PERF: %s\n", message);
        fflush(stdout);
    }
}
#endif
#endif

class FiddleContextGL : public FiddleContext
{
public:
    FiddleContextGL()
    {
#ifdef RIVE_DESKTOP_GL
        // Load the OpenGL API using glad.
        if (!gladLoadCustomLoader((GLADloadproc)glfwGetProcAddress))
        {
            fprintf(stderr, "Failed to initialize glad.\n");
            abort();
        }
#endif

        printf("GL_VENDOR: %s\n", glGetString(GL_VENDOR));
        printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
        printf("GL_VERSION: %s\n", glGetString(GL_VERSION));
#ifdef RIVE_DESKTOP_GL
        printf("GL_ANGLE_shader_pixel_local_storage_coherent: %i\n",
               GLAD_GL_ANGLE_shader_pixel_local_storage_coherent);
#endif
#if 0
        int n;
        glGetIntegerv(GL_NUM_EXTENSIONS, &n);
        for (size_t i = 0; i < n; ++i)
        {
            printf("  %s\n", glGetStringi(GL_EXTENSIONS, i));
        }
#endif

#ifdef RIVE_DESKTOP_GL
#ifdef DEBUG
        if (GLAD_GL_KHR_debug)
        {
            glEnable(GL_DEBUG_OUTPUT);
            glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
            glDebugMessageCallbackKHR(&err_msg_callback, nullptr);
        }
#endif
#endif
    }

    ~FiddleContextGL() { glDeleteFramebuffers(1, &m_zoomWindowFBO); }

    float dpiScale(GLFWwindow*) const override
    {
#ifdef __APPLE__
        return 2;
#else
        return 1;
#endif
    }

    void toggleZoomWindow() final
    {
        if (m_zoomWindowFBO)
        {
            glDeleteFramebuffers(1, &m_zoomWindowFBO);
            m_zoomWindowFBO = 0;
        }
        else
        {
            GLuint tex;
            glGenTextures(1, &tex);
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, tex);
            glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, kZoomWindowWidth, kZoomWindowHeight);

            glGenFramebuffers(1, &m_zoomWindowFBO);
            glBindFramebuffer(GL_FRAMEBUFFER, m_zoomWindowFBO);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
            glBindFramebuffer(GL_FRAMEBUFFER, 0);

            glDeleteTextures(1, &tex);
        }
    }

    void end(GLFWwindow* window, std::vector<uint8_t>* pixelData) final
    {
        assert(pixelData == nullptr); // Not implemented yet.
        onEnd();
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        if (m_zoomWindowFBO)
        {
            // Blit the zoom window.
            double xd, yd;
            glfwGetCursorPos(window, &xd, &yd);
            xd *= dpiScale(window);
            yd *= dpiScale(window);
            int width = 0, height = 0;
            glfwGetFramebufferSize(window, &width, &height);
            int x = xd, y = height - yd;
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_zoomWindowFBO);
            glBlitFramebuffer(x - kZoomWindowWidth / 2,
                              y - kZoomWindowHeight / 2,
                              x + kZoomWindowWidth / 2,
                              y + kZoomWindowHeight / 2,
                              0,
                              0,
                              kZoomWindowWidth,
                              kZoomWindowHeight,
                              GL_COLOR_BUFFER_BIT,
                              GL_NEAREST);
            glBindFramebuffer(GL_FRAMEBUFFER, 0);

            glEnable(GL_SCISSOR_TEST);
            glScissor(0,
                      0,
                      kZoomWindowWidth * kZoomWindowScale + 2,
                      kZoomWindowHeight * kZoomWindowScale + 2);
            glClearColor(.6, .6, .6, 1);
            glClear(GL_COLOR_BUFFER_BIT);
            glBindFramebuffer(GL_READ_FRAMEBUFFER, m_zoomWindowFBO);
            glBlitFramebuffer(0,
                              0,
                              kZoomWindowWidth,
                              kZoomWindowHeight,
                              0,
                              0,
                              kZoomWindowWidth * kZoomWindowScale,
                              kZoomWindowHeight * kZoomWindowScale,
                              GL_COLOR_BUFFER_BIT,
                              GL_NEAREST);
            glDisable(GL_SCISSOR_TEST);
        }
    }

protected:
    virtual void onEnd() = 0;

private:
    GLuint m_zoomWindowFBO = 0;
};

class FiddleContextGLPLS : public FiddleContextGL
{
public:
    FiddleContextGLPLS()
    {
        if (!m_plsContext)
        {
            fprintf(stderr, "Failed to create a PLS renderer.\n");
            abort();
        }
    }

    rive::Factory* factory() override { return m_plsContext.get(); }

    rive::pls::PLSRenderContext* plsContextOrNull() override { return m_plsContext.get(); }

    rive::pls::PLSRenderTarget* plsRenderTargetOrNull() override { return m_renderTarget.get(); }

    void onSizeChanged(GLFWwindow* window, int width, int height, uint32_t sampleCount) override
    {
        m_renderTarget = make_rcp<FramebufferRenderTargetGL>(width, height, 0, sampleCount);
    }

    std::unique_ptr<Renderer> makeRenderer(int width, int height) override
    {
        return std::make_unique<PLSRenderer>(m_plsContext.get());
    }

    void begin(const PLSRenderContext::FrameDescriptor& frameDescriptor) override
    {
        m_plsContext->static_impl_cast<PLSRenderContextGLImpl>()->invalidateGLState();
        m_plsContext->beginFrame(frameDescriptor);
    }

    void onEnd() override
    {
        flushPLSContext();
        m_plsContext->static_impl_cast<PLSRenderContextGLImpl>()->unbindGLInternalResources();
    }

    void flushPLSContext() override { m_plsContext->flush({.renderTarget = m_renderTarget.get()}); }

private:
    std::unique_ptr<PLSRenderContext> m_plsContext =
        PLSRenderContextGLImpl::MakeContext(PLSRenderContextGLImpl::ContextOptions());
    rcp<PLSRenderTargetGL> m_renderTarget;
};

std::unique_ptr<FiddleContext> FiddleContext::MakeGLPLS()
{
    return std::make_unique<FiddleContextGLPLS>();
}

#endif

#ifndef RIVE_SKIA

std::unique_ptr<FiddleContext> FiddleContext::MakeGLSkia() { return nullptr; }

#else

#include "skia_factory.hpp"
#include "skia_renderer.hpp"
#include "skia/include/core/SkCanvas.h"
#include "skia/include/core/SkSurface.h"
#include "skia/include/gpu/GrDirectContext.h"
#include "skia/include/gpu/gl/GrGLAssembleInterface.h"
#include "skia/include/gpu/gl/GrGLInterface.h"
#include "include/effects/SkImageFilters.h"

static GrGLFuncPtr get_skia_gl_proc_address(void* ctx, const char name[])
{
    return glfwGetProcAddress(name);
}

class FiddleContextGLSkia : public FiddleContextGL
{
public:
    FiddleContextGLSkia() :
        m_grContext(
            GrDirectContext::MakeGL(GrGLMakeAssembledInterface(nullptr, get_skia_gl_proc_address)))
    {
        if (!m_grContext)
        {
            fprintf(stderr, "GrDirectContext::MakeGL failed.\n");
            abort();
        }
    }

    rive::Factory* factory() override { return &m_factory; }

    rive::pls::PLSRenderContext* plsContextOrNull() override { return nullptr; }

    rive::pls::PLSRenderTarget* plsRenderTargetOrNull() override { return nullptr; }

    std::unique_ptr<Renderer> makeRenderer(int width, int height) override
    {
        GrBackendRenderTarget backendRT(width,
                                        height,
                                        1 /*samples*/,
                                        0 /*stencilBits*/,
                                        {0 /*fbo 0*/, GL_RGBA8});

        SkSurfaceProps surfProps(0, kUnknown_SkPixelGeometry);

        m_skSurface = SkSurface::MakeFromBackendRenderTarget(m_grContext.get(),
                                                             backendRT,
                                                             kBottomLeft_GrSurfaceOrigin,
                                                             kRGBA_8888_SkColorType,
                                                             nullptr,
                                                             &surfProps);
        if (!m_skSurface)
        {
            fprintf(stderr, "SkSurface::MakeFromBackendRenderTarget failed.\n");
            abort();
        }
        return std::make_unique<SkiaRenderer>(m_skSurface->getCanvas());
    }

    void begin(const PLSRenderContext::FrameDescriptor& frameDescriptor) override
    {
        m_skSurface->getCanvas()->clear(frameDescriptor.clearColor);
        m_grContext->resetContext();
        m_skSurface->getCanvas()->save();
    }

    void onEnd() override
    {
        m_skSurface->getCanvas()->restore();
        m_skSurface->flush();
    }

    void flushPLSContext() override {}

private:
    SkiaFactory m_factory;
    const sk_sp<GrDirectContext> m_grContext;
    sk_sp<SkSurface> m_skSurface;
};

std::unique_ptr<FiddleContext> FiddleContext::MakeGLSkia()
{
    return std::make_unique<FiddleContextGLSkia>();
}

#endif
