#if defined(WITH_RIVE_SCRIPTING) && defined(WITH_RIVE_TEXT)
#include "lua.h"
#include "lualib.h"
#include "rive/lua/scripted_text.hpp"
#include "rive/text/cursor.hpp"
#include "rive/factory.hpp"

using namespace rive;

namespace
{
struct AtomName
{
  LuaAtoms atom;
  const char* name;
};

// Rows follow the runtime enum order so the index is the enum value.
constexpr AtomName sizingNames[] = {
    {LuaAtoms::autoWidth, "autoWidth"},
    {LuaAtoms::autoHeight, "autoHeight"},
    {LuaAtoms::fixed, "fixed"}};
constexpr AtomName overflowNames[] = {
    {LuaAtoms::visible, "visible"},
    {LuaAtoms::hidden, "hidden"},
    {LuaAtoms::clipped, "clipped"},
    {LuaAtoms::ellipsis, "ellipsis"}};
// left, right, center map to TextAlign; start and end resolve against the
// paragraph direction.
constexpr AtomName alignNames[] = {
    {LuaAtoms::left, "left"},
    {LuaAtoms::right, "right"},
    {LuaAtoms::center, "center"},
    {LuaAtoms::start, "start"},
    {LuaAtoms::end, "end"}};
constexpr AtomName wrapNames[] = {
    {LuaAtoms::wrap, "wrap"},
    {LuaAtoms::noWrap, "noWrap"}};
constexpr AtomName wordBreakNames[] = {
    {LuaAtoms::breakWord, "breakWord"},
    {LuaAtoms::normal, "normal"},
    {LuaAtoms::breakAll, "breakAll"}};
constexpr AtomName originNames[] = {
    {LuaAtoms::top, "top"},
    {LuaAtoms::baseline, "baseline"}};
// Index minus one is the shaper's direction flag.
constexpr AtomName directionNames[] = {
    {LuaAtoms::autoDetect, "auto"},
    {LuaAtoms::ltr, "ltr"},
    {LuaAtoms::rtl, "rtl"}};

template <size_t N>
int readEnum(
    lua_State* L,
    int idx,
    const AtomName (&names)[N],
    const char* typeName)
{
  int atom;
  const char* str = lua_tostringatom(L, idx, &atom);
  if (!str)
  {
    luaL_typeerrorL(L, idx, lua_typename(L, LUA_TSTRING));
  }
  for (size_t i = 0; i < N; i++)
  {
    if ((int)names[i].atom == atom)
    {
      return (int)i;
    }
  }
  luaL_error(L, "'%s' is not a valid %s", str, typeName);
  return 0;
}

template <size_t N>
int pushEnum(lua_State* L, const AtomName (&names)[N], int value)
{
  lua_pushstring(L, names[value].name);
  return 1;
}

int pushDirection(lua_State* L, TextDirection direction)
{
  return pushEnum(L, directionNames, (int)direction + 1);
}

ScriptedTextLayout* checkLayout(lua_State* L, int idx)
{
  return lua_torive<ScriptedText>(L, idx)->layout.get();
}

void checkFresh(lua_State* L, ScriptedTextLayout* layout, uint32_t revision)
{
  if (layout->text.revision() != revision)
  {
    luaL_error(L, "Text changed since this was fetched, fetch it again.");
  }
}

const OrderedLine& checkLine(lua_State* L, ScriptedTextLine* line)
{
  checkFresh(L, line->layout.get(), line->revision);
  return line->layout->text.orderedLines()[line->index];
}

void pushLine(lua_State* L, ScriptedText* text, uint32_t index)
{
  auto line = lua_newrive<ScriptedTextLine>(L);
  line->layout = text->layout;
  line->revision = text->layout->text.revision();
  line->index = index;
}

void pushGlyph(
    lua_State* L,
    ScriptedTextLine* line,
    const GlyphRun& run,
    uint32_t glyphIndex,
    Vec2D position)
{
  auto glyph = lua_newrive<ScriptedGlyph>(L);
  glyph->layout = line->layout;
  glyph->revision = line->revision;
  glyph->run = &run;
  glyph->glyphIndex = glyphIndex;
  glyph->position = position;
}

Mat2D glyphTransform(const ScriptedGlyph* glyph)
{
  return RawText::glyphTransform(*glyph->run, glyph->position);
}

// Text

int text_new(lua_State* L)
{
  auto context = static_cast<ScriptingContext*>(lua_getthreaddata(L));
  lua_newrive<ScriptedText>(L)->layout = make_rcp<ScriptedTextLayout>(
      context->factory());
  return 1;
}

// Reads one field of an append style table, leaving the stack as it was.
template <typename F>
void withField(lua_State* L, int table, const char* name, F f)
{
  lua_rawgetfield(L, table, name);
  if (!lua_isnil(L, -1))
  {
    f(lua_gettop(L));
  }
  lua_pop(L, 1);
}

int text_append(lua_State* L)
{
  RawText& text = checkLayout(L, 1)->text;
  size_t length;
  const char* chars = luaL_checklstring(L, 2, &length);
  luaL_checktype(L, 3, LUA_TTABLE);

  rcp<Font> font;
  rcp<RenderPaint> paint;
  float size = 16.0f, lineHeight = -1.0f, letterSpacing = 0.0f;
  ColorInt foreground = 0xFF000000;
  withField(L, 3, "font", [&](int i) {
    font = lua_torive<ScriptedFont>(L, i)->font;
  });
  withField(L, 3, "paint", [&](int i) {
    paint = lua_torive<ScriptedPaint>(L, i)->renderPaint;
  });
  withField(L, 3, "size", [&](int i) { size = (float)luaL_checknumber(L, i); });
  withField(L, 3, "lineHeight", [&](int i) {
    lineHeight = (float)luaL_checknumber(L, i);
  });
  withField(L, 3, "letterSpacing", [&](int i) {
    letterSpacing = (float)luaL_checknumber(L, i);
  });
  withField(L, 3, "foregroundColor", [&](int i) {
    foreground = luaL_checkunsigned(L, i);
  });
  if (font == nullptr)
  {
    luaL_error(L, "Text:append needs a font.");
  }
  text.append(
      std::string(chars, length),
      std::move(paint),
      std::move(font),
      size,
      lineHeight,
      letterSpacing,
      foreground);
  return 0;
}

int text_namecall(lua_State* L)
{
  int atom;
  const char* str = lua_namecallatom(L, &atom);
  auto scriptedText = lua_torive<ScriptedText>(L, 1);
  RawText& text = scriptedText->layout->text;
  switch (atom)
  {
    case (int)LuaAtoms::append:
      return text_append(L);
    case (int)LuaAtoms::clear:
      text.clear();
      return 0;
    case (int)LuaAtoms::draw:
    {
      auto renderer = lua_torive<ScriptedRenderer>(L, 2)->validate(L);
      auto paint = lua_torive<ScriptedPaint>(L, 3, true);
      text.render(renderer, paint ? paint->renderPaint : nullptr);
      return 0;
    }
    case (int)LuaAtoms::bounds:
    {
      AABB bounds = text.bounds();
      lua_pushvec2d(L, Vec2D(bounds.minX, bounds.minY));
      lua_pushvec2d(L, Vec2D(bounds.maxX, bounds.maxY));
      return 2;
    }
    case (int)LuaAtoms::line:
    {
      int index = luaL_checkinteger(L, 2);
      if (index < 1 || (size_t)index > text.orderedLines().size())
      {
        luaL_error(L, "line %d is out of range", index);
      }
      pushLine(L, scriptedText, (uint32_t)index - 1);
      return 1;
    }
    case (int)LuaAtoms::lines:
    {
      size_t count = text.orderedLines().size();
      lua_createtable(L, (int)count, 0);
      for (size_t i = 0; i < count; i++)
      {
        pushLine(L, scriptedText, (uint32_t)i);
        lua_rawseti(L, -2, (int)i + 1);
      }
      return 1;
    }
    case (int)LuaAtoms::hitTest:
    {
      const Vec2D* position = lua_checkvec2d(L, 2);
      TextLayoutView view = text.layoutView();
      lua_pushinteger(
          L,
          CursorPosition::fromTranslation(*position, view).codePointIndex() +
              1);
      return 1;
    }
    case (int)LuaAtoms::caret:
    {
      int index = luaL_checkinteger(L, 2);
      TextLayoutView view = text.layoutView();
      auto visual = CursorPosition::atIndex(index < 1 ? 0 : index - 1, view)
                        .visualPosition(view);
      if (!visual.found())
      {
        return 0;
      }
      lua_pushnumber(L, visual.x());
      lua_pushnumber(L, visual.top());
      lua_pushnumber(L, visual.bottom());
      return 3;
    }
    case (int)LuaAtoms::selectionRects:
    {
      int from = luaL_checkinteger(L, 2);
      int to = luaL_checkinteger(L, 3);
      TextLayoutView view = text.layoutView();
      Cursor cursor(
          CursorPosition::atIndex(from < 1 ? 0 : from - 1, view),
          CursorPosition::atIndex(to < 1 ? 0 : to - 1, view));
      std::vector<AABB> rects;
      cursor.selectionRects(rects, view);
      lua_createtable(L, (int)rects.size(), 0);
      int i = 1;
      for (const AABB& rect : rects)
      {
        lua_createtable(L, 0, 2);
        lua_pushvec2d(L, Vec2D(rect.minX, rect.minY));
        lua_setfield(L, -2, "min");
        lua_pushvec2d(L, Vec2D(rect.maxX, rect.maxY));
        lua_setfield(L, -2, "max");
        lua_rawseti(L, -2, i++);
      }
      return 1;
    }
  }
  luaL_error(L, "%s is not a valid method of %s", str, ScriptedText::luaName);
  return 0;
}

int text_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));
  }
  RawText& text = checkLayout(L, 1)->text;
  switch (atom)
  {
    case (int)LuaAtoms::sizing:
      return pushEnum(L, sizingNames, (int)text.sizing());
    case (int)LuaAtoms::overflow:
      return pushEnum(L, overflowNames, (int)text.overflow());
    case (int)LuaAtoms::align:
      return pushEnum(L, alignNames, text.alignIndex());
    case (int)LuaAtoms::wrap:
      return pushEnum(L, wrapNames, (int)text.wrap());
    case (int)LuaAtoms::wordBreak:
      return pushEnum(L, wordBreakNames, (int)text.wordBreak());
    case (int)LuaAtoms::origin:
      return pushEnum(L, originNames, (int)text.origin());
    case (int)LuaAtoms::direction:
      return pushEnum(L, directionNames, text.directionIndex());
    case (int)LuaAtoms::maxWidth:
      lua_pushnumber(L, text.maxWidth());
      return 1;
    case (int)LuaAtoms::maxHeight:
      lua_pushnumber(L, text.maxHeight());
      return 1;
    case (int)LuaAtoms::paragraphSpacing:
      lua_pushnumber(L, text.paragraphSpacing());
      return 1;
    case (int)LuaAtoms::length:
      lua_pushnumber(L, (double)text.length());
      return 1;
    case (int)LuaAtoms::isEmpty:
      lua_pushboolean(L, text.empty());
      return 1;
    case (int)LuaAtoms::lineCount:
      lua_pushnumber(L, (double)text.orderedLines().size());
      return 1;
  }
  luaL_error(L, "'%s' is not a valid index of %s", key, ScriptedText::luaName);
  return 0;
}

int text_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));
  }
  RawText& text = checkLayout(L, 1)->text;
  switch (atom)
  {
    case (int)LuaAtoms::sizing:
      text.sizingIndex(readEnum(L, 3, sizingNames, "TextSizing"));
      return 0;
    case (int)LuaAtoms::overflow:
      text.overflowIndex(readEnum(L, 3, overflowNames, "TextOverflow"));
      return 0;
    case (int)LuaAtoms::align:
      text.alignIndex(readEnum(L, 3, alignNames, "TextAlign"));
      return 0;
    case (int)LuaAtoms::wrap:
      text.wrapIndex(readEnum(L, 3, wrapNames, "TextWrap"));
      return 0;
    case (int)LuaAtoms::wordBreak:
      text.wordBreakIndex(readEnum(L, 3, wordBreakNames, "TextWordBreak"));
      return 0;
    case (int)LuaAtoms::origin:
      text.originIndex(readEnum(L, 3, originNames, "TextOrigin"));
      return 0;
    case (int)LuaAtoms::direction:
      text.directionIndex(readEnum(L, 3, directionNames, "TextDirection"));
      return 0;
    case (int)LuaAtoms::maxWidth:
      text.maxWidth((float)luaL_checknumber(L, 3));
      return 0;
    case (int)LuaAtoms::maxHeight:
      text.maxHeight((float)luaL_checknumber(L, 3));
      return 0;
    case (int)LuaAtoms::paragraphSpacing:
      text.paragraphSpacing((float)luaL_checknumber(L, 3));
      return 0;
  }
  luaL_error(L, "'%s' is not a valid index of %s", key, ScriptedText::luaName);
  return 0;
}

// TextLine

int line_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));
  }
  auto line = lua_torive<ScriptedTextLine>(L, 1);
  const OrderedLine& orderedLine = checkLine(L, line);
  switch (atom)
  {
    case (int)LuaAtoms::index:
      lua_pushinteger(L, line->index + 1);
      return 1;
    case (int)LuaAtoms::x:
      lua_pushnumber(L, orderedLine.startX());
      return 1;
    case (int)LuaAtoms::top:
      lua_pushnumber(L, line->layout->text.lineTop(line->index));
      return 1;
    case (int)LuaAtoms::baseline:
      lua_pushnumber(L, orderedLine.y());
      return 1;
    case (int)LuaAtoms::bottom:
      lua_pushnumber(L, orderedLine.bottom());
      return 1;
    case (int)LuaAtoms::width:
    {
      float width = 0.0f;
      line->layout->text.forEachGlyph(
          line->index,
          [&](const GlyphRun& run, uint32_t glyphIndex, Vec2D) {
            width += run.advances[glyphIndex];
            return true;
          });
      lua_pushnumber(L, width);
      return 1;
    }
    case (int)LuaAtoms::direction:
      return pushDirection(L, line->layout->text.lineDirection(line->index));
    case (int)LuaAtoms::firstIndex:
      lua_pushinteger(
          L,
          orderedLine.firstCodePointIndex(
              line->layout->text.layoutView().glyphLookup()) +
              1);
      return 1;
    case (int)LuaAtoms::lastIndex:
      lua_pushinteger(
          L,
          orderedLine.lastCodePointIndex(
              line->layout->text.layoutView().glyphLookup()) +
              1);
      return 1;
    case (int)LuaAtoms::glyphCount:
      lua_pushinteger(L, line->layout->text.lineGlyphCount(line->index));
      return 1;
  }
  luaL_error(
      L,
      "'%s' is not a valid index of %s",
      key,
      ScriptedTextLine::luaName);
  return 0;
}

int line_iter_next(lua_State* L)
{
  auto cursor = lua_torive<ScriptedGlyphCursor>(L, 1);
  checkFresh(L, cursor->layout.get(), cursor->revision);
  if (cursor->itr == cursor->end)
  {
    lua_pushnil(L);
    return 1;
  }
  const GlyphRun* run = cursor->itr.run();
  uint32_t glyphIndex = cursor->itr.glyphIndex();
  const Vec2D& offset = run->offsets[glyphIndex];
  float y = cursor->layout->text.orderedLines()[cursor->line].y();
  lua_pushinteger(L, luaL_checkinteger(L, 2) + 1);
  auto glyph = lua_newrive<ScriptedGlyph>(L);
  glyph->layout = cursor->layout;
  glyph->revision = cursor->revision;
  glyph->run = run;
  glyph->glyphIndex = glyphIndex;
  glyph->position = Vec2D(cursor->x + offset.x, y + offset.y);
  cursor->x += run->advances[glyphIndex];
  ++cursor->itr;
  return 2;
}

int line_namecall(lua_State* L)
{
  int atom;
  const char* str = lua_namecallatom(L, &atom);
  auto line = lua_torive<ScriptedTextLine>(L, 1);
  checkLine(L, line);
  switch (atom)
  {
    case (int)LuaAtoms::glyph:
    {
      int wanted = luaL_checkinteger(L, 2) - 1;
      int index = 0;
      bool pushed = false;
      line->layout->text.forEachGlyph(
          line->index,
          [&](const GlyphRun& run, uint32_t glyphIndex, Vec2D position) {
            if (index++ != wanted)
            {
              return true;
            }
            pushGlyph(L, line, run, glyphIndex, position);
            pushed = true;
            return false;
          });
      if (!pushed)
      {
        luaL_error(L, "glyph %d is out of range", wanted + 1);
      }
      return 1;
    }
    case (int)LuaAtoms::glyphs:
    {
      int count = 0;
      lua_createtable(
          L,
          (int)line->layout->text.lineGlyphCount(line->index),
          0);
      line->layout->text.forEachGlyph(
          line->index,
          [&](const GlyphRun& run, uint32_t glyphIndex, Vec2D position) {
            pushGlyph(L, line, run, glyphIndex, position);
            lua_rawseti(L, -2, ++count);
            return true;
          });
      return 1;
    }
  }
  luaL_error(
      L,
      "%s is not a valid method of %s",
      str,
      ScriptedTextLine::luaName);
  return 0;
}

// for _, glyph in line do
int line_iter(lua_State* L)
{
  auto line = lua_torive<ScriptedTextLine>(L, 1);
  const OrderedLine& orderedLine = checkLine(L, line);
  lua_pushcfunction(L, line_iter_next, "TextLine.iter");
  auto cursor = lua_newrive<ScriptedGlyphCursor>(L);
  cursor->layout = line->layout;
  cursor->revision = line->revision;
  cursor->line = line->index;
  cursor->itr = orderedLine.begin();
  cursor->end = orderedLine.end();
  cursor->x = orderedLine.startX();
  lua_pushinteger(L, 0);
  return 3;
}

// Glyph

const ScriptedGlyph* checkGlyph(lua_State* L)
{
  auto glyph = lua_torive<ScriptedGlyph>(L, 1);
  checkFresh(L, glyph->layout.get(), glyph->revision);
  return glyph;
}

int glyph_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));
  }
  const ScriptedGlyph* glyph = checkGlyph(L);
  const GlyphRun* run = glyph->run;
  switch (atom)
  {
    case (int)LuaAtoms::id:
      lua_pushinteger(L, run->glyphs[glyph->glyphIndex]);
      return 1;
    case (int)LuaAtoms::font:
      lua_pushfont(L, run->font);
      return 1;
    case (int)LuaAtoms::size:
      lua_pushnumber(L, run->size);
      return 1;
    case (int)LuaAtoms::x:
      lua_pushnumber(L, glyph->position.x);
      return 1;
    case (int)LuaAtoms::y:
      lua_pushnumber(L, glyph->position.y);
      return 1;
    case (int)LuaAtoms::advance:
      lua_pushnumber(L, run->advances[glyph->glyphIndex]);
      return 1;
    case (int)LuaAtoms::textIndex:
      lua_pushinteger(L, run->textIndices[glyph->glyphIndex] + 1);
      return 1;
    case (int)LuaAtoms::direction:
      return pushDirection(L, run->dir());
    case (int)LuaAtoms::isColor:
      lua_pushboolean(
          L,
          run->font->isColorGlyph(run->glyphs[glyph->glyphIndex]));
      return 1;
    case (int)LuaAtoms::transform:
      lua_newrive<ScriptedMat2D>(L, glyphTransform(glyph));
      return 1;
  }
  luaL_error(L, "'%s' is not a valid index of %s", key, ScriptedGlyph::luaName);
  return 0;
}

int glyph_namecall(lua_State* L)
{
  int atom;
  const char* str = lua_namecallatom(L, &atom);
  const ScriptedGlyph* glyph = checkGlyph(L);
  const GlyphRun* run = glyph->run;
  switch (atom)
  {
    case (int)LuaAtoms::path:
    {
      Mat2D transform = glyphTransform(glyph);
      RawPath path;
      path.addPath(
          RawText::glyphPath(*run->font, run->glyphs[glyph->glyphIndex]),
          &transform);
      lua_newrive<ScriptedPath>(L, &path);
      return 1;
    }
  }
  luaL_error(L, "%s is not a valid method of %s", str, ScriptedGlyph::luaName);
  return 0;
}

const luaL_Reg textStaticMethods[] = {
    {"new", text_new},
    {NULL, NULL},
};

} // namespace

int luaopen_rive_text(lua_State* L)
{
  luaL_register(L, ScriptedText::luaName, textStaticMethods);
  lua_register_rive_type<ScriptedText>(
      L,
      text_index,
      text_namecall,
      text_newindex,
      nullptr);
  lua_register_rive_type<ScriptedTextLine>(
      L,
      line_index,
      line_namecall,
      nullptr,
      line_iter);
  lua_register_rive_type<ScriptedGlyph>(
      L,
      glyph_index,
      glyph_namecall,
      nullptr,
      nullptr);
  lua_register_rive<ScriptedGlyphCursor>(L);
  return 1;
}
#elif defined(WITH_RIVE_SCRIPTING)
struct lua_State;
int luaopen_rive_text(lua_State*) { return 0; }
#endif
