#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 "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)
{
    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 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)
    {
        // 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;
            (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);
    // 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<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
