#include "rive/core_context.hpp"
#include "rive/text/text.hpp"
#include "rive/text/text_style_paint.hpp"
#include "rive/text/text_value_run.hpp"
#include "rive/artboard.hpp"
#include "rive/hittest_command_path.hpp"
#include "rive/importers/artboard_importer.hpp"

using namespace rive;

void TextValueRun::textChanged()
{
    m_length = -1;
    textComponent()->markShapeDirty();
}

Text* TextValueRun::textComponent() const
{
    if (m_textComponent)
    {
        return m_textComponent;
    }
    return parent()->as<Text>();
}

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

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

    return StatusCode::MissingObject;
}

StatusCode TextValueRun::onAddedDirty(CoreContext* context)
{
    StatusCode code = Super::onAddedDirty(context);
    if (code != StatusCode::Ok)
    {
        return code;
    }
    auto coreObject = context->resolve(styleId());
    if (coreObject == nullptr || !coreObject->is<TextStylePaint>())
    {
        return StatusCode::MissingObject;
    }

    m_style = static_cast<TextStylePaint*>(coreObject);

    return StatusCode::Ok;
}

void TextValueRun::styleIdChanged()
{
    auto coreObject = artboard()->resolve(styleId());
    if (coreObject != nullptr && coreObject->is<TextStylePaint>())
    {
        m_style = static_cast<TextStylePaint*>(coreObject);
        textComponent()->markShapeDirty();
    }
}

uint32_t TextValueRun::offset() const
{
#ifdef WITH_RIVE_TEXT
    Text* text = textComponent();
    uint32_t offset = 0;

    for (TextValueRun* run : text->runs())
    {
        if (run == this)
        {
            break;
        }
        offset += run->length();
    }
    return offset;
#else
    return 0;
#endif
}

bool TextValueRun::canHitTest() const
{
    return (m_isHitTarget && textComponent() != nullptr &&
            !m_localBounds.isEmptyOrNaN());
}

void TextValueRun::resetHitTest()
{
    m_glyphHitRects.clear();
    m_localBounds = AABB::forExpansion();
}

void TextValueRun::addHitRect(const AABB& rect)
{
    AABB::expandTo(m_localBounds, rect.min());
    AABB::expandTo(m_localBounds, rect.max());
    m_glyphHitRects.push_back(rect);
}

void TextValueRun::computeHitContours()
{
    if (!m_rectanglesToContour)
    {
        m_rectanglesToContour = std::make_unique<RectanglesToContour>();
    }
    else
    {
        m_rectanglesToContour->reset();
    }
    for (const AABB& rect : m_glyphHitRects)
    {
        m_rectanglesToContour->addRect(rect);
    }
    m_rectanglesToContour->computeContours();
}

bool TextValueRun::hitTestAABB(const Vec2D& position)
{
    if (!canHitTest())
    {
        return false;
    }

    if (textComponent()->overflow() != TextOverflow::visible)
    {
        Mat2D inverseWorld;
        if (!textComponent()->worldTransform().invert(&inverseWorld))
        {
            return false;
        }

        if (!textComponent()->localBounds().contains(inverseWorld * position))
        {
            return false;
        }
    }

    Mat2D inverseWorld;
    Mat2D worldTransform =
        textComponent()->worldTransform() * textComponent()->m_transform;
    if (worldTransform.invert(&inverseWorld))
    {
        auto localWorld = inverseWorld * position;
        return m_localBounds.contains(localWorld);
    }

    return false;
}

bool TextValueRun::hitTestHiFi(const Vec2D& position, float hitRadius)
{
    if (!canHitTest())
    {
        return false;
    }

    auto hitArea = AABB(position.x - hitRadius,
                        position.y - hitRadius,
                        position.x + hitRadius,
                        position.y + hitRadius)
                       .round();
    HitTestCommandPath tester(hitArea);
    tester.setXform(textComponent()->worldTransform() *
                    textComponent()->m_transform);

    assert(m_rectanglesToContour != nullptr);
    for (auto contour : *m_rectanglesToContour)
    {
        assert(contour.begin() != contour.end());
        auto pointItr = contour.begin();
        auto end = contour.end();

        Vec2D firstPoint = *pointItr;
        tester.moveTo(firstPoint.x, firstPoint.y);

        while (++pointItr != end)
        {
            Vec2D point = *pointItr;
            tester.lineTo(point.x, point.y);
        }

        tester.close();
    }

    return tester.wasHit();
}

void TextValueRun::isHitTarget(bool value) { m_isHitTarget = value; }

bool TextValueRun::hitTestPoint(const Vec2D& position,
                                bool skipOnUnclipped,
                                bool isPrimaryHit)
{
    if (hitTestAABB(position) &&
        Component::hitTestPoint(position, skipOnUnclipped, isPrimaryHit))
    {
        return hitTestHiFi(position, 2);
    }
    return false;
}