#include "rive/constraints/scrolling/virtual_layout.hpp"
#include <cmath>

using namespace rive;

void VirtualLayout::beginLinear(float gap)
{
  m_itemCount = m_lineCount = 0;
  m_gap = gap;
  m_running = 0.0f;
  m_trailing = -std::numeric_limits<float>::infinity();
  m_lineOpen = false;
  m_wraps = false;
  m_grid = false;
  m_hugsLines = false;
  m_flowFromLayout = true;
  m_lineUsed.clear();
  m_lineStart.clear();
  m_lineExtent.clear();
  m_trailingMax.clear();
  m_lineFirstItem.clear();
  m_segmentStart.clear();
  m_itemExtent.clear();
  m_itemFlowExtent.clear();
  m_itemFlowOffset.clear();
  m_itemLineOffset.clear();
}

void VirtualLayout::beginWrap(
    float lineGap,
    float flowGap,
    float flowStart,
    float flowExtent,
    LayoutMainDistribute justify,
    LayoutCrossAlign align,
    bool hugsLines)
{
  beginLinear(lineGap);
  m_wraps = true;
  m_hugsLines = hugsLines;
  m_flowGap = flowGap;
  m_flowStart = flowStart;
  m_flowExtent = flowExtent;
  m_justify = justify;
  m_align = align;
}

void VirtualLayout::beginGrid(
    float rowGap,
    int columnCount,
    LayoutCrossAlign align,
    float columnGap,
    int rowCount)
{
  m_columnGap = columnGap;
  beginLinear(rowGap);
  m_wraps = true;
  m_grid = true;
  m_columnCount = std::max(1, columnCount);
  m_rowCount = rowCount;
  m_columnContents.assign(m_columnCount, 0.0f);
  m_columnStarts.clear();
  m_rowStarts.clear();
  m_align = align;
}

// Rows sit on layout's lines once it has sized every track from the row and
// column contents; rows it hasn't laid out yet stack at their content size.
void VirtualLayout::placeGridRows()
{
  // Template rows nothing fills still take their space.
  while (m_lineCount < m_rowCount)
  {
    pushLine(0.0f, 0.0f);
  }
  int n = m_lineCount;
  m_rowContents.assign(m_lineExtent.begin(), m_lineExtent.begin() + n);
  int lines = (int)m_rowStarts.size();
  m_running = 0.0f;
  m_trailing = -std::numeric_limits<float>::infinity();
  for (int line = 0; line < n; line++)
  {
    float start = m_running;
    float extent = m_rowContents[line];
    if (line + 1 < lines)
    {
      // The last line closes the last track; the others open one after
      // a gap.
      start = m_rowStarts[line] - m_rowStarts[0];
      extent = m_rowStarts[line + 1] - m_rowStarts[line] -
               (line + 2 < lines ? m_gap : 0.0f);
    }
    m_lineStart[line] = start;
    m_lineExtent[line] = extent;
    int last = line + 1 < n ? m_lineFirstItem[line + 1] : m_itemCount;
    for (int item = m_lineFirstItem[line]; item < last; item++)
    {
      // Yoga's grid centers an item in its row but reads the FlexEnd
      // that alignment writes as start; match it.
      float slack = extent - m_itemExtent[item];
      m_itemLineOffset[item] = m_align == LayoutCrossAlign::center
                                   ? slack / 2.0f
                                   : 0.0f;
    }
    m_trailing = std::max(m_trailing, start + extent);
    m_trailingMax[line] = m_trailing;
    m_running = start + extent + m_gap;
  }
}

void VirtualLayout::beginSegment() { m_segmentStart.push_back(m_itemCount); }

void VirtualLayout::pushLine(float start, float extent)
{
  m_lineStart.push_back(start);
  m_lineExtent.push_back(extent);
  m_lineFirstItem.push_back(m_itemCount);
  m_trailingMax.push_back(0.0f);
  if (m_wraps)
  {
    m_lineUsed.push_back(0.0f);
  }
  m_lineCount++;
}

void VirtualLayout::openLine()
{
  pushLine(m_running, 0.0f);
  m_lineOpen = true;
  m_lineFlowUsed = 0.0f;
}

void VirtualLayout::closeLine()
{
  int line = m_lineCount - 1;
  int first = m_lineFirstItem[line];
  if (m_grid)
  {
    // Rows are placed once all are known (see placeGridRows); until
    // then a row's extent is its tallest item.
    for (int item = first; item < m_itemCount; item++)
    {
      int column = item - first;
      m_columnContents[column] = std::max(
          m_columnContents[column],
          m_itemFlowExtent[item]);
      m_itemFlowOffset[item] = column < (int)m_columnStarts.size()
                                   ? m_columnStarts[column]
                                   : 0.0f;
    }
    m_lineOpen = false;
    return;
  }
  float lineExtent = m_lineExtent[line];

  m_lineUsed[line] = m_lineFlowUsed;
  for (int item = first; item < m_itemCount; item++)
  {
    float slack = lineExtent - m_itemExtent[item];
    m_itemLineOffset[item] = m_align == LayoutCrossAlign::start ? 0.0f
                             : m_align == LayoutCrossAlign::center
                                 ? slack / 2.0f
                                 : slack;
  }
  // Hugging content is as wide as its widest line, known only at end().
  if (!m_hugsLines)
  {
    placeLine(line, m_flowExtent);
  }

  m_trailing = std::max(m_trailing, m_lineStart[line] + lineExtent);
  m_trailingMax[line] = m_trailing;
  m_running = m_lineStart[line] + lineExtent + m_gap;
  m_lineOpen = false;
}

void VirtualLayout::placeLine(int line, float extent)
{
  int first = m_lineFirstItem[line];
  int last = line + 1 < (int)m_lineFirstItem.size() && line + 1 < m_lineCount
                 ? m_lineFirstItem[line + 1]
                 : m_itemCount;
  int count = last - first;
  float freeSpace = extent - m_lineUsed[line];
  float lead = 0.0f;
  float between = m_flowGap;
  switch (m_justify)
  {
    case LayoutMainDistribute::start:
      break;
    case LayoutMainDistribute::center:
      lead = freeSpace / 2.0f;
      break;
    case LayoutMainDistribute::end:
      lead = freeSpace;
      break;
    case LayoutMainDistribute::spaceBetween:
      if (count > 1)
      {
        between += std::max(freeSpace, 0.0f) / (count - 1);
      }
      break;
  }
  float flow = m_flowStart + lead;
  for (int item = first; item < last; item++)
  {
    m_itemFlowOffset[item] = flow;
    flow += m_itemFlowExtent[item] + between;
  }
}

void VirtualLayout::addItem(float extent, float flowExtent)
{
  if (!m_wraps)
  {
    pushLine(m_running, extent);
    m_trailing = std::max(m_trailing, m_running + extent);
    m_trailingMax.back() = m_trailing;
    m_running += extent + m_gap;
    m_itemCount++;
    return;
  }
  // Flex wrap breaks before an item that would overflow a non-empty line;
  // a grid row breaks once its columns are full.
  if (m_lineOpen &&
      (m_grid ? m_itemCount - m_lineFirstItem[m_lineCount - 1] >= m_columnCount
              : m_lineFlowUsed + m_flowGap + flowExtent > m_flowExtent))
  {
    closeLine();
  }
  if (!m_lineOpen)
  {
    openLine();
    m_lineFlowUsed = flowExtent;
  }
  else
  {
    m_lineFlowUsed += m_flowGap + flowExtent;
  }
  int line = m_lineCount - 1;
  m_lineExtent[line] = std::max(m_lineExtent[line], extent);
  m_itemExtent.push_back(extent);
  m_itemFlowExtent.push_back(flowExtent);
  m_itemFlowOffset.push_back(0.0f);
  m_itemLineOffset.push_back(0.0f);
  m_itemCount++;
}

void VirtualLayout::end()
{
  if (m_lineOpen)
  {
    closeLine();
  }
  if (m_grid)
  {
    placeGridRows();
  }
  m_lineFirstItem.push_back(m_itemCount);
  m_startSuffixMin.resize(m_lineCount);
  // Gaps more negative than a line is long start later lines before
  // earlier ones; the lowest start from each line on finds the last line
  // starting before a point anyway.
  float lowest = std::numeric_limits<float>::infinity();
  for (int line = m_lineCount - 1; line >= 0; line--)
  {
    lowest = std::min(lowest, m_lineStart[line]);
    m_startSuffixMin[line] = lowest;
  }
  if (m_wraps && !m_grid && m_hugsLines)
  {
    float widest = 0.0f;
    for (int line = 0; line < m_lineCount; line++)
    {
      widest = std::max(widest, m_lineUsed[line]);
    }
    for (int line = 0; line < m_lineCount; line++)
    {
      placeLine(line, widest);
    }
  }
}

float VirtualLayout::itemFlowOffset(int item) const
{
  return m_wraps ? m_itemFlowOffset[item] : 0.0f;
}

float VirtualLayout::itemLineOffset(int item) const
{
  return m_wraps ? m_itemLineOffset[item] : 0.0f;
}

int VirtualLayout::segmentOf(int item) const
{
  // Last segment starting at or before the item; empty segments share a
  // start with the next one, so take the last match.
  auto it = std::upper_bound(
      m_segmentStart.begin(),
      m_segmentStart.end(),
      item);
  return (int)(it - m_segmentStart.begin()) - 1;
}

float VirtualLayout::lineStart(int line) const
{
  int wrapped = wrapLine(line);
  int cycle = (line - wrapped) / m_lineCount;
  return cycle * cycleExtent() + m_lineStart[wrapped];
}

float VirtualLayout::lineExtent(int line) const
{
  return m_lineExtent[wrapLine(line)];
}

int VirtualLayout::lineFirstItem(int line) const
{
  return m_lineFirstItem[wrapLine(line)];
}

int VirtualLayout::lineLastItem(int line) const
{
  return m_lineFirstItem[wrapLine(line) + 1] - 1;
}

int VirtualLayout::lineOfItem(int item) const
{
  int lo = 0, hi = m_lineCount - 1;
  while (lo < hi)
  {
    int mid = (lo + hi + 1) >> 1;
    if (m_lineFirstItem[mid] <= item)
    {
      lo = mid;
    }
    else
    {
      hi = mid - 1;
    }
  }
  return lo;
}

int VirtualLayout::lastStartBefore(float value) const
{
  // The lowest start from each line on only grows, so the first line from
  // which every start is at or past value bounds the answer.
  int lo = 0, hi = m_lineCount;
  while (lo < hi)
  {
    int mid = (lo + hi) >> 1;
    if (m_startSuffixMin[mid] >= value)
    {
      hi = mid;
    }
    else
    {
      lo = mid + 1;
    }
  }
  return lo - 1;
}

int VirtualLayout::firstTrailingPast(float value, bool inclusive) const
{
  int lo = 0, hi = m_lineCount;
  while (lo < hi)
  {
    int mid = (lo + hi) >> 1;
    float edge = m_trailingMax[mid];
    if (edge > value || (inclusive && edge == value))
    {
      hi = mid;
    }
    else
    {
      lo = mid + 1;
    }
  }
  return lo;
}

VirtualWindow VirtualLayout::window(
    float offset,
    float viewport,
    bool infinite,
    int buffer) const
{
  int n = m_lineCount;
  if (n == 0)
  {
    return VirtualWindow();
  }
  // First line still on screen: its trailing edge is past the offset.
  int start = firstTrailingPast(offset);
  if (start == n)
  {
    // Only a carousel's trailing gap can be past every line; the next
    // cycle's first line is the one coming in.
    start = infinite ? n : n - 1;
  }

  // Last line on screen: the last one starting before the far edge.
  float limit = offset + viewport;
  int end;
  if (!infinite)
  {
    end = std::max(start, lastStartBefore(limit));
  }
  else
  {
    // The latest unwrapped line starting before it, at most a cycle on.
    int latest = -1;
    float cycle = cycleExtent();
    for (int c = 0; c <= 2; c++)
    {
      int found = lastStartBefore(limit - c * cycle);
      if (found >= 0)
      {
        latest = c * n + found;
      }
    }
    end = std::min(std::max(start, latest), start + n - 1);
  }

  VirtualWindow window;
  window.visibleStart = start;
  window.visibleEnd = end;
  bufferWindow(window, n, buffer, infinite);
  return window;
}

void VirtualLayout::bufferWindow(
    VirtualWindow& window,
    int count,
    int buffer,
    bool cycles)
{
  int start = window.visibleStart;
  int end = window.visibleEnd;
  window.start = start;
  window.end = end;
  if (buffer <= 0)
  {
    return;
  }
  int extra = std::max(0, count - (end - start + 1));
  int before = std::max(0, std::min(buffer, cycles ? extra : start));
  int after = std::max(
      0,
      std::min(buffer, cycles ? extra - before : count - 1 - end));
  window.start = start - before;
  window.end = end + after;
}

float VirtualLayout::columnCycleExtent() const
{
  int count = columnCount();
  if (!m_grid || (int)m_columnStarts.size() < count + 1)
  {
    return 0.0f;
  }
  return m_columnStarts[count] - m_columnStarts[0] + m_columnGap;
}

float VirtualLayout::columnStart(int column) const
{
  int wrapped = wrapColumn(column);
  if (wrapped >= (int)m_columnStarts.size())
  {
    return 0.0f;
  }
  int cycle = (column - wrapped) / columnCount();
  return cycle * columnCycleExtent() + m_columnStarts[wrapped];
}

VirtualWindow VirtualLayout::columnWindow(
    float offset,
    float viewport,
    int buffer,
    bool infinite) const
{
  VirtualWindow window;
  int count = columnCount();
  window.start = window.visibleStart = 0;
  window.end = window.visibleEnd = count - 1;
  // Column lines bound each column: count + 1 of them, gaps included.
  if (!m_grid || (int)m_columnStarts.size() < count + 1)
  {
    return window;
  }
  auto columnEnd = [&](int column) {
    return column < count - 1 ? m_columnStarts[column + 1] - m_columnGap
                              : m_columnStarts[count];
  };
  float cycle = infinite ? columnCycleExtent() : 0.0f;
  if (cycle <= 0.0f)
  {
    // As with lines: the first column whose trailing edge is past the
    // offset, through the last that starts before the far edge.
    int start = 0;
    while (start < count - 1 && columnEnd(start) <= offset)
    {
      start++;
    }
    int end = start;
    while (end < count - 1 && m_columnStarts[end + 1] < offset + viewport)
    {
      end++;
    }
    window.visibleStart = start;
    window.visibleEnd = end;
    bufferWindow(window, count, buffer, false);
    return window;
  }
  // Find the first column within the offset's cycle, then count on in
  // unwrapped columns; past the last column the next cycle's first is in.
  int k = (int)std::floor((offset - m_columnStarts[0]) / cycle);
  float local = offset - k * cycle;
  int start = 0;
  while (start < count && columnEnd(start) <= local)
  {
    start++;
  }
  start += k * count;
  // At most one cycle: each item is realized once.
  int end = start;
  while (end < start + count - 1 && columnStart(end + 1) < offset + viewport)
  {
    end++;
  }
  window.visibleStart = start;
  window.visibleEnd = end;
  bufferWindow(window, count, buffer, true);
  return window;
}
