/*
 * Copyright 2022 Rive
 */

#include "rive/text_engine.hpp"
#include <limits>
#include <algorithm>
using namespace rive;

static bool autowidth(float width) { return width < 0.0f; }

float GlyphLine::ComputeMaxWidth(
    Span<GlyphLine> lines,
    Span<const GlyphRun> runs)
{
  float maxLineWidth = 0.0f;
  for (auto& line : lines)
  {
    maxLineWidth = std::max(
        maxLineWidth,
        runs[line.endRunIndex].xpos[line.endGlyphIndex] -
            runs[line.startRunIndex].xpos[line.startGlyphIndex]);
  }
  return maxLineWidth;
}

static const rive::Font::LineMetrics computeLineMetrics(
    const rive::Font::LineMetrics& metrics,
    float customLineHeight,
    float fontSize)
{
  if (customLineHeight < 0.0f)
  {
    return {metrics.ascent * fontSize, metrics.descent * fontSize};
  }
  float baseline = -metrics.ascent;
  float height = baseline + metrics.descent;
  float baselineFactor = baseline / height;

  float actualAscent = -baselineFactor * customLineHeight;

  return {actualAscent, customLineHeight + actualAscent};
}

void GlyphLine::ComputeLineSpacing(
    bool isFirstLine,
    Span<GlyphLine> lines,
    Span<const GlyphRun> runs,
    float width,
    TextAlign align)
{
  bool first = isFirstLine;
  float Y = 0; // top of our frame
  for (auto& line : lines)
  {
    float asc = 0;
    float realAscent = 0;
    float des = 0;
    float lh = 0;
    for (uint32_t i = line.startRunIndex; i <= line.endRunIndex; ++i)
    {
      const auto& run = runs[i];
      const auto& metrics = computeLineMetrics(
          run.font->lineMetrics(),
          run.lineHeight,
          run.size);
      realAscent = std::min(
          realAscent,
          run.font->lineMetrics().ascent * run.size);
      asc = std::min(asc, metrics.ascent);
      des = std::max(des, metrics.descent);
      if (run.lineHeight >= 0.0f)
      {
        lh = std::max(lh, run.lineHeight);
      }
      else
      {
        lh = std::max(lh, -asc + des);
      }
    }
    line.top = Y;
    if (first)
    {
      Y = -realAscent;
      first = false;
    }
    else
    {
      Y -= asc;
    }
    line.baseline = Y;
    Y += des;
    line.bottom = Y;

    auto lineWidth = runs[line.endRunIndex].xpos[line.endGlyphIndex] -
                     runs[line.startRunIndex].xpos[line.startGlyphIndex];
    switch (align)
    {
      case TextAlign::right:
        line.startX = width - lineWidth;
        break;
      case TextAlign::left:
        line.startX = 0;
        break;
      case TextAlign::center:
        line.startX = width / 2.0f - lineWidth / 2.0f;
        break;
    }
  }
}

struct WordMarker
{
  const GlyphRun* run;
  uint32_t index;

  bool next(Span<const GlyphRun> runs)
  {
    index += 2;
    while (index >= run->breaks.size())
    {
      index -= run->breaks.size();
      run++;
      if (run == runs.end())
      {
        return false;
      }
    }
    return true;
  }
};

class RunIterator
{
  Span<const GlyphRun> m_runs;
  const GlyphRun* m_run;
  uint32_t m_index;

public:
  RunIterator(Span<const GlyphRun> runs, const GlyphRun* run, uint32_t index)
      : m_runs(runs)
      , m_run(run)
      , m_index(index)
  {}

  bool back()
  {
    if (m_index == 0)
    {
      if (m_run == m_runs.begin())
      {
        return false;
      }
      m_run--;
      if (m_run->glyphs.size() == 0)
      {
        m_index = 0;
        return back();
      }
      else
      {
        m_index = m_run->glyphs.size() == 0
                      ? 0
                      : (uint32_t)m_run->glyphs.size() - 1;
      }
    }
    else
    {
      m_index--;
    }
    // Never stop inside a glyph cluster.
    while (m_index > 0 &&
           m_run->textIndices[m_index] == m_run->textIndices[m_index - 1])
    {
      m_index--;
    }
    // If there are any word-joiners, do not break on them and find the
    // closest index that does not wrap a WJ
    if (m_run->joiners.size() > 0 && m_run->textIndices[m_index] > 0)
    {
      auto joiners = m_run->joiners;
      auto wordJoinerIndex = m_run->textIndices[m_index] - 1;
      size_t mid = 0;
      size_t start = 0;
      size_t end = joiners.size();
      // If this condition is not met, skip to avoid binary search
      if (wordJoinerIndex >= joiners[start] &&
          wordJoinerIndex < joiners[end - 1])
      {
        while (start < end)
        {
          mid = (start + end) >> 1;
          auto joinerCandidate = joiners[mid];
          if (joinerCandidate == wordJoinerIndex)
          {
            // we found that the previous text index is a joiner
            // now let's clean all indexes that are pointing to word
            // joiners
            bool isJoiner = true;
            auto currentJoinerIndex = mid;
            while (isJoiner)
            {
              if (m_index == 0)
              {
                return back();
              }
              // If the text index of the previous glyph is a
              // joiner, we need to skip it
              if (m_run->textIndices[m_index - 1] ==
                  joiners[currentJoinerIndex])
              {
                m_index--;
                if (currentJoinerIndex > 0)
                {
                  // we keep moving up the joiners list in
                  // case there are consecutive word joiners
                  currentJoinerIndex--;
                }
                else
                {
                  isJoiner = false;
                }
              }
              else
              {
                isJoiner = false;
              }
            }
            return back();
          }
          if (joinerCandidate < wordJoinerIndex)
          {
            start = mid + 1;
          }
          else
          {
            end = mid;
          }
        }
      }
    }
    return true;
  }

  bool forward()
  {
    if (m_index == m_run->glyphs.size())
    {
      if (m_run == m_runs.end())
      {
        return false;
      }
      m_run++;
      m_index = 0;
      if (m_index == m_run->glyphs.size())
      {
        return forward();
      }
    }
    else
    {
      m_index++;
    }
    while (m_index > 0 && m_index < m_run->glyphs.size() &&
           m_run->textIndices[m_index] == m_run->textIndices[m_index - 1])
    {
      m_index++;
    }
    if (m_run->joiners.size() > 0 && m_index < m_run->textIndices.size())
    {
      auto joiners = m_run->joiners;
      auto wordJoinerIndex = m_run->textIndices[m_index];
      size_t mid = 0;
      size_t start = 0;
      size_t end = joiners.size();
      // If this condition is not met, skip to avoid binary search
      if (wordJoinerIndex >= joiners[start] &&
          wordJoinerIndex < joiners[end - 1])
      {

        while (start < end)
        {
          mid = (start + end) >> 1;
          auto joinerCandidate = joiners[mid];
          if (joinerCandidate == wordJoinerIndex)
          {
            // we found that the next text index is a joiner
            // now let's clean all indexes that are pointing to word
            // joiners
            bool isJoiner = true;
            auto currentJoinerIndex = mid;
            while (isJoiner)
            {
              if (m_index == m_run->glyphs.size())
              {
                return forward();
              }
              // If the text index of the current glyph is a
              // joiner, we need to skip it
              if (currentJoinerIndex < joiners.size() &&
                  m_run->textIndices[m_index] == joiners[currentJoinerIndex])
              {
                m_index++;
                if (currentJoinerIndex < joiners.size())
                {
                  // we keep moving down the joiners list in
                  // case there are consecutive word joiners
                  currentJoinerIndex++;
                }
                else
                {
                  isJoiner = false;
                }
              }
              else
              {
                isJoiner = false;
              }
            }
            return forward();
          }
          if (joinerCandidate < wordJoinerIndex)
          {
            start = mid + 1;
          }
          else
          {
            end = mid;
          }
        }
      }
    }
    return true;
  }

  float x() const { return m_run->xpos[m_index]; }

  const GlyphRun* run() const { return m_run; }
  uint32_t index() const { return m_index; }

  bool operator==(const RunIterator& o) const
  {
    return m_run == o.m_run && m_index == o.m_index;
  }
};

SimpleArray<GlyphLine> GlyphLine::BreakLines(
    Span<const GlyphRun> runs,
    float width,
    TextWordBreak wordBreak)
{
  float maxLineWidth = autowidth(width) ? std::numeric_limits<float>::max()
                                        : width;

  SimpleArrayBuilder<GlyphLine> lines;

  if (runs.empty())
  {
    return lines;
  }

  auto limit = maxLineWidth;

  bool advanceWord = false;

  // We iterate the breaks list with a WordMarker helper which is
  // basically an iterator. The breaks lists contains tightly packed
  // start/end indices per run. So the first valid word is at break index
  // 0,1 (per run). Because a run can be created with no valid breaks, we
  // start the word iterator at a negative index and attempt to move it to
  // the first valid index (which could be in the Nth run in the
  // paragraph). If that fails, we know we have no words to break in the
  // entire paragraph and can early out. See how WordMarker::next works
  // and notice how we also use it below in this same method.
  WordMarker start = {runs.begin(), (uint32_t)-2};
  WordMarker end = {runs.begin(), (uint32_t)-1};
  if (!start.next(runs) || !end.next(runs))
  {
    return lines;
  }

  GlyphLine line = GlyphLine();

  uint32_t breakIndex = end.run->breaks[end.index];
  const GlyphRun* breakRun = end.run;
  uint32_t lastEndGlyphIndex = end.index;
  uint32_t startBreakIndex = start.run->breaks[start.index];
  const GlyphRun* startBreakRun = start.run;

  float x = end.run->xpos[breakIndex];
  while (true)
  {
    if (advanceWord)
    {
      lastEndGlyphIndex = end.index;

      if (!start.next(runs))
      {
        break;
      }
      if (!end.next(runs))
      {
        break;
      }

      advanceWord = false;

      breakIndex = end.run->breaks[end.index];
      breakRun = end.run;
      startBreakIndex = start.run->breaks[start.index];
      startBreakRun = start.run;
      x = end.run->xpos[breakIndex];
    }

    bool isForcedBreak = breakRun == startBreakRun &&
                         breakIndex == startBreakIndex;

    uint32_t startRunIndex = (uint32_t)(start.run - runs.begin());
    // Nothing has been placed on this line yet and it begins exactly at
    // this word, so the word is alone on its line and can't be knocked
    // any further down.
    bool wordStartsLine = line.startGlyphIndex == startBreakIndex &&
                          line.startRunIndex == startRunIndex;

    // TextWordBreak::normal never cuts a word: one that doesn't fit even
    // when alone on its line overflows the box instead, so treat it as if
    // it fit. Falling into the knock-to-a-new-line branch below would
    // spin forever -- it would rebuild an identical (empty) line and
    // never set advanceWord.
    bool overflows = !isForcedBreak && x > limit &&
                     !(wordBreak == TextWordBreak::normal && wordStartsLine);

    if (overflows)
    {
      // A whole word overflowed, break until we can no longer break
      // (or it fits). breakAll also cuts inside a word that isn't
      // alone on its line, but only once at least one cluster of it
      // still fits here. Without that bound the walk-back below -- which
      // has no lower bound, since the lineStart == lineEnd test is an
      // exact match -- could land in the whitespace *before* the word,
      // leaving the space on the end of this line (inflating the width
      // ComputeMaxWidth/ComputeLineSpacing derive from it) or at the
      // start of the next one. When not even one cluster fits we fall
      // through to knocking the whole word down, where wordStartsLine
      // becomes true and it gets cut normally.
      bool splitInsideWord = wordStartsLine;
      if (!splitInsideWord && wordBreak == TextWordBreak::breakAll)
      {
        RunIterator firstCluster(runs, start.run, startBreakIndex);
        splitInsideWord = firstCluster.forward() && firstCluster.x() <= limit;
      }
      if (splitInsideWord)
      {
        bool canBreakMore = true;
        while (canBreakMore && x > limit)
        {

          RunIterator lineStart = RunIterator(
              runs,
              runs.begin() + line.startRunIndex,
              line.startGlyphIndex);
          RunIterator lineEnd = RunIterator(
              runs,
              end.run,
              end.run->breaks[end.index]);
          // Look for the next character that doesn't overflow.
          while (true)
          {
            if (!lineEnd.back())
            {
              // Hit the start of the text, can't go back.
              canBreakMore = false;
              break;
            }
            else if (lineEnd.x() <= limit)
            {
              if (lineStart == lineEnd && !lineEnd.forward())
              {
                // Hit the start of the line and could not
                // go forward to consume a single character.
                // We can't break any further.
                canBreakMore = false;
              }
              else
              {
                line.endRunIndex = (uint32_t)(lineEnd.run() - runs.begin());
                line.endGlyphIndex = lineEnd.index();
              }
              break;
            }
          }
          if (canBreakMore)
          {
            // Add the line and push the limit out.
            limit = lineEnd.x() + maxLineWidth;
            if (!line.empty())
            {
              lines.add(line);
            }
            // Setup the next line.
            line = GlyphLine(
                (uint32_t)(lineEnd.run() - runs.begin()),
                lineEnd.index());
          }
        }
      }
      else
      {
        // word overflowed, knock it to a new line
        auto startX = start.run->xpos[start.run->breaks[start.index]];
        limit = startX + maxLineWidth;

        if (!line.empty() || start.index - lastEndGlyphIndex > 1)
        {
          lines.add(line);
        }

        line = GlyphLine(startRunIndex, startBreakIndex);
      }
    }
    else
    {
      line.endRunIndex = (uint32_t)(end.run - runs.begin());
      line.endGlyphIndex = end.run->breaks[end.index];
      advanceWord = true;
      // Forced BR.
      if (isForcedBreak)
      {
        lines.add(line);
        auto startX = start.run->xpos[start.run->breaks[start.index] + 1];
        limit = startX + maxLineWidth;
        line = GlyphLine(
            (uint32_t)(start.run - runs.begin()),
            startBreakIndex + 1);
      }
    }
  }

  // Add the last line.
  if (!line.empty())
  {
    lines.add(line);
  }

  return lines;
}
