/*
 * Copyright 2022 Rive
 */

#include "rive/text/line_breaker.hpp"

using namespace rive;

// Return the index for the run that contains the char at textOffset
static int _offsetToRunIndex(Span<const RenderGlyphRun> runs, size_t textOffset) {
    assert(textOffset >= 0);
    for (int i = 0; i < (int)runs.size() - 1; ++i) {
        if (textOffset <= runs[i].textOffsets.back()) {
            return i;
        }
    }
    return (int)runs.size() - 1;
}

static int textOffsetToGlyphIndex(const RenderGlyphRun& run, size_t textOffset) {
    assert(textOffset >= run.textOffsets.front());
    //    assert(textOffset <= run.textOffsets.back()); // not true for last run

    // todo: bsearch?
    auto begin = run.textOffsets.begin();
    auto end = run.textOffsets.end();
    auto iter = std::find(begin, end, textOffset);
    if (iter == end) { // end of run
        return (int)run.glyphs.size() - 1;
    }
    return (int)(iter - begin);
}

std::vector<RenderGlyphLine> RenderGlyphLine::BreakLines(Span<const RenderGlyphRun> runs,
                                                         Span<const int> breaks,
                                                         float width) {
    assert(breaks.size() >= 2);

    std::vector<RenderGlyphLine> lines;
    int startRun = 0;
    int startIndex = 0;
    double xlimit = width;

    int prevRun = 0;
    int prevIndex = 0;

    int wordStart = breaks[0];
    int wordEnd = breaks[1];
    size_t nextBreakIndex = 2;
    int lineStartTextOffset = wordStart;

    for (;;) {
        assert(wordStart <= wordEnd); // == means trailing spaces?

        int endRun = _offsetToRunIndex(runs, wordEnd);
        int endIndex = textOffsetToGlyphIndex(runs[endRun], wordEnd);
        float pos = runs[endRun].xpos[endIndex];
        bool bumpBreakIndex = true;
        if (pos > xlimit) {
            int wsRun = _offsetToRunIndex(runs, wordStart);
            int wsIndex = textOffsetToGlyphIndex(runs[wsRun], wordStart);

            bumpBreakIndex = false;
            // does just one word not fit?
            if (lineStartTextOffset == wordStart) {
                // walk backwards a letter at a time until we fit, stopping at
                // 1 letter.
                int wend = wordEnd;
                while (pos > xlimit && wend - 1 > wordStart) {
                    wend -= 1;
                    prevRun = _offsetToRunIndex(runs, wend);
                    prevIndex = textOffsetToGlyphIndex(runs[prevRun], wend);
                    pos = runs[prevRun].xpos[prevIndex];
                }
                assert(wend < wordEnd || wend == wordEnd && wordStart + 1 == wordEnd);
                if (wend == wordEnd) {
                    bumpBreakIndex = true;
                }

                // now reset our "whitespace" marker to just be prev, since
                // by defintion we have no extra whitespace on this line
                wsRun = prevRun;
                wsIndex = prevIndex;
                wordStart = wend;
            }

            // bulid the line
            const auto lineStartX = runs[startRun].xpos[startIndex];
            lines.push_back(RenderGlyphLine(startRun,
                                            startIndex,
                                            prevRun,
                                            prevIndex,
                                            wsRun,
                                            wsIndex,
                                            lineStartX));

            // update for the next line
            xlimit = runs[wsRun].xpos[wsIndex] + width;
            startRun = prevRun = wsRun;
            startIndex = prevIndex = wsIndex;
            lineStartTextOffset = wordStart;
        } else {
            // we didn't go too far, so remember this word-end boundary
            prevRun = endRun;
            prevIndex = endIndex;
        }

        if (bumpBreakIndex) {
            if (nextBreakIndex < breaks.size()) {
                wordStart = breaks[nextBreakIndex++];
                wordEnd = breaks[nextBreakIndex++];
            } else {
                break; // bust out of the loop
            }
        }
    }
    // scoop up the last line (if present)
    const int tailRun = (int)runs.size() - 1;
    const int tailIndex = (int)runs[tailRun].glyphs.size();
    if (startRun != tailRun || startIndex != tailIndex) {
        const auto startX = runs[startRun].xpos[startIndex];
        lines.push_back(
            RenderGlyphLine(startRun, startIndex, tailRun, tailIndex, tailRun, tailIndex, startX));
    }

    ComputeLineSpacing(lines, runs);

    return lines;
}

void RenderGlyphLine::ComputeLineSpacing(Span<RenderGlyphLine> lines,
                                         Span<const RenderGlyphRun> runs) {
    float Y = 0; // top of our frame
    for (auto& line : lines) {
        float asc = 0;
        float des = 0;
        for (int i = line.startRun; i <= line.wsRun; ++i) {
            const auto& run = runs[i];

            asc = std::min(asc, run.font->lineMetrics().ascent * run.size);
            des = std::max(des, run.font->lineMetrics().descent * run.size);
        }
        line.top = Y;
        Y -= asc;
        line.baseline = Y;
        Y += des;
        line.bottom = Y;
    }
    // TODO: good place to perform left/center/right alignment
}
