#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, m_factory->makeEmptyRenderPath(), 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;
    paragraphIndex = 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;
            }

            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));
            }

            const OrderedLine& orderedLine = m_orderedLines[lineIndex];
            float x = line.startX;
            float renderY = y + line.baseline;
            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);

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

                x += advance;

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

                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)
    {
        renderer->drawPath(style->path.get(),
                           paint ? paint.get() : style->paint.get());
    }
    if (m_overflow == TextOverflow::clipped && m_clipRenderPath)
    {
        renderer->restore();
    }
}
#endif
