#ifdef WITH_RIVE_TEXT
#include "rive/text/fully_shaped_text.hpp"
#include "rive/text/text.hpp"
#include <algorithm>
#include <limits>

using namespace rive;

void FullyShapedText::shape(
    Span<Unichar> text,
    Span<TextRun> runs,
    TextSizing sizing,
    float maxWidth,
    float maxHeight,
    TextAlign alignment,
    TextWrap wrap,
    TextOrigin origin,
    TextOverflow overflow,
    float paragraphSpacing,
    float alignWidth,
    VerticalTextAlign verticalAlignment,
    float alignHeight)
{
  m_verticalOffset = 0.0f;
  m_paragraphs = runs[0].font->shapeText(text, runs);
  m_glyphLookup.compute(text, m_paragraphs);

  m_paragraphLines = Text::BreakLines(
      m_paragraphs,
      sizing == TextSizing::autoWidth ? -1.0f : maxWidth,
      alignment,
      wrap,
      TextWordBreak::breakWord,
      alignWidth);
  m_orderedLines.clear();
  m_ellipsisRun = {};

  // build render styles.
  if (m_paragraphs.empty())
  {
    m_bounds = AABB(0.0f, 0.0f, 0.0f, 0.0f);
    return;
  }

  // Build up ordered runs as we go.
  int32_t paragraphIndex = 0;
  float y = 0.0f;
  float minY = 0.0f;
  // Lines don't start at 0 when they're aligned center/right, so track the
  // real horizontal extents rather than assuming [0, widest line].
  float minX = std::numeric_limits<float>::max();
  float maxX = -std::numeric_limits<float>::max();
  if (origin == TextOrigin::baseline && !m_paragraphLines.empty() &&
      !m_paragraphLines[0].empty())
  {
    y -= m_paragraphLines[0][0].baseline;
    minY = y;
  }

  int ellipsisLine = -1;
  bool isEllipsisLineLast = false;
  // Find the line to put the ellipsis on (line before the one that
  // overflows).
  bool wantEllipsis = overflow == TextOverflow::ellipsis &&
                      sizing == TextSizing::fixed;

  int lastLineIndex = -1;
  for (const SimpleArray<GlyphLine>& paragraphLines : m_paragraphLines)
  {
    const Paragraph& paragraph = m_paragraphs[paragraphIndex++];
    for (const GlyphLine& line : paragraphLines)
    {
      const GlyphRun& endRun = paragraph.runs[line.endRunIndex];
      const GlyphRun& startRun = paragraph.runs[line.startRunIndex];
      float width = endRun.xpos[line.endGlyphIndex] -
                    startRun.xpos[line.startGlyphIndex];
      minX = std::min(minX, line.startX);
      maxX = std::max(maxX, line.startX + width);
      lastLineIndex++;
      if (wantEllipsis && y + line.bottom <= maxHeight)
      {
        ellipsisLine++;
      }
    }

    if (!paragraphLines.empty())
    {
      y += paragraphLines.back().bottom;
    }
    y += paragraphSpacing;
  }
  if (wantEllipsis && ellipsisLine == -1)
  {
    // Nothing fits, just show the first line and ellipse it.
    ellipsisLine = 0;
  }
  isEllipsisLineLast = lastLineIndex == ellipsisLine;

  int32_t lineIndex = 0;
  if (minX > maxX)
  {
    // Paragraphs but no lines.
    minX = maxX = 0.0f;
  }
  float maxY = std::max(minY, y - paragraphSpacing);

  // Align the block within the field the same way lines align within it
  // horizontally: only while it fits, so text taller than the field stays
  // at the top and leaves vertical scrolling alone.
  float slack = alignHeight - (maxY - minY);
  if (slack > 0.0f)
  {
    switch (verticalAlignment)
    {
      case VerticalTextAlign::top:
        break;
      case VerticalTextAlign::middle:
        m_verticalOffset = slack / 2.0f;
        break;
      case VerticalTextAlign::bottom:
        m_verticalOffset = slack;
        break;
    }
  }

  m_bounds = AABB(minX, minY + m_verticalOffset, maxX, maxY + m_verticalOffset);

  // Left unshifted so the overflow checks below still measure the text
  // against the box; only the line positions carry the alignment offset.
  y = 0;
  if (origin == TextOrigin::baseline && !m_paragraphLines.empty() &&
      !m_paragraphLines[0].empty())
  {
    y -= m_paragraphLines[0][0].baseline;
  }
  paragraphIndex = 0;

  for (const SimpleArray<GlyphLine>& paragraphLines : m_paragraphLines)
  {
    const Paragraph& paragraph = m_paragraphs[paragraphIndex++];
    for (const GlyphLine& line : paragraphLines)
    {
      switch (overflow)
      {
        case TextOverflow::hidden:
          if (sizing == TextSizing::fixed && y + line.bottom > maxHeight)
          {
            return;
          }
          break;
        case TextOverflow::clipped:
          if (sizing == TextSizing::fixed && y + line.top > maxHeight)
          {
            return;
          }
          break;
        default:
          break;
      }

      m_orderedLines.emplace_back(OrderedLine(
          paragraph,
          line,
          maxWidth,
          alignment,
          ellipsisLine == lineIndex,
          isEllipsisLineLast,
          &m_ellipsisRun,
          y + line.baseline + m_verticalOffset));

      if (lineIndex == ellipsisLine)
      {
        return;
      }
      lineIndex++;
    }
    if (!paragraphLines.empty())
    {
      y += paragraphLines.back().bottom;
    }
    y += paragraphSpacing;
  }
  return;
}
#endif