#ifdef RIVE_WASM_MODULE
// In-module implementations of the abstract render interfaces the bindings
// call through: geometry stays in module memory as RawPath and syncs to the
// host lazily; every native contact is a u32 handle crossing a rive_*_v1
// import. Compiled only into the script module (never the runtime).
#include "rive/factory.hpp"
#include "rive/math/raw_path.hpp"
#include "rive/renderer.hpp"
#include "rive/wasm/module_render.hpp"
#include "rive/wasm/rive_bindings_v1.h"

#include <stdio.h>

using namespace rive;

namespace
{

class ModuleRenderPath : public RenderPath
{
public:
    ModuleRenderPath() = default;
    ModuleRenderPath(RawPath& rawPath, FillRule rule) :
        m_rawPath(rawPath), m_fillRule(rule)
    {}
    ~ModuleRenderPath() override
    {
        if (m_handle != 0)
        {
            rive_path_release(m_handle);
        }
    }

    void rewind() override
    {
        m_rawPath.rewind();
        m_dirty = true;
    }
    void fillRule(FillRule value) override
    {
        m_fillRule = value;
        m_dirty = true;
    }
    void addPath(CommandPath* path, const Mat2D& transform) override
    {
        addRenderPath(path->renderPath(), transform);
    }
    void addRenderPath(const RenderPath* path, const Mat2D& transform) override
    {
        auto modulePath = static_cast<const ModuleRenderPath*>(path);
        m_rawPath.addPath(modulePath->m_rawPath, &transform);
        m_dirty = true;
    }
    void moveTo(float x, float y) override
    {
        m_rawPath.moveTo(x, y);
        m_dirty = true;
    }
    void lineTo(float x, float y) override
    {
        m_rawPath.lineTo(x, y);
        m_dirty = true;
    }
    void cubicTo(float ox, float oy, float ix, float iy, float x, float y)
        override
    {
        m_rawPath.cubicTo(ox, oy, ix, iy, x, y);
        m_dirty = true;
    }
    void close() override
    {
        m_rawPath.close();
        m_dirty = true;
    }
    void addRawPath(const RawPath& path) override
    {
        m_rawPath.addPath(path, nullptr);
        m_dirty = true;
    }

    // Pushes geometry to the host when it changed since the last draw.
    uint32_t sync()
    {
        if (m_handle == 0)
        {
            m_handle = rive_path_new();
            m_dirty = true;
        }
        if (m_dirty)
        {
            rive_path_update(m_handle,
                             (const uint8_t*)m_rawPath.verbs().data(),
                             (uint32_t)m_rawPath.verbs().size(),
                             (const float*)m_rawPath.points().data(),
                             (uint32_t)m_rawPath.points().size() * 2,
                             (uint32_t)m_fillRule);
            m_dirty = false;
        }
        return m_handle;
    }

private:
    RawPath m_rawPath;
    FillRule m_fillRule = FillRule::nonZero;
    uint32_t m_handle = 0;
    bool m_dirty = false;
};

class ModuleRenderPaint : public RenderPaint
{
public:
    ModuleRenderPaint() : m_handle(rive_paint_new()) {}
    ~ModuleRenderPaint() override { rive_paint_release(m_handle); }

    void style(RenderPaintStyle value) override
    {
        rive_paint_style(m_handle, (uint32_t)value);
    }
    void color(ColorInt value) override { rive_paint_color(m_handle, value); }
    void thickness(float value) override
    {
        rive_paint_thickness(m_handle, value);
    }
    void join(StrokeJoin value) override
    {
        rive_paint_join(m_handle, (uint32_t)value);
    }
    void cap(StrokeCap value) override
    {
        rive_paint_cap(m_handle, (uint32_t)value);
    }
    void feather(float value) override { rive_paint_feather(m_handle, value); }
    void blendMode(BlendMode value) override
    {
        rive_paint_blend_mode(m_handle, (uint32_t)value);
    }
    void shader(rcp<RenderShader> value) override;
    void invalidateStroke() override {}

    uint32_t handle() const { return m_handle; }

private:
    rcp<RenderShader> m_shader;
    uint32_t m_handle;
};

class ModuleRenderShader : public RenderShader
{
public:
    ModuleRenderShader(uint32_t handle) : m_handle(handle) {}
    ~ModuleRenderShader() override { rive_shader_release(m_handle); }
    uint32_t handle() const { return m_handle; }

private:
    uint32_t m_handle;
};

// Out of line so ModuleRenderShader's handle accessor is visible.
void ModuleRenderPaint::shader(rcp<RenderShader> value)
{
    // Pinned so the host handle outlives the assignment.
    m_shader = value;
    rive_paint_shader(
        m_handle,
        value != nullptr
            ? static_cast<ModuleRenderShader*>(value.get())->handle()
            : 0);
}

// Contents live in module memory and push to the host on unmap.
class ModuleRenderBuffer : public RenderBuffer
{
public:
    ModuleRenderBuffer(RenderBufferType type,
                       RenderBufferFlags flags,
                       size_t sizeInBytes) :
        RenderBuffer(type, flags, sizeInBytes),
        m_handle(rive_buffer_new((uint32_t)type,
                                 (uint32_t)flags,
                                 (uint32_t)sizeInBytes)),
        m_store(new uint8_t[sizeInBytes])
    {}
    ~ModuleRenderBuffer() override
    {
        rive_buffer_release(m_handle);
        delete[] m_store;
    }
    uint32_t handle() const { return m_handle; }

protected:
    void* onMap() override { return m_store; }
    void onUnmap() override
    {
        rive_buffer_update(m_handle, m_store, (uint32_t)sizeInBytes());
    }

private:
    uint32_t m_handle;
    uint8_t* m_store;
};

// Instances live in module memory and push to the host on each edit.
class ModuleImageMeshInstances : public ImageMeshInstances
{
public:
    ModuleImageMeshInstances(size_t count) :
        ImageMeshInstances(count),
        m_handle(rive_mesh_instances_new((uint32_t)count)),
        m_hostCount(count)
    {}
    ~ModuleImageMeshInstances() override
    {
        rive_mesh_instances_release(m_handle);
    }
    uint32_t handle() const { return m_handle; }

protected:
    void onEndEdit() override
    {
        Span<const ImageMeshInstanceData> data = instanceData();
        if (data.size() != m_hostCount)
        {
            rive_mesh_instances_resize(m_handle, (uint32_t)data.size());
            m_hostCount = data.size();
        }
        rive_mesh_instances_update(
            m_handle,
            0,
            reinterpret_cast<const uint8_t*>(data.data()),
            (uint32_t)(data.size() * sizeof(ImageMeshInstanceData)));
    }

private:
    uint32_t m_handle;
    size_t m_hostCount;
};

class ModuleRenderImage : public RenderImage
{
public:
    ModuleRenderImage(uint32_t handle) : m_handle(handle)
    {
        m_Width = (int)rive_image_width(handle);
        m_Height = (int)rive_image_height(handle);
    }
    ~ModuleRenderImage() override { rive_image_release(m_handle); }
    uint32_t handle() const { return m_handle; }

private:
    uint32_t m_handle;
};

class ModuleFactory : public Factory
{
public:
#if defined(RIVE_CANVAS) && defined(RIVE_ORE)
    ore::Context* ore() override { return wasmModuleOreContext(); }
#endif
    rcp<RenderBuffer> makeRenderBuffer(RenderBufferType type,
                                       RenderBufferFlags flags,
                                       size_t sizeInBytes) override
    {
        return make_rcp<ModuleRenderBuffer>(type, flags, sizeInBytes);
    }
    rcp<ImageMeshInstances> makeImageMeshInstances(size_t count) override
    {
        return make_rcp<ModuleImageMeshInstances>(count);
    }
    rcp<RenderShader> makeLinearGradient(float sx,
                                         float sy,
                                         float ex,
                                         float ey,
                                         const ColorInt colors[],
                                         const float stops[],
                                         size_t count) override
    {
        return make_rcp<ModuleRenderShader>(
            rive_shader_linear(sx, sy, ex, ey, colors, stops, (uint32_t)count));
    }
    rcp<RenderShader> makeRadialGradient(float cx,
                                         float cy,
                                         float radius,
                                         const ColorInt colors[],
                                         const float stops[],
                                         size_t count) override
    {
        return make_rcp<ModuleRenderShader>(
            rive_shader_radial(cx, cy, radius, colors, stops, (uint32_t)count));
    }
    rcp<RenderPath> makeRenderPath(RawPath& rawPath, FillRule rule) override
    {
        return make_rcp<ModuleRenderPath>(rawPath, rule);
    }
    rcp<RenderPath> makeEmptyRenderPath() override
    {
        return make_rcp<ModuleRenderPath>();
    }
    rcp<RenderPaint> makeRenderPaint() override
    {
        return make_rcp<ModuleRenderPaint>();
    }
    rcp<RenderImage> decodeImage(Span<const uint8_t>) override
    {
        return nullptr;
    }
};

class ModuleRenderer : public Renderer
{
public:
    ModuleRenderer(uint32_t handle) : m_handle(handle) {}
    void save() override { rive_renderer_save(m_handle); }
    void restore() override { rive_renderer_restore(m_handle); }
    void transform(const Mat2D& transform) override
    {
        rive_renderer_transform(m_handle,
                                transform.xx(),
                                transform.xy(),
                                transform.yx(),
                                transform.yy(),
                                transform.tx(),
                                transform.ty());
    }
    void drawPath(RenderPath* path, RenderPaint* paint) override
    {
        rive_renderer_draw_path(
            m_handle,
            static_cast<ModuleRenderPath*>(path)->sync(),
            static_cast<ModuleRenderPaint*>(paint)->handle());
    }
    void clipPath(RenderPath* path) override
    {
        rive_renderer_clip_path(m_handle,
                                static_cast<ModuleRenderPath*>(path)->sync());
    }
    void drawImage(const RenderImage* image,
                   ImageSampler sampler,
                   BlendMode blend,
                   float opacity) override
    {
        rive_renderer_draw_image(
            m_handle,
            static_cast<const ModuleRenderImage*>(image)->handle(),
            sampler.asKey(),
            (uint32_t)blend,
            opacity);
    }
    void drawImageMesh(const RenderImage* image,
                       ImageSampler sampler,
                       rcp<RenderBuffer> vertices,
                       rcp<RenderBuffer> uvCoords,
                       rcp<RenderBuffer> indices,
                       uint32_t vertexCount,
                       uint32_t indexCount,
                       BlendMode blend,
                       float opacity) override
    {
        rive_renderer_draw_image_mesh(
            m_handle,
            static_cast<const ModuleRenderImage*>(image)->handle(),
            sampler.asKey(),
            static_cast<ModuleRenderBuffer*>(vertices.get())->handle(),
            static_cast<ModuleRenderBuffer*>(uvCoords.get())->handle(),
            static_cast<ModuleRenderBuffer*>(indices.get())->handle(),
            (uint32_t)blend,
            opacity);
    }
    void drawImageMeshInstanced(const RenderImage* image,
                                ImageSampler sampler,
                                rcp<RenderBuffer> vertices,
                                rcp<RenderBuffer> uvCoords,
                                rcp<RenderBuffer> indices,
                                uint32_t vertexCount,
                                uint32_t indexCount,
                                rcp<ImageMeshInstances> instances) override
    {
        rive_renderer_draw_image_mesh_instanced(
            m_handle,
            static_cast<const ModuleRenderImage*>(image)->handle(),
            sampler.asKey(),
            static_cast<ModuleRenderBuffer*>(vertices.get())->handle(),
            static_cast<ModuleRenderBuffer*>(uvCoords.get())->handle(),
            static_cast<ModuleRenderBuffer*>(indices.get())->handle(),
            static_cast<ModuleImageMeshInstances*>(instances.get())->handle());
    }
    void modulateOpacity(float) override {}
    void modulateColor(ColorInt color, bool replace) override
    {
        rive_renderer_modulate_color(m_handle, color, replace);
    }
    uint32_t handle() const { return m_handle; }

private:
    uint32_t m_handle;
};

} // namespace

namespace rive
{
uint32_t wasmModuleImageHandle(RenderImage* image)
{
    return image != nullptr ? static_cast<ModuleRenderImage*>(image)->handle()
                            : 0;
}

Factory* wasmModuleFactory()
{
    static ModuleFactory factory;
    return &factory;
}

std::unique_ptr<Renderer> makeWasmModuleRenderer(uint32_t handle)
{
    return std::make_unique<ModuleRenderer>(handle);
}

uint32_t wasmModuleRendererHandle(Renderer* renderer)
{
    return renderer != nullptr
               ? static_cast<ModuleRenderer*>(renderer)->handle()
               : 0;
}

rcp<RenderImage> makeWasmModuleRenderImage(uint32_t handle)
{
    return make_rcp<ModuleRenderImage>(handle);
}
} // namespace rive

#endif
