#ifdef WITH_RIVE_TEXT
#include "rive/text/raw_text.hpp"
#include "rive/text_engine.hpp"
#include "rive/factory.hpp"

using namespace rive;

RawText::RawText(Factory* factory) : m_factory(factory) {}
bool RawText::empty() const { return m_styled.empty(); }

void RawText::append(const std::string& text,
                     rcp<RenderPaint> paint,
                     rcp<Font> font,
                     float size,
                     float lineHeight,
                     float letterSpacing)
{
    int styleIndex = 0;
    for (RenderStyle& style : m_styles)
    {
        if (style.paint == paint)
        {
            break;
        }
        styleIndex++;
    }
    if (styleIndex == m_styles.size())
    {
        m_styles.push_back({paint, true});
    }
    m_styled.append(font, size, lineHeight, letterSpacing, text, styleIndex);
    m_dirty = true;
}

void RawText::clear()
{
    m_styled.clear();
    m_dirty = true;
}

TextSizing RawText::sizing() const { return m_sizing; }

TextOverflow RawText::overflow() const { return m_overflow; }

TextAlign RawText::align() const { return m_align; }

float RawText::maxWidth() const { return m_maxWidth; }

float RawText::maxHeight() const { return m_maxHeight; }

float RawText::paragraphSpacing() const { return m_paragraphSpacing; }

void RawText::sizing(TextSizing value)
{
    if (m_sizing != value)
    {
        m_sizing = value;
        m_dirty = true;
    }
}

void RawText::overflow(TextOverflow value)
{
    if (m_overflow != value)
    {
        m_overflow = value;
        m_dirty = true;
    }
}

void RawText::align(TextAlign value)
{
    if (m_align != value)
    {
        m_align = value;
        m_dirty = true;
    }
}

void RawText::paragraphSpacing(float value)
{
    if (m_paragraphSpacing != value)
    {
        m_paragraphSpacing = value;
        m_dirty = true;
    }
}

void RawText::maxWidth(float value)
{
    if (m_maxWidth != value)
    {
        m_maxWidth = value;
        m_dirty = true;
    }
}

void RawText::maxHeight(float value)
{
    if (m_maxHeight != value)
    {
        m_maxHeight = value;
        m_dirty = true;
    }
}

void RawText::update()
{
    for (RenderStyle& style : m_styles)
    {
        style.path.rewind();
        style.isEmpty = true;
    }
    m_renderStyles.clear();
    if (m_styled.empty())
    {
        return;
    }
    auto runs = m_styled.runs();

    m_shape = runs[0].font->shapeText(m_styled.unichars(), runs);
    m_lines =
        Text::BreakLines(m_shape,
                         m_sizing == TextSizing::autoWidth ? -1.0f : m_maxWidth,
                         m_align,
                         m_wrap);

    m_orderedLines.clear();
    m_ellipsisRun = {};

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

    // Build up ordered runs as we go.
    int paragraphIndex = 0;
    float y = 0.0f;
    float minY = 0.0f;
    float measuredWidth = 0.0f;
    if (m_origin == TextOrigin::baseline && !m_lines.empty() &&
        !m_lines[0].empty())
    {
        y -= m_lines[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 =
        m_overflow == TextOverflow::ellipsis && m_sizing == TextSizing::fixed;

    int lastLineIndex = -1;
    for (const SimpleArray<GlyphLine>& paragraphLines : m_lines)
    {
        const Paragraph& paragraph = m_shape[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];
            if (width > measuredWidth)
            {
                measuredWidth = width;
            }
            lastLineIndex++;
            if (wantEllipsis && y + line.bottom <= m_maxHeight)
            {
                ellipsisLine++;
            }
        }

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

    int lineIndex = 0;
    switch (m_sizing)
    {
        case TextSizing::autoWidth:
            m_bounds = AABB(0.0f,
                            minY,
                            measuredWidth,
                            std::max(minY, y - m_paragraphSpacing));
            break;
        case TextSizing::autoHeight:
            m_bounds = AABB(0.0f,
                            minY,
                            m_maxWidth,
                            std::max(minY, y - m_paragraphSpacing));
            break;
        case TextSizing::fixed:
            m_bounds = AABB(0.0f, minY, m_maxWidth, minY + m_maxHeight);
            break;
    }

    // Build the clip path if we want it.
    if (m_overflow == TextOverflow::clipped)
    {
        if (m_clipRenderPath == nullptr)
        {
            m_clipRenderPath = m_factory->makeEmptyRenderPath();
        }
        else
        {
            m_clipRenderPath->rewind();
        }

        m_clipRenderPath->addRect(m_bounds.minX,
                                  m_bounds.minY,
                                  m_bounds.width(),
                                  m_bounds.height());
    }
    else
    {
        m_clipRenderPath = nullptr;
    }

    y = 0;
    if (m_origin == TextOrigin::baseline && !m_lines.empty() &&
        !m_lines[0].empty())
    {
        y -= m_lines[0][0].baseline;
    }
    paragraphIndex = 0;

    for (const SimpleArray<GlyphLine>& paragraphLines : m_lines)
    {
        const Paragraph& paragraph = m_shape[paragraphIndex++];
        for (const GlyphLine& line : paragraphLines)
        {
            switch (m_overflow)
            {
                case TextOverflow::hidden:
                    if (m_sizing == TextSizing::fixed &&
                        y + line.bottom > m_maxHeight)
                    {
                        return;
                    }
                    break;
                case TextOverflow::clipped:
                    if (m_sizing == TextSizing::fixed &&
                        y + line.top > m_maxHeight)
                    {
                        return;
                    }
                    break;
                default:
                    break;
            }

            float renderY = y + line.baseline;
            if (lineIndex >= m_orderedLines.size())
            {
                // We need to still compute this line's ordered runs.
                m_orderedLines.emplace_back(
                    OrderedLine(paragraph,
                                line,
                                m_maxWidth,
                                ellipsisLine == lineIndex,
                                isEllipsisLineLast,
                                &m_ellipsisRun,
                                renderY));
            }

            const OrderedLine& orderedLine = m_orderedLines[lineIndex];
            float x = line.startX;

            for (auto glyphItr : orderedLine)
            {
                const GlyphRun* run = std::get<0>(glyphItr);
                size_t glyphIndex = std::get<1>(glyphItr);

                const Font* font = run->font.get();
                const Vec2D& offset = run->offsets[glyphIndex];

                GlyphID glyphId = run->glyphs[glyphIndex];
                float advance = run->advances[glyphIndex];

                RawPath path = font->getPath(glyphId);

                assert(run->styleId < m_styles.size());
                RenderStyle* style = &m_styles[run->styleId];
                assert(style != nullptr);

                Mat2D transform(run->size,
                                0.0f,
                                0.0f,
                                run->size,
                                x + offset.x,
                                renderY + offset.y);

                x += advance;
                style->path.addPathClockwise(path, &transform);

                if (style->isEmpty)
                {
                    // This was the first path added to the style, so let's mark
                    // it in our draw list.
                    style->isEmpty = false;

                    m_renderStyles.push_back(style);
                }
            }
            if (lineIndex == ellipsisLine)
            {
                return;
            }
            lineIndex++;
        }
        if (!paragraphLines.empty())
        {
            y += paragraphLines.back().bottom;
        }
        y += m_paragraphSpacing;
    }
}

AABB RawText::bounds()
{
    if (m_dirty)
    {
        update();
        m_dirty = false;
    }
    return m_bounds;
}

void RawText::render(Renderer* renderer, rcp<RenderPaint> paint)
{
    if (m_dirty)
    {
        update();
        m_dirty = false;
    }

    if (m_overflow == TextOverflow::clipped && m_clipRenderPath)
    {
        renderer->save();
        renderer->clipPath(m_clipRenderPath.get());
    }
    for (auto style : m_renderStyles)
    {
        auto renderPaint = paint ? paint.get() : style->paint.get();
        if (renderPaint != nullptr)
        {
            renderer->drawPath(style->path.renderPath(m_factory), renderPaint);
        }
    }
    if (m_overflow == TextOverflow::clipped && m_clipRenderPath)
    {
        renderer->restore();
    }
}
#endif
