#include "rive/text/text.hpp"
#include "rive/text/text_modifier_range.hpp"
#include "rive/text/text_modifier_group.hpp"
#include "rive/text/text_value_run.hpp"
#include "rive/text/glyph_lookup.hpp"
#include "rive/animation/cubic_interpolator_component.hpp"
#include "rive/core_context.hpp"

using namespace rive;

StatusCode TextModifierRange::onAddedDirty(CoreContext* context)
{
    StatusCode code = Super::onAddedDirty(context);
    if (code != StatusCode::Ok)
    {
        return code;
    }

    if (runId() != Core::emptyId)
    {
        auto coreObject = context->resolve(runId());
        if (coreObject == nullptr || !coreObject->is<TextValueRun>())
        {
            return StatusCode::MissingObject;
        }
        m_run = static_cast<TextValueRun*>(coreObject);
    }

    if (parent() != nullptr && parent()->is<TextModifierGroup>())
    {
        parent()->as<TextModifierGroup>()->addModifierRange(this);
        return StatusCode::Ok;
    }

    return StatusCode::MissingObject;
}

void TextModifierRange::addChild(Component* component)
{
    Super::addChild(component);
    if (component->is<CubicInterpolatorComponent>())
    {
        // mark this as the cubic interpolator.
        m_interpolator = component->as<CubicInterpolatorComponent>();
    }
}

void TextModifierRange::clearRangeMap() { m_rangeMapper.clear(); }

void TextModifierRange::computeRange(
    Span<const Unichar> text,
    const SimpleArray<Paragraph>& shape,
    const SimpleArray<SimpleArray<GlyphLine>>& lines,
    const GlyphLookup& glyphLookup)
{
    // Check if the range mapper is still valid.
    if (!m_rangeMapper.empty())
    {
        return;
    }
    uint32_t start = 0;
    uint32_t end = (uint32_t)text.size();
    if (m_run != nullptr)
    {
        start = m_run->offset();
        end = start + m_run->length();
    }
    switch (units())
    {
        case TextRangeUnits::charactersExcludingSpaces:
            m_rangeMapper.fromCharacters(text, start, end, glyphLookup, true);
            break;
        case TextRangeUnits::words:
            m_rangeMapper.fromWords(text, start, end);
            break;
        case TextRangeUnits::lines:
            m_rangeMapper
                .fromLines(text, start, end, shape, lines, glyphLookup);
            break;
        default:
            m_rangeMapper.fromCharacters(text, start, end, glyphLookup);
            break;
    }
}

float TextModifierRange::coverageAt(float t)
{
    float c = 0.0f;
    if (m_indexTo >= m_indexFrom)
    {
        if (t < m_indexFrom || t > m_indexTo)
        {
            c = 0.0f;
        }
        else if (t < m_indexFalloffFrom)
        {
            float range = std::max(0.0f, m_indexFalloffFrom - m_indexFrom);
            c = range == 0.0f ? 1.0f : std::max(0.0f, t - m_indexFrom) / range;
            if (m_interpolator != nullptr)
            {
                c = m_interpolator->transform(c);
            }
        }
        else if (t > m_indexFalloffTo)
        {
            float range = std::max(0.0f, m_indexTo - m_indexFalloffTo);
            c = range == 0.0f
                    ? 1.0f
                    : 1.0f - std::min(1.0f, (t - m_indexFalloffTo) / range);
            if (m_interpolator != nullptr)
            {
                c = m_interpolator->transform(c);
            }
        }
        else
        {
            c = 1.0f;
        }
    }
    return c;
}

void TextModifierRange::computeCoverage(Span<float> coverage)
{
    if (m_rangeMapper.empty())
    {
        return;
    }

    // Compute range mapped coverage.
    uint32_t count = m_rangeMapper.unitCount();
    switch (type())
    {
        case TextRangeType::unitIndex:
            m_indexFrom = offsetModifyFrom();
            m_indexTo = offsetModifyTo();
            m_indexFalloffFrom = offsetFalloffFrom();
            m_indexFalloffTo = offsetFalloffTo();
            break;
        case TextRangeType::percentage:
            m_indexFrom = count * offsetModifyFrom();
            m_indexTo = count * offsetModifyTo();
            m_indexFalloffFrom = count * offsetFalloffFrom();
            m_indexFalloffTo = count * offsetFalloffTo();
            break;
    }

    TextRangeMode rangeMode = mode();
    for (uint32_t unitIndex = 0; unitIndex < count; unitIndex++)
    {
        uint32_t unitLength = (uint32_t)m_rangeMapper.unitLength(unitIndex);
        uint32_t characterIndex = m_rangeMapper.unitCharacterIndex(unitIndex);
        float c = strength() * coverageAt(unitIndex + 0.5f);
        for (uint32_t i = 0; i < unitLength; i++)
        {
            assert((characterIndex + i) < (uint32_t)coverage.size());
            float current = coverage[characterIndex + i];
            switch (rangeMode)
            {
                case TextRangeMode::add:
                    current += c;
                    break;
                case TextRangeMode::subtract:
                    current -= c;
                    break;
                case TextRangeMode::max:
                    current = std::max(current, c);
                    break;
                case TextRangeMode::min:
                    current = std::min(current, c);
                    break;
                case TextRangeMode::multiply:
                    current *= c;
                    break;
                case TextRangeMode::difference:
                    current = std::abs(current - c);
                    break;
            }
            coverage[characterIndex + i] =
                clamp() ? std::max(0.0f, std::min(1.0f, current)) : current;
        }

        // Set space between units coverage to 0.
        if (unitIndex + 1 < m_rangeMapper.unitCharacterIndexCount())
        {
            uint32_t nextCharacterIndex =
                m_rangeMapper.unitCharacterIndex(unitIndex + 1);
            for (uint32_t i = characterIndex + unitLength;
                 i < nextCharacterIndex;
                 i++)
            {
                coverage[i] = 0;
            }
        }
    }
}

void TextModifierRange::modifyFromChanged()
{
    parent()->as<TextModifierGroup>()->rangeChanged();
}
void TextModifierRange::modifyToChanged()
{
    parent()->as<TextModifierGroup>()->rangeChanged();
}
void TextModifierRange::strengthChanged()
{
    parent()->as<TextModifierGroup>()->rangeChanged();
}
void TextModifierRange::unitsValueChanged()
{
    parent()->as<TextModifierGroup>()->rangeTypeChanged();
}
void TextModifierRange::typeValueChanged()
{
    parent()->as<TextModifierGroup>()->rangeChanged();
}
void TextModifierRange::modeValueChanged()
{
    parent()->as<TextModifierGroup>()->rangeChanged();
}
void TextModifierRange::clampChanged()
{
    parent()->as<TextModifierGroup>()->rangeChanged();
}
void TextModifierRange::falloffFromChanged()
{
    parent()->as<TextModifierGroup>()->rangeChanged();
}
void TextModifierRange::falloffToChanged()
{
    parent()->as<TextModifierGroup>()->rangeChanged();
}
void TextModifierRange::offsetChanged()
{
    parent()->as<TextModifierGroup>()->rangeChanged();
}

bool TextModifierRange::needsShape() const
{
    return units() == TextRangeUnits::lines;
}

void RangeMapper::clear()
{
    m_unitCharacterIndices.clear();
    m_unitLengths.clear();
}

float RangeMapper::unitToCharacterRange(float word) const
{
    if (m_unitCharacterIndices.empty())
    {
        return 0.0f;
    }
    float clampedUnit = std::min(std::max(word, 0.0f),
                                 (float)(m_unitCharacterIndices.size() - 1));
    size_t intUnit = (size_t)clampedUnit;
    float characters = (float)m_unitCharacterIndices[intUnit];
    if (intUnit < m_unitLengths.size())
    {
        float fraction = clampedUnit - intUnit;
        characters += m_unitLengths[intUnit] * fraction;
    }
    return characters;
}

void RangeMapper::addRange(uint32_t indexFrom,
                           uint32_t indexTo,
                           uint32_t startOffset,
                           uint32_t endOffset)
{
    if (indexTo > startOffset && endOffset > indexFrom)
    {
        uint32_t actualStart = std::max(startOffset, indexFrom);
        uint32_t actualEnd = std::min(endOffset, indexTo);
        if (actualEnd > actualStart)
        {
            m_unitCharacterIndices.push_back(actualStart);
            m_unitLengths.push_back(actualEnd - actualStart);
        }
    }
}

void RangeMapper::fromWords(Span<const Unichar> text,
                            uint32_t start,
                            uint32_t end)
{
    if (text.empty())
    {
        return;
    }

    bool wantWhiteSpace = false;
    uint32_t characterCount = 0;
    uint32_t index = 0;
    uint32_t indexFrom = 0;
    for (Unichar unit : text)
    {
        if (wantWhiteSpace == isWhiteSpace(unit))
        {
            if (!wantWhiteSpace)
            {
                indexFrom = index;
            }
            else
            {
                addRange(indexFrom, indexFrom + characterCount, start, end);

                characterCount = 0;
            }
            wantWhiteSpace = !wantWhiteSpace;
        }
        if (wantWhiteSpace)
        {
            characterCount++;
        }
        index++;
    }
    if (characterCount > 0)
    {
        addRange(indexFrom, indexFrom + characterCount, start, end);
    }
    m_unitCharacterIndices.push_back(end);
}

void RangeMapper::fromCharacters(Span<const Unichar> text,
                                 uint32_t start,
                                 uint32_t end,
                                 const GlyphLookup& glyphLookup,
                                 bool withoutSpaces)
{
    if (text.empty())
    {
        return;
    }
    for (uint32_t i = start; i < end;)
    {
        Unichar unit = text[i];
        if (withoutSpaces && isWhiteSpace(unit))
        {
            i++;
            continue;
        }
        // Don't break ligated glyphs.
        uint32_t codePoints = glyphLookup.count(i);
        m_unitCharacterIndices.push_back(i);
        m_unitLengths.push_back(codePoints);
        i += codePoints;
    }

    m_unitCharacterIndices.push_back(end);
}

void RangeMapper::fromLines(Span<const Unichar> text,
                            uint32_t start,
                            uint32_t end,
                            const SimpleArray<Paragraph>& shape,
                            const SimpleArray<SimpleArray<GlyphLine>>& lines,
                            const GlyphLookup& glyphLookup)
{
    if (text.empty())
    {
        return;
    }
    uint32_t paragraphIndex = 0;
    for (const SimpleArray<GlyphLine>& paragraphLines : lines)
    {
        const Paragraph& paragraph = shape[paragraphIndex++];
        const SimpleArray<GlyphRun>& glyphRuns = paragraph.runs;
        for (const GlyphLine& line : paragraphLines)
        {
            const GlyphRun& rf = glyphRuns[line.startRunIndex];
            uint32_t indexFrom = rf.textIndices[line.startGlyphIndex];

            const GlyphRun& rt = glyphRuns[line.endRunIndex];
            uint32_t endGlyphIndex =
                line.endGlyphIndex == 0 ? 0 : line.endGlyphIndex - 1;
            uint32_t indexTo = rt.textIndices[endGlyphIndex];
            indexTo += glyphLookup.count(indexTo);

            addRange(indexFrom, indexTo, start, end);
        }
    }
    m_unitCharacterIndices.push_back(end);
}
