#ifdef WITH_RIVE_SCRIPTING
#include "lua.h"
#include "rive/renderer.hpp"
#include "rive/rive_types.hpp"
#include "rive/shapes/paint/blend_mode.hpp"
#include "rive/shapes/paint/fill.hpp"
#include "rive/shapes/paint/stroke.hpp"
#include "rive/shapes/paint/solid_color.hpp"
#include "rive/shapes/paint/feather.hpp"
#include "lualib.h"
#include "rive/lua/rive_lua_libs.hpp"
#include "rive/factory.hpp"

using namespace rive;

static void readStyle(lua_State* L, ScriptedPaint* paint, int index)
{
    int atom;
    const char* styleName = lua_tostringatom(L, index, &atom);
    if (!styleName)
    {
        luaL_typeerrorL(L, index, lua_typename(L, LUA_TSTRING));
    }
    switch (atom)
    {
        case (int)LuaAtoms::stroke:
            paint->style(RenderPaintStyle::stroke);
            break;
        case (int)LuaAtoms::fill:
            paint->style(RenderPaintStyle::fill);
            break;
        default:
            luaL_error(L, "'%s' is not a valid PaintStyle", styleName);
            break;
    }
}

static void readJoin(lua_State* L, ScriptedPaint* paint, int index)
{
    int atom;
    const char* joinName = lua_tostringatom(L, index, &atom);
    if (!joinName)
    {
        luaL_typeerrorL(L, index, lua_typename(L, LUA_TSTRING));
    }
    switch (atom)
    {
        case (int)LuaAtoms::miter:
            paint->join(StrokeJoin::miter);
            break;
        case (int)LuaAtoms::round:
            paint->join(StrokeJoin::round);
            break;
        case (int)LuaAtoms::bevel:
            paint->join(StrokeJoin::bevel);
            break;
        default:
            luaL_error(L, "'%s' is not a valid StrokeJoin", joinName);
            break;
    }
}

static void readCap(lua_State* L, ScriptedPaint* paint, int index)
{
    int atom;
    const char* capName = lua_tostringatom(L, index, &atom);
    if (!capName)
    {
        luaL_typeerrorL(L, index, lua_typename(L, LUA_TSTRING));
    }
    switch (atom)
    {
        case (int)LuaAtoms::butt:
            paint->cap(StrokeCap::butt);
            break;
        case (int)LuaAtoms::round:
            paint->cap(StrokeCap::round);
            break;
        case (int)LuaAtoms::square:
            paint->cap(StrokeCap::square);
            break;
        default:
            luaL_error(L, "'%s' is not a valid StrokeCap", capName);
            break;
    }
}

BlendMode rive::lua_toblendmode(lua_State* L, int idx)
{
    int atom;
    const char* blendName = lua_tostringatom(L, idx, &atom);
    if (!blendName)
    {
        luaL_typeerrorL(L, idx, lua_typename(L, LUA_TSTRING));
    }
    switch (atom)
    {
        case (int)LuaAtoms::srcOver:
            return BlendMode::srcOver;

        case (int)LuaAtoms::screen:
            return BlendMode::screen;

        case (int)LuaAtoms::overlay:
            return BlendMode::overlay;

        case (int)LuaAtoms::darken:
            return BlendMode::darken;

        case (int)LuaAtoms::lighten:
            return BlendMode::lighten;

        case (int)LuaAtoms::colorDodge:
            return BlendMode::colorDodge;

        case (int)LuaAtoms::colorBurn:
            return BlendMode::colorBurn;

        case (int)LuaAtoms::hardLight:
            return BlendMode::hardLight;

        case (int)LuaAtoms::softLight:
            return BlendMode::softLight;

        case (int)LuaAtoms::difference:
            return BlendMode::difference;

        case (int)LuaAtoms::exclusion:
            return BlendMode::exclusion;

        case (int)LuaAtoms::multiply:
            return BlendMode::multiply;

        case (int)LuaAtoms::hue:
            return BlendMode::hue;

        case (int)LuaAtoms::saturation:
            return BlendMode::saturation;

        case (int)LuaAtoms::color:
            return BlendMode::color;

        case (int)LuaAtoms::luminosity:
            return BlendMode::luminosity;

        default:
            luaL_error(L, "'%s' is not a valid BlendMode", blendName);
            return BlendMode::srcOver;
    }
}

static void readBlendMode(lua_State* L, ScriptedPaint* paint, int index)
{
    auto blendMode = lua_toblendmode(L, index);
    paint->blendMode(blendMode);
}

ScriptedPaintData::ScriptedPaintData() {}

ScriptedPaintData::ScriptedPaintData(const ShapePaint* shapePaint)
{
    if (shapePaint->is<Fill>())
    {
        style(RenderPaintStyle::fill);
    }
    else if (shapePaint->is<Stroke>())
    {
        auto stroke = shapePaint->as<Stroke>();
        style(RenderPaintStyle::stroke);
        thickness(stroke->thickness());
        cap((StrokeCap)stroke->cap());
        join((StrokeJoin)stroke->join());
    }
    for (auto& child : shapePaint->children())
    {
        if (child->is<SolidColor>())
        {
            color(child->as<SolidColor>()->colorValue());
            break;
        }
    }
    if (shapePaint->feather())
    {
        feather(shapePaint->feather()->strength());
    }
    blendMode((BlendMode)shapePaint->blendModeValue());
}

ScriptedPaint::ScriptedPaint(Factory* factory) :
    renderPaint(factory->makeRenderPaint())
{}

ScriptedPaint::ScriptedPaint(Factory* factory, const ScriptedPaint& source) :
    ScriptedPaint(factory)
{
    style(source.m_style);
    color(source.m_color);
    thickness(source.m_thickness);
    join(source.m_join);
    cap(source.m_cap);
    feather(source.m_feather);
    blendMode(source.m_blendMode);
    gradient(source.m_gradient);
}

static bool paint_set_value(lua_State* L,
                            ScriptedPaint* renderPaint,
                            int keyAtom,
                            int valueIndex)
{
    switch (keyAtom)
    {
        case (int)LuaAtoms::style:
            readStyle(L, renderPaint, valueIndex);
            return true;
        case (int)LuaAtoms::join:
            readJoin(L, renderPaint, valueIndex);
            return true;
        case (int)LuaAtoms::cap:
            readCap(L, renderPaint, valueIndex);
            return true;
        case (int)LuaAtoms::thickness:
            renderPaint->thickness(float(luaL_checknumber(L, valueIndex)));
            return true;
        case (int)LuaAtoms::blendMode:
            readBlendMode(L, renderPaint, valueIndex);
            return true;
        case (int)LuaAtoms::feather:
            renderPaint->feather(float(luaL_checknumber(L, valueIndex)));
            return true;
        case (int)LuaAtoms::gradient:
        {
            ScriptedGradient* gradient =
                lua_torive<ScriptedGradient>(L, valueIndex, true);
            if (gradient != nullptr)
            {
                renderPaint->gradient(gradient->shader);
            }
            else
            {
                renderPaint->gradient(nullptr);
            }
            return true;
        }
        case (int)LuaAtoms::color:
            renderPaint->color(luaL_checkunsigned(L, valueIndex));
            return true;
        default:
            return false;
    }
}

static void setPropertiesFromDefinitionTable(lua_State* L,
                                             ScriptedPaint* scriptedPaint,
                                             int tableIndex)
{
    luaL_checktype(L, tableIndex, LUA_TTABLE);

    // iterate table
    // Push another reference to the table on top of the stack (so we know
    // where it is, and this function can work for negative, positive and
    // pseudo indices
    lua_pushvalue(L, tableIndex);
    // stack now contains: -1 => table
    lua_pushnil(L);
    // stack now contains: -1 => nil; -2 => table
    while (lua_next(L, -2))
    {
        // stack now contains: -1 => value; -2 => key; -3 => table
        // copy the key so that lua_tostring does not modify the original
        // lua_pushvalue(L, -2);
        // stack now contains: -1 => key; -2 => value; -3 => key; -4 =>
        // table
        int atom;
        const char* key = lua_tostringatom(L, -2, &atom);
        if (key)
        {
            paint_set_value(L, scriptedPaint, atom, -1);
        }
        lua_pop(L, 1);
        // stack now contains: -1 => key; -2 => table
    }
    // stack now contains: -1 => table (when lua_next returns 0 it pops the
    // key but does not push anything.) Pop table
    lua_pop(L, 1);
}

static int paint_new(lua_State* L)
{
    ScriptingContext* context =
        static_cast<ScriptingContext*>(lua_getthreaddata(L));
    lua_newrive<ScriptedPaint>(L, context->factory());

    return 1;
}

static int paint_with(lua_State* L)
{
    ScriptingContext* context =
        static_cast<ScriptingContext*>(lua_getthreaddata(L));
    auto scriptedPaint = lua_newrive<ScriptedPaint>(L, context->factory());
    setPropertiesFromDefinitionTable(L, scriptedPaint, 1);
    return 1;
}

static int paint_newindex(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto scriptedPaint = lua_torive<ScriptedPaint>(L, 1);
    paint_set_value(L, scriptedPaint, atom, 3);

    return 0;
}

void ScriptedPaintData::pushStyle(lua_State* L)
{
    switch (m_style)
    {
        case RenderPaintStyle::fill:
            lua_pushstring(L, "fill");
            break;
        case RenderPaintStyle::stroke:
            lua_pushstring(L, "stroke");
            break;
        default:
            RIVE_UNREACHABLE();
    }
}

void ScriptedPaintData::pushJoin(lua_State* L)
{
    switch (m_join)
    {
        case StrokeJoin::miter:
            lua_pushstring(L, "miter");
            break;
        case StrokeJoin::bevel:
            lua_pushstring(L, "bevel");
            break;
        case StrokeJoin::round:
            lua_pushstring(L, "round");
            break;
        default:
            RIVE_UNREACHABLE();
    }
}

void ScriptedPaintData::pushCap(lua_State* L)
{
    switch (m_cap)
    {
        case StrokeCap::butt:
            lua_pushstring(L, "butt");
            break;
        case StrokeCap::square:
            lua_pushstring(L, "square");
            break;
        case StrokeCap::round:
            lua_pushstring(L, "round");
            break;
        default:
            RIVE_UNREACHABLE();
    }
}

void ScriptedPaintData::pushThickness(lua_State* L)
{
    lua_pushnumber(L, m_thickness);
}

void ScriptedPaintData::pushBlendMode(lua_State* L)
{
    switch (m_blendMode)
    {
        case BlendMode::srcOver:
            lua_pushstring(L, "srcOver");
            break;
        case BlendMode::screen:
            lua_pushstring(L, "screen");
            break;
        case BlendMode::overlay:
            lua_pushstring(L, "overlay");
            break;
        case BlendMode::darken:
            lua_pushstring(L, "darken");
            break;
        case BlendMode::lighten:
            lua_pushstring(L, "lighten");
            break;
        case BlendMode::colorDodge:
            lua_pushstring(L, "colorDodge");
            break;
        case BlendMode::colorBurn:
            lua_pushstring(L, "colorBurn");
            break;
        case BlendMode::hardLight:
            lua_pushstring(L, "hardLight");
            break;
        case BlendMode::softLight:
            lua_pushstring(L, "softLight");
            break;
        case BlendMode::difference:
            lua_pushstring(L, "difference");
            break;
        case BlendMode::exclusion:
            lua_pushstring(L, "exclusion");
            break;
        case BlendMode::multiply:
            lua_pushstring(L, "multiply");
            break;
        case BlendMode::hue:
            lua_pushstring(L, "hue");
            break;
        case BlendMode::saturation:
            lua_pushstring(L, "saturation");
            break;
        case BlendMode::color:
            lua_pushstring(L, "color");
            break;
        case BlendMode::luminosity:
            lua_pushstring(L, "luminosity");
            break;
        default:
            RIVE_UNREACHABLE();
    }
}

void ScriptedPaintData::pushFeather(lua_State* L)
{
    lua_pushnumber(L, m_feather);
}
void ScriptedPaintData::pushGradient(lua_State* L)
{
    if (m_gradient)
    {
        ScriptedGradient* gradient = lua_newrive<ScriptedGradient>(L);
        gradient->shader = m_gradient;
    }
    else
    {
        lua_pushnil(L);
    }
}
void ScriptedPaintData::pushColor(lua_State* L)
{
    lua_pushunsigned(L, m_color);
}

static int paint_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto scriptedPaint = (ScriptedPaintData*)lua_touserdata(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::style:
            scriptedPaint->pushStyle(L);
            return 1;
        case (int)LuaAtoms::join:
            scriptedPaint->pushJoin(L);
            return 1;
        case (int)LuaAtoms::cap:
            scriptedPaint->pushCap(L);
            return 1;
        case (int)LuaAtoms::thickness:
            scriptedPaint->pushThickness(L);
            return 1;
        case (int)LuaAtoms::blendMode:
            scriptedPaint->pushBlendMode(L);
            return 1;
        case (int)LuaAtoms::feather:
            scriptedPaint->pushFeather(L);
            return 1;
        case (int)LuaAtoms::gradient:
            scriptedPaint->pushGradient(L);
            return 1;
        case (int)LuaAtoms::color:
            scriptedPaint->pushColor(L);
            return 1;
        default:
            return 0;
    }
}

static int paint_copy(lua_State* L)
{
    int argCount = lua_gettop(L);

    auto scriptedPaint = lua_torive<ScriptedPaint>(L, 1);

    ScriptingContext* context =
        static_cast<ScriptingContext*>(lua_getthreaddata(L));
    auto scriptedPaintCopy =
        lua_newrive<ScriptedPaint>(L, context->factory(), *scriptedPaint);

    if (argCount == 2)
    {
        setPropertiesFromDefinitionTable(L, scriptedPaintCopy, 2);
    }
    return 1;
}

static int paint_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        switch (atom)
        {
            case (int)LuaAtoms::copy:
                return paint_copy(L);
        }
    }

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

static const luaL_Reg paintStaticMethods[] = {
    {"new", paint_new},
    {"with", paint_with},
    {NULL, NULL},
};

int luaopen_rive_paint(lua_State* L)
{
    lua_register_rive<ScriptedPaintData>(L);

    lua_pushcfunction(L, paint_index, nullptr);
    lua_setfield(L, -2, "__index");
    lua_setreadonly(L, -1, true);
    lua_pop(L, 1); // pop the metatable

    luaL_register(L, ScriptedPaint::luaName, paintStaticMethods);
    lua_register_rive<ScriptedPaint>(L);

    lua_pushcfunction(L, paint_index, nullptr);
    lua_setfield(L, -2, "__index");

    lua_pushcfunction(L, paint_newindex, nullptr);
    lua_setfield(L, -2, "__newindex");

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

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

    return 1;
}

#endif
