#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.hpp"

#include <math.h>
#include <stdio.h>

using namespace rive;

bool ScriptedRenderer::end()
{
    assert(m_renderer != nullptr);
    auto count = m_saveCount;

    while (count)
    {
        m_renderer->restore();
        count--;
    }
    // if (m_saveCount != 0)
    // {
    //     luaL_error(L,
    //                "%s save/restore stack was unbalanced with %i remaining "
    //                "saves to restore.",
    //                ScriptedRenderer::luaName,
    //                m_saveCount);
    // }
    m_renderer = nullptr;
    bool success = m_saveCount == 0;
    m_saveCount = 0;
    return success;
}

void ScriptedRenderer::save(lua_State* L)
{
    validate(L);
    m_renderer->save();
    m_saveCount++;
}

void ScriptedRenderer::restore(lua_State* L)
{
    validate(L);
    if (m_saveCount == 0)
    {
        luaL_error(L,
                   "%s save/restore stack was unbalanced by trying to restore "
                   "more times than saved.",
                   ScriptedRenderer::luaName);
    }
    m_renderer->restore();
    m_saveCount--;
}

void ScriptedRenderer::transform(lua_State* L, const Mat2D& mat2d)
{
    validate(L);
    m_renderer->transform(mat2d);
}

void ScriptedRenderer::clipPath(lua_State* L, ScriptedPath* path)
{
    validate(L);
    m_renderer->clipPath(path->renderPath(L));
}

static int renderer_drawImage(lua_State* L)
{
    auto scriptedRenderer = lua_torive<ScriptedRenderer>(L, 1);
    auto scriptedImage = lua_torive<ScriptedImage>(L, 2);
    auto scriptedSampler = lua_torive<ScriptedImageSampler>(L, 3);
    auto blendMode = lua_toblendmode(L, 4);
    auto opacity = float(luaL_checknumber(L, 5));

    auto renderer = scriptedRenderer->validate(L);
    renderer->drawImage(scriptedImage->image.get(),
                        scriptedSampler->sampler,
                        blendMode,
                        opacity);

    return 0;
}

static int renderer_drawImageMesh(lua_State* L)
{
    auto scriptedRenderer = lua_torive<ScriptedRenderer>(L, 1);
    auto scriptedImage = lua_torive<ScriptedImage>(L, 2);
    auto scriptedSampler = lua_torive<ScriptedImageSampler>(L, 3);
    auto scriptedVertexBuffer = lua_torive<ScriptedVertexBuffer>(L, 4);
    auto scriptedUVBuffer = lua_torive<ScriptedVertexBuffer>(L, 5);
    auto scriptedTriangleBuffer = lua_torive<ScriptedTriangleBuffer>(L, 6);
    auto blendMode = lua_toblendmode(L, 7);
    auto opacity = float(luaL_checknumber(L, 8));

    auto renderer = scriptedRenderer->validate(L);
    renderer->drawImageMesh(scriptedImage->image.get(),
                            scriptedSampler->sampler,
                            scriptedVertexBuffer->vertexBuffer,
                            scriptedUVBuffer->vertexBuffer,
                            scriptedTriangleBuffer->indexBuffer,
                            (uint32_t)scriptedVertexBuffer->values.size(),
                            (uint32_t)scriptedTriangleBuffer->values.size(),
                            blendMode,
                            opacity);

    return 0;
}

Renderer* ScriptedRenderer::validate(lua_State* L)
{
    if (m_renderer == nullptr)
    {
        luaL_error(L, "%s is no longer valid.", ScriptedRenderer::luaName);
    }
    return m_renderer;
}

static int renderer_drawPath(lua_State* L)
{
    auto scriptedRenderer = lua_torive<ScriptedRenderer>(L, 1);
    auto scriptedPath = lua_torive<ScriptedPath>(L, 2);
    auto scriptedPaint = lua_torive<ScriptedPaint>(L, 3);

    auto renderer = scriptedRenderer->validate(L);
    renderer->drawPath(scriptedPath->renderPath(L),
                       scriptedPaint->renderPaint.get());

    return 0;
}

static int renderer_save(lua_State* L)
{
    auto scriptedRenderer = lua_torive<ScriptedRenderer>(L, 1);
    scriptedRenderer->save(L);

    return 0;
}

static int renderer_restore(lua_State* L)
{
    auto scriptedRenderer = lua_torive<ScriptedRenderer>(L, 1);
    scriptedRenderer->restore(L);

    return 0;
}

static int renderer_clip_path(lua_State* L)
{
    auto scriptedRenderer = lua_torive<ScriptedRenderer>(L, 1);
    auto path = lua_torive<ScriptedPath>(L, 2);
    scriptedRenderer->clipPath(L, path);
    return 0;
}

static int renderer_transform(lua_State* L)
{
    auto scriptedRenderer = lua_torive<ScriptedRenderer>(L, 1);
    auto mat2d = lua_torive<ScriptedMat2D>(L, 2);
    scriptedRenderer->transform(L, mat2d->value);
    return 0;
}

static int renderer_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        switch (atom)
        {
            case (int)LuaAtoms::drawPath:
                return renderer_drawPath(L);
            case (int)LuaAtoms::save:
                return renderer_save(L);
            case (int)LuaAtoms::restore:
                return renderer_restore(L);
            case (int)LuaAtoms::clipPath:
                return renderer_clip_path(L);
            case (int)LuaAtoms::transform:
                return renderer_transform(L);
            case (int)LuaAtoms::drawImage:
                return renderer_drawImage(L);
            case (int)LuaAtoms::drawImageMesh:
                return renderer_drawImageMesh(L);
        }
    }

    luaL_error(L,
               "%s is not a valid method of %s",
               str,
               ScriptedRenderer::luaName);
    return 0;
}

int luaopen_rive_renderer(lua_State* L)
{
    lua_register_rive<ScriptedRenderer>(L);

    lua_pushcfunction(L, renderer_namecall, nullptr);
    lua_setfield(L, -2, "__namecall");

    lua_setreadonly(L, -1, true);
    lua_pop(L, 1); // pop the metatable
    return 1;
}

#endif
