#include "rive/text/cursor.hpp"
#ifdef WITH_RIVE_TEXT
using namespace rive;

static uint32_t absDiffUint(uint32_t a, uint32_t b)
{
  return a > b ? a - b : b - a;
}

static uint32_t subtractUint32(uint32_t a, uint32_t b)
{
  return a > b ? a - b : 0;
}

CursorVisualPosition CursorPosition::visualPosition(
    const TextLayoutView& shape) const
{
  const GlyphLookup& glyphLookup = shape.glyphLookup();
  const std::vector<OrderedLine>& orderedLines = shape.orderedLines();

  if (glyphLookup.empty() || m_codePointIndex > shape.textLength())
  {
    return CursorVisualPosition::missing();
  }
  uint32_t targetIndex = glyphLookup[m_codePointIndex];
  if (m_lineIndex < 0 || m_lineIndex >= orderedLines.size())
  {
    return CursorVisualPosition::missing();
  }
  const OrderedLine& orderedLine = orderedLines[m_lineIndex];

  float x = orderedLine.startX();

  // Iterate each glyph and see if it's the one we're looking for.
  bool haveFirstIndex = false;
  uint32_t firstTextIndex = 0, lastTextIndex = 0;
  for (auto glyphItr : orderedLine)
  {
    const GlyphRun* run = std::get<0>(glyphItr);
    size_t glyphIndex = std::get<1>(glyphItr);
    float advance = run->advances[glyphIndex];

    if (advance != 0 &&
        targetIndex == glyphLookup[run->textIndices[glyphIndex]])
    {
      x += advance * glyphLookup.advanceFactor(
                         m_codePointIndex,
                         run->dir() == TextDirection::rtl);

      const Font* font = run->font.get();
      return CursorVisualPosition(
          x,
          orderedLine.y() + font->ascent(run->size),
          orderedLine.y() + font->descent(run->size));
    }
    else
    {
      if (!haveFirstIndex)
      {
        firstTextIndex = lastTextIndex = run->textIndices[glyphIndex];
        haveFirstIndex = true;
      }
      else
      {
        lastTextIndex = run->textIndices[glyphIndex];
      }
      x += advance;
    }
  }

  // Didn't find the glyph, we're at the end of the line.
  const GlyphRun* run = orderedLine.lastRun();
  const Font* font = run->font.get();

  return CursorVisualPosition(
      absDiffUint(m_codePointIndex, firstTextIndex) <
              absDiffUint(m_codePointIndex, lastTextIndex)
          ? orderedLine.startX()
          : x,
      orderedLine.y() + font->ascent(run->size),
      orderedLine.y() + font->descent(run->size));
}

CursorPosition CursorPosition::fromTranslation(
    const Vec2D translation,
    const TextLayoutView& shape)
{
  const std::vector<OrderedLine>& orderedLines = shape.orderedLines();
  if (orderedLines.empty())
  {
    return CursorPosition::zero();
  }

  uint32_t lineIndex = 0;
  uint32_t maxLine = (uint32_t)(orderedLines.size() - 1);
  for (const OrderedLine& orderedLine : orderedLines)
  {
    if (orderedLine.bottom() < translation.y && lineIndex != maxLine)
    {
      lineIndex++;
      continue;
    }
    return fromOrderedLine(orderedLine, lineIndex, translation.x, shape);
  }

  return CursorPosition::zero();
}

CursorPosition CursorPosition::fromOrderedLine(
    const OrderedLine& orderedLine,
    uint32_t lineIndex,
    float translationX,
    const TextLayoutView& shape)
{
  const GlyphLookup& glyphLookup = shape.glyphLookup();

  // An empty line has no glyph to land after, so the cursor goes before its
  // line break; landing after it would put it at the start of the next line.
  uint32_t breakIndex;
  if (orderedLine.emptyLineCodePointIndex(breakIndex))
  {
    return CursorPosition(lineIndex, breakIndex).clamped(shape);
  }

  float x = orderedLine.startX();
  /// Iterate each glyph and see if it's the one we're looking for.
  auto end = orderedLine.end();
  GlyphItr lastGlyphItr = orderedLine.begin();
  for (GlyphItr itr = orderedLine.begin(); itr != end; ++itr)
  {
    lastGlyphItr = itr;
    const GlyphRun* run = itr.run();
    uint32_t glyphIndex = itr.glyphIndex();
    float advance = run->advances[glyphIndex];
    if (translationX <= x + advance)
    {
      float ratio = advance == 0.0f
                        ? 1.0f
                        : std::max(
                              0.0f,
                              std::min((translationX - x) / advance, 1.0f));
      uint32_t textIndex = run->textIndices[glyphIndex];
      uint32_t nextTextIndex = textIndex;
      uint32_t absoluteGlyphIndex = glyphLookup[textIndex];
      while (nextTextIndex != subtractUint32((uint32_t)glyphLookup.size(), 1) &&
             glyphLookup[nextTextIndex] == absoluteGlyphIndex)
      {
        nextTextIndex++;
      }
      uint32_t parts = nextTextIndex - textIndex;
      uint32_t part = (uint32_t)std::round(ratio * (float)parts);

      return CursorPosition(
                 lineIndex,
                 run->dir() == TextDirection::ltr
                     ? textIndex + part
                     : (part > nextTextIndex ? 0 : nextTextIndex - part))
          .clamped(shape);
    }
    else
    {
      x += advance;
    }
  }

  const GlyphRun* run = lastGlyphItr.run();
  uint32_t glyphIndex = lastGlyphItr.glyphIndex();

  uint32_t textIndex = run->textIndices[glyphIndex];
  uint32_t nextTextIndex = textIndex;
  uint32_t absoluteGlyphIndex = glyphLookup[textIndex];
  while (nextTextIndex != subtractUint32((uint32_t)glyphLookup.size(), 1) &&
         glyphLookup[nextTextIndex] == absoluteGlyphIndex)
  {
    nextTextIndex++;
  }
  uint32_t parts = nextTextIndex - textIndex;
  return CursorPosition(
             lineIndex,
             run->dir() == TextDirection::ltr ? textIndex + parts
                                              : nextTextIndex - parts)
      .clamped(shape);
}

CursorPosition CursorPosition::fromLineX(
    uint32_t lineIndex,
    float x,
    const TextLayoutView& shape)
{
  const std::vector<OrderedLine>& orderedLines = shape.orderedLines();
  if (lineIndex >= orderedLines.size())
  {
    return CursorPosition::zero();
  }

  return fromOrderedLine(orderedLines[lineIndex], lineIndex, x, shape);
}

uint32_t CursorPosition::lineIndex(int32_t inc) const
{
  if (inc < 0 && (uint32_t)(-inc) > m_lineIndex)
  {
    return 0;
  }
  return m_lineIndex + inc;
}

uint32_t CursorPosition::codePointIndex(int32_t inc) const
{
  if (inc < 0 && (uint32_t)(-inc) > m_codePointIndex)
  {
    return 0;
  }
  return m_codePointIndex + inc;
}

CursorPosition CursorPosition::clamped(const TextLayoutView& shape) const
{
  return CursorPosition(
      std::min(
          m_lineIndex,
          subtractUint32((uint32_t)shape.orderedLines().size(), 1)),
      std::min(m_codePointIndex, shape.textLength()));
}

CursorPosition CursorPosition::atIndex(
    uint32_t codePointIndex,
    const TextLayoutView& shape)
{
  // The layout owner defines its last selectable source offset.
  if (codePointIndex >= shape.textLength())
  {
    return CursorPosition(
        subtractUint32((uint32_t)shape.orderedLines().size(), 1),
        shape.textLength());
  }

  const SimpleArray<Paragraph>& paragraphs = shape.paragraphs();
  const SimpleArray<SimpleArray<GlyphLine>>&
      paragraphLines = shape.paragraphLines();

  uint32_t paragraphIndex = 0;
  uint32_t lineIndex = 0;
  for (const SimpleArray<GlyphLine>& lines : paragraphLines)
  {
    const Paragraph& paragraph = paragraphs[paragraphIndex++];
    for (const GlyphLine& line : lines)
    {
      const GlyphRun& run = paragraph.runs[line.startRunIndex];
      uint32_t smallestTextIndexInLine = run.textIndices[line.startGlyphIndex];

      if (smallestTextIndexInLine <= codePointIndex)
      {
        lineIndex++;
        continue;
      }
      return CursorPosition(lineIndex - 1, codePointIndex).clamped(shape);
    }
  }

  return CursorPosition(lineIndex - 1, codePointIndex).clamped(shape);
}

void Cursor::selectionRects(
    std::vector<AABB>& rects,
    const TextLayoutView& shape) const
{
  if (shape.orderedLines().empty() || shape.glyphLookup().empty())
  {
    return;
  }
  auto firstPosition = first().clamped(shape);
  auto lastPosition = last().clamped(shape);

  uint32_t firstLine = firstPosition.lineIndex();
  uint32_t lastLine = lastPosition.lineIndex();
  uint32_t firstCodePointIndex = firstPosition.codePointIndex();
  uint32_t lastCodePointIndex = lastPosition.codePointIndex();

  const GlyphLookup& glyphLookup = shape.glyphLookup();
  const std::vector<OrderedLine>& orderedLines = shape.orderedLines();
  for (uint32_t lineIndex = firstLine; lineIndex <= lastLine; lineIndex++)
  {
    const OrderedLine& orderedLine = orderedLines[lineIndex];
    float x = orderedLine.startX();
    for (auto glyphItr : orderedLine)
    {
      const GlyphRun* run = std::get<0>(glyphItr);
      size_t glyphIndex = std::get<1>(glyphItr);
      float advance = run->advances[glyphIndex];
      uint32_t codePointIndex = run->textIndices[glyphIndex];
      uint32_t count = glyphLookup.count(codePointIndex);
      uint32_t endCodePointIndex = codePointIndex + count;
      float y = orderedLine.y();

      // Check if this part of this glyph overlaps selection.
      if (lastCodePointIndex > codePointIndex &&
          endCodePointIndex > firstCodePointIndex)
      {
        uint32_t after = subtractUint32(firstCodePointIndex, codePointIndex);
        uint32_t before = subtractUint32(endCodePointIndex, lastCodePointIndex);
        float startFactor = (float)after / (float)count;
        float endFactor = (float)(count - before) / (float)count;
        if (run->dir() == TextDirection::rtl)
        {
          startFactor = 1.0f - startFactor;
          endFactor = 1.0f - endFactor;
        }

        auto font = run->font;
        float left = x + advance * startFactor;
        float right = x + advance * endFactor;
        if (left > right)
        {
          float swap = right;
          right = left;
          left = swap;
        }
        rects.push_back(AABB(
            left,
            y + font->ascent(run->size),
            right,
            y + font->descent(run->size)));
      }
      x += advance;
    }
  }
}

void Cursor::updateSelectionPath(
    ShapePaintPath& path,
    const std::vector<AABB>& rects,
    const TextLayoutView& shape) const
{}

bool Cursor::resolveLinePositions(const TextLayoutView& shape)
{
  bool resolved = false;
  if (!m_start.hasLineIndex())
  {
    m_start.resolveLine(shape);
    resolved = true;
  }
  if (!m_end.hasLineIndex())
  {
    m_end.resolveLine(shape);
    resolved = true;
  }
  return resolved;
}

void CursorPosition::resolveLine(const TextLayoutView& shape)
{
  const GlyphLookup& glyphLookup = shape.glyphLookup();
  const std::vector<OrderedLine>& orderedLines = shape.orderedLines();

  uint32_t lineIndex = 0;
  for (const OrderedLine& orderedLine : orderedLines)
  {
    if (orderedLine.containsCodePointIndex(glyphLookup, m_codePointIndex))
    {
      break;
    }
    lineIndex++;
  }
  m_lineIndex = lineIndex;
}

bool Cursor::contains(uint32_t codePointIndex) const
{
  return codePointIndex >= first().codePointIndex() &&
         codePointIndex < last().codePointIndex();
}
#endif