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

using namespace rive;

// Defined in lua_gpu.cpp (compiled as ObjC++ on Apple, has ore includes).
#ifdef RIVE_ORE
extern int riveImageViewImpl(lua_State* L);
#endif

// Out-of-line destructor. The rcp<ore::TextureView> member (when
// RIVE_CANVAS && RIVE_ORE) prevents implicit ~ScriptedImage() in TUs
// that don't include the full ore headers. When ore is not enabled the
// default-generated body is fine.
#if !(defined(RIVE_CANVAS) && defined(RIVE_ORE))
ScriptedImage::~ScriptedImage() = default;
ScriptedImage* ScriptedImage::luaNew(lua_State* L)
{
    return lua_newrive<ScriptedImage>(L);
}
#endif

static void image_direct_width(void* udata, void* result)
{
    auto* self = (ScriptedImage*)udata;
    lua_userdatadirectfield_setnumber(result,
                                      self->image ? (double)self->image->width()
                                                  : 0);
}

static void image_direct_height(void* udata, void* result)
{
    auto* self = (ScriptedImage*)udata;
    lua_userdatadirectfield_setnumber(
        result,
        self->image ? (double)self->image->height() : 0);
}

static int image_index(lua_State* L)
{
    auto image = lua_torive<ScriptedImage>(L, 1);

    int atom;
    const char* name = lua_tostringatom(L, 2, &atom);
    if (!name)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
    }
    switch (atom)
    {
        case (int)LuaAtoms::width:
            lua_pushnumber(L, image->image ? image->image->width() : 0);
            return 1;
        case (int)LuaAtoms::height:
            lua_pushnumber(L, image->image ? image->image->height() : 0);
            return 1;
#ifdef RIVE_ORE
        case (int)LuaAtoms::view:
            lua_pushcfunction(L, riveImageViewImpl, "Image.view");
            return 1;
#endif
    }
    luaL_error(L,
               "'%s' is not a valid index of %s",
               name,
               ScriptedImage::luaName);
    return 0;
}

static int imagesampler_construct(lua_State* L)
{
    int wrapXAtom;
    const char* wrapXName = lua_tostringatom(L, 1, &wrapXAtom);
    if (!wrapXName)
    {
        luaL_typeerrorL(L, 1, lua_typename(L, LUA_TSTRING));
    }
    int wrapYAtom;
    const char* wrapYName = lua_tostringatom(L, 2, &wrapYAtom);
    if (!wrapYName)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
    }
    int imageFilterAtom;
    const char* imageFilterName = lua_tostringatom(L, 3, &imageFilterAtom);
    if (!imageFilterName)
    {
        luaL_typeerrorL(L, 3, lua_typename(L, LUA_TSTRING));
    }
    ImageWrap wrapX = ImageWrap::clamp;
    ImageWrap wrapY = ImageWrap::clamp;
    ImageFilter filter = ImageFilter::bilinear;
    switch (wrapXAtom)
    {
        case (int)LuaAtoms::clamp:
            break;
        case (int)LuaAtoms::repeat:
            wrapX = ImageWrap::repeat;
            break;
        case (int)LuaAtoms::mirror:
            wrapX = ImageWrap::mirror;
            break;
        default:
            luaL_error(L, "'%s' is not a valid ImageWrap", wrapXName);
            break;
    }
    switch (wrapYAtom)
    {
        case (int)LuaAtoms::clamp:
            break;
        case (int)LuaAtoms::repeat:
            wrapY = ImageWrap::repeat;
            break;
        case (int)LuaAtoms::mirror:
            wrapY = ImageWrap::mirror;
            break;
        default:
            luaL_error(L, "'%s' is not a valid ImageWrap", wrapYName);
            break;
    }

    switch (imageFilterAtom)
    {
        case (int)LuaAtoms::bilinear:
            break;
        case (int)LuaAtoms::nearest:
            filter = ImageFilter::nearest;
            break;
        default:
            luaL_error(L, "'%s' is not a valid ImageFilter", imageFilterName);
            break;
    }

    lua_newrive<ScriptedImageSampler>(L, wrapX, wrapY, filter);
    return 1;
}

int luaopen_rive_image(lua_State* L)
{
    lua_register_rive<ScriptedImage>(L);

    lua_pushcfunction(L, image_index, nullptr);
    lua_setfield(L, -2, "__index");
    lua_setreadonly(L, -1, true);
    lua_pop(L, 1);

    lua_registeruserdatadirectfieldget(L,
                                       ScriptedImage::luaTag,
                                       "width",
                                       image_direct_width);
    lua_registeruserdatadirectfieldget(L,
                                       ScriptedImage::luaTag,
                                       "height",
                                       image_direct_height);

    lua_pushcfunction(L, imagesampler_construct, ScriptedImageSampler::luaName);
    lua_setfield(L, LUA_GLOBALSINDEX, ScriptedImageSampler::luaName);
    lua_register_rive<ScriptedImageSampler>(L);

    return 0;
}

#endif
