#include "fiddle_context.hpp"

#include "rive/pls/pls_factory.hpp"
#include "rive/pls/pls_renderer.hpp"
#include "rive/pls/gl/pls_render_context_gl.hpp"
#include "rive/pls/gl/pls_render_target_gl.hpp"
#include "rive/pls/metal/pls_render_context_metal.h"
#include "rive/pls/metal/pls_render_target_metal.h"
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>

#define GLFW_INCLUDE_NONE
#define GLFW_EXPOSE_NATIVE_COCOA
#include "GLFW/glfw3.h"
#include <GLFW/glfw3native.h>

using namespace rive;
using namespace rive::pls;

class FiddleContextMetalPLS : public FiddleContext
{
public:
    FiddleContextMetalPLS() { printf("==== MTLDevice: %s ====\n", m_gpu.name.UTF8String); }

    float dpiScale() const override
    {
        NSWindow* nsWindow = glfwGetCocoaWindow(g_window);
        return nsWindow.screen.backingScaleFactor;
    }

    std::unique_ptr<Factory> makeFactory() override { return std::make_unique<PLSFactory>(); }

    void onSizeChanged(int width, int height) override
    {
        NSWindow* nsWindow = glfwGetCocoaWindow(g_window);
        nsWindow.contentView.wantsLayer = YES;
        float backingScaleFactor = [[nsWindow screen] backingScaleFactor];

        m_swapchain = [CAMetalLayer layer];
        m_swapchain.device = m_gpu;
        m_swapchain.opaque = YES;
        m_swapchain.framebufferOnly = YES;
        m_swapchain.pixelFormat = MTLPixelFormatBGRA8Unorm;
        m_swapchain.contentsScale = backingScaleFactor;
        m_swapchain.displaySyncEnabled = NO;
        nsWindow.contentView.layer = m_swapchain;

        m_renderTarget = m_plsContext->makeRenderTarget(MTLPixelFormatBGRA8Unorm, width, height);
    }

    void toggleZoomWindow() override {}

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

    void begin() override
    {
        m_surface = [m_swapchain nextDrawable];
        m_renderTarget->setTargetTexture(m_surface.texture);

        PLSRenderContext::FrameDescriptor frameDescriptor;
        frameDescriptor.renderTarget = m_renderTarget;
        frameDescriptor.clearColor = 0xff404040;
        frameDescriptor.wireframe = g_wireframe;
        frameDescriptor.fillsDisabled = g_disableFill;
        frameDescriptor.strokesDisabled = g_disableStroke;
        m_plsContext->beginFrame(std::move(frameDescriptor));
    }

    void end() override
    {
        m_plsContext->flush();

        id<MTLCommandBuffer> commandBuffer = [m_queue commandBuffer];
        [commandBuffer presentDrawable:m_surface];
        [commandBuffer commit];
    }

    void shrinkGPUResourcesToFit() final { m_plsContext->shrinkGPUResourcesToFit(); }

private:
    id<MTLDevice> m_gpu = MTLCreateSystemDefaultDevice();
    id<MTLCommandQueue> m_queue = [m_gpu newCommandQueue];
    id<CAMetalDrawable> m_surface = nil;
    std::unique_ptr<PLSRenderContextMetal> m_plsContext =
        PLSRenderContextMetal::Make(m_gpu, m_queue);
    CAMetalLayer* m_swapchain;
    rcp<PLSRenderTargetMetal> m_renderTarget;
};

std::unique_ptr<FiddleContext> FiddleContext::MakeMetalPLS()
{
    return std::make_unique<FiddleContextMetalPLS>();
}
