#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.hpp"
#include "rive/file.hpp"
#include "rive/artboard.hpp"
#include "rive/custom_property_boolean.hpp"
#include "rive/custom_property_color.hpp"
#include "rive/assets/manifest_asset.hpp"
#include "rive/custom_property_number.hpp"
#include "rive/custom_property_string.hpp"
#include "rive/drawable.hpp"
#include "rive/animation/listener_invocation.hpp"
#include "rive/animation/state_machine_instance.hpp"
#include "rive/input/focus_manager.hpp"
#include "rive/viewmodel/viewmodel_property_number.hpp"
#include "rive/viewmodel/viewmodel_property_trigger.hpp"
#include "rive/node.hpp"
#include "rive/bones/root_bone.hpp"
#include "rive/constraints/constraint.hpp"
#include "rive/math/transform_components.hpp"
#include "rive/shapes/path.hpp"

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

using namespace rive;

ScriptReffedArtboard::ScriptReffedArtboard(
    File* file,
    std::unique_ptr<ArtboardInstance>&& artboardInstance,
    rcp<ViewModelInstance> viewModelInstance,
    rcp<DataContext> parentDataContext,
    ScriptingContext* scriptingContext
#ifdef WITH_RIVE_TOOLS
    ,
    rcp<File> filePin
#endif
    ) :
    m_file(file),
#ifdef WITH_RIVE_TOOLS
    m_filePin(std::move(filePin)),
#endif
    m_artboard(std::move(artboardInstance)),
    m_stateMachine(m_artboard->defaultStateMachine()),
    m_scriptingContext(scriptingContext)
{
    // A scripted artboard is a root: nothing hosts it in another artboard's
    // focus tree, so it owns its FocusManager and builds its own focus tree.
    m_artboard->buildFocusTree(m_artboard->ensureFocusManager(), nullptr);
    if (viewModelInstance)
    {
        m_viewModelInstance = viewModelInstance;
    }
    else
    {
        m_viewModelInstance = m_file->createViewModelInstance(m_artboard.get());
    }
    if (m_stateMachine && m_viewModelInstance)
    {
        if (parentDataContext)
        {
            auto dataContext = make_rcp<DataContext>(m_viewModelInstance);
            dataContext->parent(parentDataContext);
            m_stateMachine->bindDataContext(dataContext);
        }
        else
        {
            m_stateMachine->bindViewModelInstance(m_viewModelInstance);
        }
    }
    // Keep the bound instance tracked for end-of-frame advance for as long as
    // this artboard uses it — even if the script drops its ScriptedViewModel
    // wrapper. Covers both the passed-in and the auto-created instance.
    if (m_scriptingContext != nullptr)
    {
        m_scriptingContext->trackViewModelInstance(m_viewModelInstance);
    }
}

ScriptReffedArtboard::~ScriptReffedArtboard()
{
    if (m_scriptingContext != nullptr)
    {
        m_scriptingContext->untrackViewModelInstance(m_viewModelInstance.get());
    }
    // Make sure state machine is deleted before artboard since
    // StateMachineInstance destructor accesses the artboard.
    m_stateMachine = nullptr;
    // Make sure artboard is deleted before file.
    m_artboard = nullptr;
    m_file = nullptr;
}

rive::File* ScriptReffedArtboard::file() { return m_file; }

Artboard* ScriptReffedArtboard::artboard() { return m_artboard.get(); }

StateMachineInstance* ScriptReffedArtboard::stateMachine()
{
    return m_stateMachine.get();
}

static const int kVisitorIndex = 3;
static const int kVisitContextIndex = 4;
static const int kVisitedDrawableIndex = 5;

struct LuaDrawVisit
{
    lua_State* L;
    VisitedDrawable* visited;
    ScriptedRenderer* renderer;
    // A visitor that draws a nested artboard is visited again from inside
    // its own call frame, where artboard:draw's stack slots are out of reach.
    int visitorRef;
    int contextRef;
    int visitedRef;
    int rendererRef;
    int errorRef = LUA_NOREF;
    bool visiting = false;
};

static void luaDrawVisitor(void* context,
                           Drawable* drawable,
                           Renderer* renderer)
{
    auto visit = static_cast<LuaDrawVisit*>(context);
    lua_State* L = visit->L;
    if (visit->errorRef != LUA_NOREF || !lua_checkstack(L, 4))
    {
        drawable->draw(renderer);
        return;
    }
    // The visit outside this one reads its own drawable again afterwards.
    Drawable* outer = visit->visited->drawable;
    visit->visited->drawable = drawable;
    bool nested = visit->visiting;
    if (nested)
    {
        lua_getref(L, visit->visitorRef);
        lua_getref(L, visit->contextRef);
        lua_getref(L, visit->visitedRef);
        lua_getref(L, visit->rendererRef);
    }
    else
    {
        lua_pushvalue(L, kVisitorIndex);
        lua_pushvalue(L, kVisitContextIndex);
        lua_pushvalue(L, kVisitedDrawableIndex);
        lua_pushvalue(L, 2);
    }
    visit->visiting = true;
    uint32_t saves = visit->renderer->saveCount();
    if (lua_pcall(L, 3, 0, 0) != LUA_OK)
    {
        // Rethrown once the draw loop has unwound on its own.
        visit->errorRef = lua_ref(L, -1);
        lua_pop(L, 1);
        visit->renderer->restoreTo(saves);
    }
    visit->visiting = nested;
    visit->visited->drawable = outer;
}

static int artboard_draw(lua_State* L)
{
    auto scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
    auto scriptedRenderer = lua_torive<ScriptedRenderer>(L, 2);

    auto renderer = scriptedRenderer->validate(L);
    if (lua_isnoneornil(L, kVisitorIndex))
    {
        scriptedArtboard->artboard()->drawInternal(renderer);
        return 0;
    }
    luaL_checktype(L, kVisitorIndex, LUA_TFUNCTION);
    lua_settop(L, kVisitContextIndex);
    luaL_checkstack(L, 8, "artboard draw visitor");
    auto visited = lua_newrive<VisitedDrawable>(L);
    LuaDrawVisit visit = {L,
                          visited,
                          scriptedRenderer,
                          lua_ref(L, kVisitorIndex),
                          lua_ref(L, kVisitContextIndex),
                          lua_ref(L, -1),
                          lua_ref(L, 2)};
    scriptedArtboard->artboard()->drawInternal(
        renderer,
        luaDrawVisitor,
        &visit,
        scriptedArtboard->scriptReffedArtboard()->file());
    visited->drawable = nullptr;
    for (int ref : {visit.visitorRef,
                    visit.contextRef,
                    visit.visitedRef,
                    visit.rendererRef})
    {
        lua_unref(L, ref);
    }
    if (visit.errorRef != LUA_NOREF)
    {
        lua_getref(L, visit.errorRef);
        lua_unref(L, visit.errorRef);
        lua_error(L);
    }
    return 0;
}

static Drawable* visitedDrawable(lua_State* L)
{
    auto visited = lua_torive<VisitedDrawable>(L, 1);
    if (visited->drawable == nullptr)
    {
        luaL_error(L, "Drawable is only valid inside the draw visitor");
    }
    return visited->drawable;
}

// The key a visitor reads custom properties by; one that matches nothing
// when no property in the file carries that name.
static int artboard_propertyKey(lua_State* L)
{
    auto scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
    size_t length = 0;
    const char* name = luaL_checklstring(L, 2, &length);
    lua_pushunsigned(L,
                     File::customPropertyKey(
                         scriptedArtboard->scriptReffedArtboard()->file(),
                         name,
                         length));
    return 1;
}

static int artboard_drawModulated(lua_State* L)
{
    auto scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
    auto renderer = lua_torive<ScriptedRenderer>(L, 2)->validate(L);
    scriptedArtboard->artboard()->drawModulated(
        renderer,
        luaL_checkunsigned(L, 3),
        scriptedArtboard->scriptReffedArtboard()->file());
    return 0;
}

// Nothing when the drawable has no property of this key and kind.
static int drawable_value(lua_State* L, CustomPropertyKind kind)
{
    auto property =
        visitedDrawable(L)->customProperty(luaL_checkunsigned(L, 2));
    if (property == nullptr || property->kind() != kind)
    {
        return 0;
    }
    switch (kind)
    {
        case CustomPropertyKind::number:
            lua_pushnumber(
                L,
                property->as<CustomPropertyNumber>()->propertyValue());
            break;
        case CustomPropertyKind::boolean:
            lua_pushboolean(
                L,
                property->as<CustomPropertyBoolean>()->propertyValue());
            break;
        case CustomPropertyKind::color:
            lua_pushunsigned(
                L,
                (unsigned)property->as<CustomPropertyColor>()->propertyValue());
            break;
        case CustomPropertyKind::string:
        {
            const std::string& value =
                property->as<CustomPropertyString>()->propertyValue();
            lua_pushlstring(L, value.data(), value.size());
            break;
        }
        default:
            return 0;
    }
    return 1;
}

#ifdef WITH_RIVE_TOOLS
// For tooling and debugging, so shipping runtimes leave it out.
static int drawable_properties(lua_State* L)
{
    static const char* kindNames[] =
        {"number", "boolean", "string", "color", "enum", "trigger"};
    auto drawable = visitedDrawable(L);
    auto file = drawable->artboard()->drawVisitorFile();
    auto manifest = file != nullptr ? file->manifest() : nullptr;
    lua_newtable(L);
    int index = 0;
    for (auto child : drawable->children())
    {
        auto property = CustomProperty::tagging(child);
        if (property == nullptr || manifest == nullptr)
        {
            continue;
        }
        const std::string& name = manifest->resolveName(property->nameId());
        lua_createtable(L, 0, 2);
        lua_pushlstring(L, name.data(), name.size());
        lua_setfield(L, -2, "name");
        lua_pushstring(L, kindNames[(int)property->kind()]);
        lua_setfield(L, -2, "kind");
        lua_rawseti(L, -2, ++index);
    }
    return 1;
}
#endif

static int drawable_draw(lua_State* L)
{
    auto renderer = lua_torive<ScriptedRenderer>(L, 2)->validate(L);
    visitedDrawable(L)->draw(renderer);
    return 0;
}

static int drawable_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        switch (atom)
        {
            case (int)LuaAtoms::number:
                return drawable_value(L, CustomPropertyKind::number);
            case (int)LuaAtoms::boolean:
                return drawable_value(L, CustomPropertyKind::boolean);
            case (int)LuaAtoms::color:
                return drawable_value(L, CustomPropertyKind::color);
            case (int)LuaAtoms::string:
                return drawable_value(L, CustomPropertyKind::string);
#ifdef WITH_RIVE_TOOLS
            case (int)LuaAtoms::properties:
                return drawable_properties(L);
#endif
            case (int)LuaAtoms::draw:
                return drawable_draw(L);
        }
    }
    luaL_error(L,
               "%s is not a valid method of %s",
               str,
               VisitedDrawable::luaName);
    return 0;
}

bool ScriptedArtboard::advance(float seconds)
{
    auto machine = stateMachine();
    if (machine)
    {
        // A scripted artboard's view models are advanced/reset by the host
        // frame, not by this script-driven advance, so skip the VM consume.
        return machine->advanceAndApply(seconds, false);
    }
    else
    {
        return artboard()->advance(seconds);
    }
}

static int apply_pointer_event(lua_State* L, int atom)
{
    auto scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
    auto pointerEvent = lua_torive<ScriptedPointerEvent>(L, 2);
    auto result = 0;
    if (scriptedArtboard->stateMachine())
    {
        switch (atom)
        {
            case (int)LuaAtoms::pointerDown:
                result = (int)scriptedArtboard->stateMachine()->pointerDown(
                    pointerEvent->m_position,
                    pointerEvent->m_id);
                break;
            case (int)LuaAtoms::pointerMove:
                result = (int)scriptedArtboard->stateMachine()->pointerMove(
                    pointerEvent->m_position,
                    0,
                    pointerEvent->m_id);
                break;
            case (int)LuaAtoms::pointerUp:
                result = (int)scriptedArtboard->stateMachine()->pointerUp(
                    pointerEvent->m_position,
                    pointerEvent->m_id);
                break;
            case (int)LuaAtoms::pointerExit:
                result = (int)scriptedArtboard->stateMachine()->pointerExit(
                    pointerEvent->m_position,
                    pointerEvent->m_id);
                break;
        }
    }
    lua_pushinteger(L, result);
    return 1;
}

static int apply_gamepad_event(lua_State* L, int atom)
{
    auto scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
    auto result = 0;
    auto stateMachine = scriptedArtboard->stateMachine();
    if (stateMachine)
    {
        auto dispatch = [&](const ListenerInvocation& invocation) {
            ScriptedDrawable* dispatched = nullptr;
            if (auto* fm = stateMachine->focusManager())
            {
                (void)fm->gamepadDispatch(invocation, &dispatched);
            }
            result = (int)stateMachine->broadcastGamepadToScriptedDrawables(
                invocation,
                dispatched);
        };
        switch (atom)
        {
            case (int)LuaAtoms::gamepadConnected:
            {
                auto* connected = lua_torive<ScriptedGamepadConnected>(L, 2);
                dispatch(ListenerInvocation::gamepadConnected(
                    connected->m_snapshot));
                break;
            }
            case (int)LuaAtoms::gamepadEvent:
            {
                auto* event = lua_torive<ScriptedGamepadEvent>(L, 2);
                dispatch(ListenerInvocation::gamepadEvent(event->m_data));
                break;
            }
            case (int)LuaAtoms::gamepadDisconnected:
            {
                auto* disconnected =
                    lua_torive<ScriptedGamepadDisconnected>(L, 2);
                dispatch(ListenerInvocation::gamepadDisconnected(
                    disconnected->m_deviceId));
                break;
            }
        }
    }
    lua_pushinteger(L, result);
    return 1;
}

static int artboard_advance(lua_State* L)
{
    auto scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
    auto seconds = float(luaL_checknumber(L, 2));

    bool advanced = scriptedArtboard->advance(seconds);
    lua_pushboolean(L, advanced ? 1 : 0);

    return 1;
}

static int artboard_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);

    if (str != nullptr)
    {
        switch (atom)
        {
            case (int)LuaAtoms::draw:
                return artboard_draw(L);
            case (int)LuaAtoms::propertyKey:
                return artboard_propertyKey(L);
            case (int)LuaAtoms::drawModulated:
                return artboard_drawModulated(L);
            case (int)LuaAtoms::advance:
                return artboard_advance(L);
            case (int)LuaAtoms::instance:
            {
                int nargs = lua_gettop(L);
                auto scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
                if (nargs == 2)
                {

                    auto scriptedViewModel =
                        lua_torive<ScriptedViewModel>(L, 2);
                    return scriptedArtboard->instance(
                        L,
                        scriptedViewModel->viewModelInstance());
                }
                return scriptedArtboard->instance(L, nullptr);
            }
            case (int)LuaAtoms::animation:
            {
                auto scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
                const char* animationName = luaL_checkstring(L, 2);
                return scriptedArtboard->animation(L, animationName);
            }
            case (int)LuaAtoms::addToPath:
            {
                int nargs = lua_gettop(L);
                auto scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
                auto scriptedPath = lua_torive<ScriptedPath>(L, 2);
                Mat2D* transform = nullptr;
                if (nargs == 3)
                {
                    auto matrix = lua_torive<ScriptedMat2D>(L, 3);
                    transform = &matrix->value;
                }

                scriptedArtboard->scriptReffedArtboard()
                    ->artboard()
                    ->addToRawPath(scriptedPath->rawPath, transform);
                scriptedPath->markDirty();

                return 0;
            }
            case (int)LuaAtoms::bounds:
            {
                auto scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
                const auto& bounds = scriptedArtboard->artboard()->bounds();
                lua_pushvec2d(L, bounds.min());
                lua_pushvec2d(L, bounds.max());
                return 2;
            }
            case (int)LuaAtoms::node:
            {
                auto scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
                const char* name = luaL_checkstring(L, 2);
                auto component =
                    scriptedArtboard->artboard()->find<TransformComponent>(
                        name);
                if (component == nullptr)
                {
                    lua_pushnil(L);
                    return 1;
                }
                lua_newrive<ScriptedNode>(
                    L,
                    scriptedArtboard->scriptReffedArtboard(),
                    component);
                return 1;
            }
            case (int)LuaAtoms::pointerDown:
            case (int)LuaAtoms::pointerUp:
            case (int)LuaAtoms::pointerMove:
            case (int)LuaAtoms::pointerExit:
            {
                return apply_pointer_event(L, atom);
            }
            case (int)LuaAtoms::gamepadEvent:
            case (int)LuaAtoms::gamepadConnected:
            case (int)LuaAtoms::gamepadDisconnected:
            {
                return apply_gamepad_event(L, atom);
            }
        }
    }

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

int ScriptedArtboard::pushData(lua_State* L)
{
    if (m_dataRef != 0)
    {
        lua_rawgeti(L, LUA_REGISTRYINDEX, m_dataRef);
        return 1;
    }
    auto vm = viewModelInstance();
    if (!vm)
    {
        lua_pushnil(L);
    }
    else
    {
        lua_newrive<ScriptedViewModel>(L, L, ref_rcp(vm->viewModel()), vm);
    }
    m_dataRef = lua_ref(L, -1);

    return 1;
}

int ScriptedArtboard::instance(lua_State* L,
                               rcp<ViewModelInstance> viewModelInstance)
{
    auto artboardInstance = artboard()->instance();
    artboardInstance->frameOrigin(false);
    // Clones share the source's dependency on a cross-lifetime host file.
    lua_newrive<ScriptedArtboard>(L,
                                  L,
                                  m_scriptReffedArtboard->file(),
                                  std::move(artboardInstance),
                                  viewModelInstance,
                                  m_dataContext
#ifdef WITH_RIVE_TOOLS
                                  ,
                                  m_scriptReffedArtboard->filePin()
#endif
    );
    return 1;
}

int ScriptedArtboard::animation(lua_State* L, const char* animationName)
{
    if (artboard()->isInstance())
    {

        auto animation = static_cast<ArtboardInstance*>(artboard())
                             ->animationNamed(animationName);
        if (animation)
        {
            lua_newrive<ScriptedAnimation>(L, L, std::move(animation));
            return 1;
        }
    }
    return 0;
}

ScriptedNode::ScriptedNode(rcp<ScriptReffedArtboard> artboard,
                           TransformComponent* component) :
    m_artboard(artboard), m_component(component)
{}

const ShapePaint* ScriptedNode::shapePaint()
{
    if (m_shapePaint)
    {
        return m_shapePaint;
    }
    if (m_component != nullptr && m_component->is<ShapePaint>())
    {
        return m_component->as<ShapePaint>();
    }
    return nullptr;
}

// Direct field getters bypass the __index Lua frame. They are dispatched by
// LOP_GETTABLEKS via global_State::udatadirectfields[tag]. Only fields that
// read a primitive without allocation or side effects belong here; the
// __index slow path still handles every other key.

static void artboard_direct_width(void* udata, void* result)
{
    lua_userdatadirectfield_setnumber(
        result,
        ((ScriptedArtboard*)udata)->artboard()->width());
}

static void artboard_direct_height(void* udata, void* result)
{
    lua_userdatadirectfield_setnumber(
        result,
        ((ScriptedArtboard*)udata)->artboard()->height());
}

static void artboard_direct_frameOrigin(void* udata, void* result)
{
    lua_userdatadirectfield_setboolean(
        result,
        ((ScriptedArtboard*)udata)->artboard()->frameOrigin() ? 1 : 0);
}

static int artboard_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 scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::frameOrigin:
            lua_pushboolean(L,
                            scriptedArtboard->artboard()->frameOrigin() ? 1
                                                                        : 0);
            return 1;

        case (int)LuaAtoms::width:
            lua_pushnumber(L, scriptedArtboard->artboard()->width());
            return 1;
        case (int)LuaAtoms::height:
            lua_pushnumber(L, scriptedArtboard->artboard()->height());
            return 1;
        case (int)LuaAtoms::data:
            return scriptedArtboard->pushData(L);

        default:
            break;
    }

    luaL_error(L,
               "'%s' is not a valid index of %s",
               key,
               ScriptedArtboard::luaName);
    return 0;
}

static int artboard_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 scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::frameOrigin:
            scriptedArtboard->artboard()->frameOrigin(luaL_checkboolean(L, 3) !=
                                                      0);
            return 0;
        case (int)LuaAtoms::width:
            scriptedArtboard->artboard()->width(luaL_checknumber(L, 3));
            return 0;
        case (int)LuaAtoms::height:
            scriptedArtboard->artboard()->height(luaL_checknumber(L, 3));
            return 0;
        default:
            break;
    }

    luaL_error(L,
               "'%s' is not a valid index of %s",
               key,
               ScriptedArtboard::luaName);

    return 0;
}

ScriptedArtboard::ScriptedArtboard(
    lua_State* L,
    File* file,
    std::unique_ptr<ArtboardInstance>&& artboardInstance,
    rcp<ViewModelInstance> viewModelInstance,
    rcp<DataContext> dataContext
#ifdef WITH_RIVE_TOOLS
    ,
    rcp<File> filePin
#endif
    ) :
    m_state(L),
    m_scriptReffedArtboard(make_rcp<ScriptReffedArtboard>(
        file,
        std::move(artboardInstance),
        viewModelInstance,
        dataContext,
        static_cast<ScriptingContext*>(lua_getthreaddata(L))
#ifdef WITH_RIVE_TOOLS
            ,
        std::move(filePin)
#endif
            )),
    m_dataContext(dataContext)
{}

ScriptedArtboard::~ScriptedArtboard()
{
    lua_unref(m_state, m_dataRef);
    m_scriptReffedArtboard = nullptr;
}

ScriptedAnimation::ScriptedAnimation(
    lua_State* L,
    std::unique_ptr<LinearAnimationInstance> animation) :
    m_state(L), m_animation(std::move(animation))
{}

float ScriptedAnimation::duration()
{
    auto durationFrames = (float)m_animation->duration();
    auto fps = (float)m_animation->fps();
    return durationFrames / fps;
}

int ScriptedAnimation::advance()
{
    auto seconds = float(luaL_checknumber(m_state, 2));

    bool advanced = m_animation->advance(seconds);
    m_animation->apply();
    lua_pushboolean(m_state, advanced ? 1 : 0);
    return 1;
}

int ScriptedAnimation::setTime(std::string mode)
{
    float seconds = 0;
    if (mode == "seconds")
    {
        seconds = float(luaL_checknumber(m_state, 2));
    }
    else if (mode == "frames")
    {
        auto frames = float(luaL_checknumber(m_state, 2));

        seconds = frames / m_animation->fps();
    }
    else if (mode == "percentage")
    {
        auto percentage = float(luaL_checknumber(m_state, 2));
        seconds = percentage * duration();
    }

    m_animation->time(m_animation->animation()->globalToLocalSeconds(seconds));
    m_animation->apply();
    return 0;
}

static void node_direct_x(void* udata, void* result)
{
    lua_userdatadirectfield_setnumber(result,
                                      ((ScriptedNode*)udata)->component()->x());
}

static void node_direct_y(void* udata, void* result)
{
    lua_userdatadirectfield_setnumber(result,
                                      ((ScriptedNode*)udata)->component()->y());
}

static void node_direct_rotation(void* udata, void* result)
{
    lua_userdatadirectfield_setnumber(
        result,
        ((ScriptedNode*)udata)->component()->rotation());
}

static void node_direct_scaleX(void* udata, void* result)
{
    lua_userdatadirectfield_setnumber(
        result,
        ((ScriptedNode*)udata)->component()->scaleX());
}

static void node_direct_scaleY(void* udata, void* result)
{
    lua_userdatadirectfield_setnumber(
        result,
        ((ScriptedNode*)udata)->component()->scaleY());
}

static void node_direct_position(void* udata, void* result)
{
    auto component = ((ScriptedNode*)udata)->component();
    lua_userdatadirectfield_setvector(result,
                                      component->x(),
                                      component->y(),
                                      0.0f
#if LUA_VECTOR_SIZE == 4
                                      ,
                                      0.0f
#endif
    );
}

static void node_direct_scale(void* udata, void* result)
{
    auto component = ((ScriptedNode*)udata)->component();
    lua_userdatadirectfield_setvector(result,
                                      component->scaleX(),
                                      component->scaleY(),
                                      0.0f
#if LUA_VECTOR_SIZE == 4
                                      ,
                                      0.0f
#endif
    );
}

static int node_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 scriptedNode = lua_torive<ScriptedNode>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::position:
            lua_pushvector2(L,
                            scriptedNode->component()->x(),
                            scriptedNode->component()->y());
            return 1;

        case (int)LuaAtoms::rotation:
            lua_pushnumber(L, scriptedNode->component()->rotation());
            return 1;

        case (int)LuaAtoms::scale:
            lua_pushvector2(L,
                            scriptedNode->component()->scaleX(),
                            scriptedNode->component()->scaleY());
            return 1;

        case (int)LuaAtoms::scaleX:
            lua_pushnumber(L, scriptedNode->component()->scaleX());
            return 1;

        case (int)LuaAtoms::scaleY:
            lua_pushnumber(L, scriptedNode->component()->scaleY());
            return 1;

        case (int)LuaAtoms::worldTransform:
            lua_newrive<ScriptedMat2D>(
                L,
                scriptedNode->component()->worldTransform());
            return 1;

        case (int)LuaAtoms::children:
        {
            auto component = scriptedNode->component();
            if (component->is<ContainerComponent>())
            {
                auto container = component->as<ContainerComponent>();
                // speculative pre-alloc the table
                auto& children = container->children();
                lua_createtable(L, (int)children.size(), 0);

                int index = 1;
                for (auto child : children)
                {
                    if (child->is<TransformComponent>())
                    {
                        lua_newrive<ScriptedNode>(
                            L,
                            scriptedNode->artboard(),
                            child->as<TransformComponent>());
                        // Set table[i] = value, pops the value
                        lua_rawseti(L, -2, index++);
                    }
                }
            }
            return 1;
        }

        case (int)LuaAtoms::parent:
        {
            auto parent = scriptedNode->component()->parent();
            if (parent != nullptr && parent->is<TransformComponent>())
            {
                lua_newrive<ScriptedNode>(L,
                                          scriptedNode->artboard(),
                                          parent->as<TransformComponent>());
            }
            else
            {
                lua_pushnil(L);
            }
            return 1;
        }
        case (int)LuaAtoms::paint:
        {
            auto shapePaint = scriptedNode->shapePaint();
            if (shapePaint)
            {
                lua_newrive<ScriptedPaintData>(L, shapePaint);
            }
            else
            {
                lua_pushnil(L);
            }
            return 1;
        }

        default:
            switch (key[0])
            {
                case 'x':
                    lua_pushnumber(L, scriptedNode->component()->x());
                    return 1;
                case 'y':
                    lua_pushnumber(L, scriptedNode->component()->y());
                    return 1;
            }
    }

    luaL_error(L,
               "'%s' is not a valid index of %s",
               key,
               ScriptedNode::luaName);
    return 0;
}

static int node_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 scriptedNode = lua_torive<ScriptedNode>(L, 1);
    auto component = scriptedNode->component();
    switch (atom)
    {
        case (int)LuaAtoms::position:
        {
            const float* vec = luaL_checkvector(L, 3);

            if (component->is<Node>())
            {
                Node* node = component->as<Node>();
                node->x(vec[0]);
                node->y(vec[1]);
            }
            else if (component->is<RootBone>())
            {
                RootBone* bone = component->as<RootBone>();
                bone->x(vec[0]);
                bone->y(vec[1]);
            }
            return 0;
        }
        case (int)LuaAtoms::rotation:
            component->rotation(float(luaL_checknumber(L, 3)));
            return 0;

        case (int)LuaAtoms::scale:
        {
            const float* vec = luaL_checkvector(L, 3);
            component->scaleX(vec[0]);
            component->scaleY(vec[1]);
            return 0;
        }

        case (int)LuaAtoms::scaleX:
            component->scaleX(float(luaL_checknumber(L, 3)));
            return 0;

        case (int)LuaAtoms::scaleY:
            component->scaleY(float(luaL_checknumber(L, 3)));
            return 0;

        case (int)LuaAtoms::worldTransform:
        {
            Mat2D& transform = component->mutableWorldTransform();
            transform = *(Mat2D*)lua_torive<ScriptedMat2D>(L, 3);
            return 0;
        }

        default:
            switch (key[0])
            {
                case 'x':
                    if (component->is<Node>())
                    {
                        Node* node = component->as<Node>();
                        node->x(float(luaL_checknumber(L, 3)));
                    }
                    else if (component->is<RootBone>())
                    {
                        RootBone* bone = component->as<RootBone>();
                        bone->x(float(luaL_checknumber(L, 3)));
                    }
                    return 0;
                case 'y':
                    if (component->is<Node>())
                    {
                        Node* node = component->as<Node>();
                        node->y(float(luaL_checknumber(L, 3)));
                    }
                    else if (component->is<RootBone>())
                    {
                        RootBone* bone = component->as<RootBone>();
                        bone->y(float(luaL_checknumber(L, 3)));
                    }
                    return 0;
            }
    }

    luaL_error(L,
               "'%s' is not a valid index of %s",
               key,
               ScriptedNode::luaName);
    return 0;
}

static int node_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        switch (atom)
        {
            case (int)LuaAtoms::decompose:
            {
                auto scriptedNode = lua_torive<ScriptedNode>(L, 1);
                auto component = scriptedNode->component();
                Mat2D world = getParentWorld(*component).invertOrIdentity() *
                              (*(Mat2D*)lua_torive<ScriptedMat2D>(L, 2));
                TransformComponents components = world.decompose();
                if (component->is<Node>())
                {
                    Node* node = component->as<Node>();
                    node->x(components.x());
                    node->y(components.y());
                }
                else if (component->is<RootBone>())
                {
                    RootBone* bone = component->as<RootBone>();
                    bone->x(components.x());
                    bone->y(components.y());
                }
                component->scaleX(components.scaleX());
                component->scaleY(components.scaleY());
                component->rotation(components.rotation());
                return 0;
            }

            case (int)LuaAtoms::asPath:
            {

                auto scriptedNode = lua_torive<ScriptedNode>(L, 1);
                auto component = scriptedNode->component();
                if (component->is<Path>())
                {
                    lua_newrive<ScriptedPathData>(
                        L,
                        &component->as<Path>()->rawPath());
                }
                else
                {
                    lua_pushnil(L);
                }
                return 1;
            }

            case (int)LuaAtoms::asPaint:
            {
                auto scriptedNode = lua_torive<ScriptedNode>(L, 1);
                auto shapePaint = scriptedNode->shapePaint();
                if (shapePaint)
                {
                    lua_newrive<ScriptedPaintData>(L, shapePaint);
                }
                else
                {
                    lua_pushnil(L);
                }
                return 1;
            }
        }
    }

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

static void animation_direct_duration(void* udata, void* result)
{
    lua_userdatadirectfield_setnumber(result,
                                      ((ScriptedAnimation*)udata)->duration());
}

static int animation_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 scriptedAnimation = lua_torive<ScriptedAnimation>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::duration:
            lua_pushnumber(L, scriptedAnimation->duration());
            return 1;
    }

    luaL_error(L,
               "'%s' is not a valid index of %s",
               key,
               ScriptedNode::luaName);
    return 0;
}

static int animation_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        auto scriptedAnimation = lua_torive<ScriptedAnimation>(L, 1);
        switch (atom)
        {
            case (int)LuaAtoms::advance:
            {
                return scriptedAnimation->advance();
            }
            case (int)LuaAtoms::setTime:
            {
                return scriptedAnimation->setTime("seconds");
            }
            case (int)LuaAtoms::setTimeFrames:
            {
                return scriptedAnimation->setTime("frames");
            }
            case (int)LuaAtoms::setTimePercentage:
            {
                return scriptedAnimation->setTime("percentage");
            }
        }
    }

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

int luaopen_rive_artboards(lua_State* L)
{
    lua_register_rive<ScriptedArtboard>(L);

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

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

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

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

    lua_registeruserdatadirectfieldget(L,
                                       ScriptedArtboard::luaTag,
                                       "width",
                                       artboard_direct_width);
    lua_registeruserdatadirectfieldget(L,
                                       ScriptedArtboard::luaTag,
                                       "height",
                                       artboard_direct_height);
    lua_registeruserdatadirectfieldget(L,
                                       ScriptedArtboard::luaTag,
                                       "frameOrigin",
                                       artboard_direct_frameOrigin);

    lua_register_rive<ScriptedNode>(L);

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

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

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

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

    lua_registeruserdatadirectfieldget(L,
                                       ScriptedNode::luaTag,
                                       "x",
                                       node_direct_x);
    lua_registeruserdatadirectfieldget(L,
                                       ScriptedNode::luaTag,
                                       "y",
                                       node_direct_y);
    lua_registeruserdatadirectfieldget(L,
                                       ScriptedNode::luaTag,
                                       "rotation",
                                       node_direct_rotation);
    lua_registeruserdatadirectfieldget(L,
                                       ScriptedNode::luaTag,
                                       "scaleX",
                                       node_direct_scaleX);
    lua_registeruserdatadirectfieldget(L,
                                       ScriptedNode::luaTag,
                                       "scaleY",
                                       node_direct_scaleY);
    lua_registeruserdatadirectfieldget(L,
                                       ScriptedNode::luaTag,
                                       "position",
                                       node_direct_position);
    lua_registeruserdatadirectfieldget(L,
                                       ScriptedNode::luaTag,
                                       "scale",
                                       node_direct_scale);

    lua_register_rive<VisitedDrawable>(L);
    lua_pushcfunction(L, drawable_namecall, nullptr);
    lua_setfield(L, -2, "__namecall");
    lua_setreadonly(L, -1, true);
    lua_pop(L, 1); // pop the metatable

    lua_register_rive<ScriptedAnimation>(L);
    lua_pushcfunction(L, animation_index, nullptr);
    lua_setfield(L, -2, "__index");

    lua_pushcfunction(L, animation_namecall, nullptr);
    lua_setfield(L, -2, "__namecall");
    lua_pop(L, 1); // pop the metatable

    lua_registeruserdatadirectfieldget(L,
                                       ScriptedAnimation::luaTag,
                                       "duration",
                                       animation_direct_duration);

    return 0;
}
#endif
