#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;

#ifdef WITH_RIVE_EDITOR
std::unique_ptr<ArtboardInstance> ScriptingContext::instantiateArtboard(
    Artboard* source)
{
  return source->instance();
}

std::unique_ptr<StateMachineInstance> ScriptingContext::artboardStateMachine(
    ArtboardInstance* instance)
{
  return instance->defaultStateMachine();
}
rcp<ViewModelInstance> ScriptingContext::artboardViewModel(
    File* file,
    Artboard* instance)
{
  return file->createViewModelInstance(instance);
}

#endif

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))
    ,
#ifdef WITH_RIVE_EDITOR
    m_stateMachine(
        scriptingContext
            ? scriptingContext->artboardStateMachine(m_artboard.get())
            : m_artboard->defaultStateMachine())
    , m_scriptingContext(
          scriptingContext ? scriptingContext->artboardLifetime()
                           : std::shared_ptr<ScriptingContext*>())
#else
    m_stateMachine(m_artboard->defaultStateMachine())
#endif
{
  // 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
  {
#ifdef WITH_RIVE_EDITOR
    m_viewModelInstance = scriptingContext
                              ? scriptingContext->artboardViewModel(
                                    m_file,
                                    m_artboard.get())
                              : m_file->createViewModelInstance(
                                    m_artboard.get());
#else
    m_viewModelInstance = m_file->createViewModelInstance(m_artboard.get());
#endif
  }
  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);
    }
  }
#ifdef WITH_RIVE_EDITOR
  else if (m_viewModelInstance && m_artboard->editorArena())
  {
    m_artboard->bindViewModelInstance(m_viewModelInstance, parentDataContext);
  }
#endif
}

ScriptReffedArtboard::~ScriptReffedArtboard()
{
  // Make sure state machine is deleted before artboard since
  // StateMachineInstance destructor accesses the artboard.
  m_stateMachine = nullptr;
#ifdef WITH_RIVE_EDITOR
  if (auto context = m_scriptingContext.lock())
    (*context)->releaseArtboard(m_artboard.get());
#endif
  // 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);
#ifdef WITH_RIVE_TOOLS
  scriptedArtboard->artboard()->settleIfImagesRevealed();
#endif
  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);
#ifdef WITH_RIVE_TOOLS
  scriptedArtboard->artboard()->settleIfImagesRevealed();
#endif
  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_scroll_event(lua_State* L)
{
  auto machine = lua_torive<ScriptedArtboard>(L, 1)->stateMachine();
  auto scrollEvent = lua_torive<ScriptedScrollEvent>(L, 2);
  auto result = 0;
  if (machine)
  {
    result = (int)machine->pointerScroll(
        scrollEvent->m_position,
        scrollEvent->m_event,
        scrollEvent->m_timeStamp,
        scrollEvent->m_id);
  }
  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::pointerScroll:
      {
        return apply_scroll_event(L);
      }
      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)
{
#ifdef WITH_RIVE_EDITOR
  auto* context = ScriptingContext::from(L);
  auto artboardInstance = context ? context->instantiateArtboard(artboard())
                                  : artboard()->instance();
#else
  auto artboardInstance = artboard()->instance();
#endif
  if (!artboardInstance)
    luaL_error(L, "Could not instantiate artboard");
  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,
          ScriptingContext::from(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:
      rive_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:
      rive_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
