#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.hpp"
#include "rive/file.hpp"
#include "rive/artboard.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 <math.h>
#include <stdio.h>

using namespace rive;

ScriptReffedArtboard::ScriptReffedArtboard(
    File* file,
    std::unique_ptr<ArtboardInstance>&& artboardInstance,
    rcp<ViewModelInstance> viewModelInstance,
    rcp<DataContext> parentDataContext) :
    m_file(file),
    m_artboard(std::move(artboardInstance)),
    m_stateMachine(m_artboard->defaultStateMachine())
{
    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);
        }
    }
}

ScriptReffedArtboard::~ScriptReffedArtboard()
{
    // 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 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);
    scriptedArtboard->artboard()->drawInternal(renderer);

    return 0;
}

static int artboard_draw_canvas(lua_State* L)
{
    auto scriptedArtboard = lua_torive<ScriptedArtboard>(L, 1);
    scriptedArtboard->artboard()->internalDrawCanvases();

    return 0;
}

bool ScriptedArtboard::advance(float seconds)
{
    auto machine = stateMachine();
    if (machine)
    {
        return machine->advanceAndApply(seconds);
    }
    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;
            (void)stateMachine->focusManager()->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::drawCanvas:
                return artboard_draw_canvas(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);
    lua_newrive<ScriptedArtboard>(L,
                                  L,
                                  m_scriptReffedArtboard->file(),
                                  std::move(artboardInstance),
                                  viewModelInstance,
                                  m_dataContext);
    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) :
    m_state(L),
    m_scriptReffedArtboard(
        make_rcp<ScriptReffedArtboard>(file,
                                       std::move(artboardInstance),
                                       viewModelInstance,
                                       dataContext)),
    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<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
