#include "rive/text/text_style_paint.hpp"
#include "rive/text/text.hpp"
#include "rive/text/text_variation_helper.hpp"
#include "rive/shapes/paint/shape_paint.hpp"
#include "rive/shapes/paint/fill.hpp"
#include "rive/shapes/paint/solid_color.hpp"
#include "rive/shapes/paint/feather.hpp"
#include "rive/artboard.hpp"
#include "rive/factory.hpp"

using namespace rive;

TextStylePaint::TextStylePaint() : m_path(true, FillRule::clockwise) {}

void TextStylePaint::rewindPath()
{
    m_path.rewind();
    m_hasContents = false;
    m_opacityPaths.clear();
}

bool TextStylePaint::addPath(const RawPath& rawPath, float opacity)
{
    bool hadContents = m_hasContents;
    m_hasContents = true;
    if (opacity > 0.0f)
    {

        // m_path contains everything, so inner feather bounds can work.
        m_path.addPathClockwise(rawPath);

        // Bucket by opacity
        auto itr = m_opacityPaths.find(opacity);
        ShapePaintPath* shapePaintPath = nullptr;
        if (itr != m_opacityPaths.end())
        {
            ShapePaintPath& path = itr->second;
            shapePaintPath = &path;
        }
        else
        {
            m_opacityPaths[opacity] = ShapePaintPath(true, FillRule::clockwise);
            shapePaintPath = &m_opacityPaths.at(opacity);
        }
        shapePaintPath->addPathClockwise(rawPath);
    }

    return !hadContents;
}

void TextStylePaint::draw(Renderer* renderer, const Mat2D& worldTransform)
{
    for (auto shapePaint : m_ShapePaints)
    {
        if (!shapePaint->shouldDraw())
        {
            continue;
        }
        shapePaint->blendMode(parent()->as<Text>()->blendMode());

        // For blend modes to work, opaque paths render first
        auto itr = m_opacityPaths.find(1.0f);
        if (itr != m_opacityPaths.end())
        {
            ShapePaintPath& path = itr->second;
            shapePaint->draw(renderer, &path, worldTransform, true);
        }

        if (m_paintPool.size() < m_opacityPaths.size())
        {
            m_paintPool.reserve(m_opacityPaths.size());
            Factory* factory = artboard()->factory();
            while (m_paintPool.size() < m_opacityPaths.size())
            {
                m_paintPool.emplace_back(factory->makeRenderPaint());
            }
        }

        uint32_t paintIndex = 0;
        for (itr = m_opacityPaths.begin(); itr != m_opacityPaths.end(); itr++)
        {
            // Don't render opaque paths twice
            if (itr->first == 1.0f)
            {
                continue;
            }
            RenderPaint* renderPaint = m_paintPool[paintIndex++].get();
            shapePaint->applyTo(renderPaint, itr->first);
            if (auto feather = shapePaint->feather())
            {
                renderPaint->feather(feather->strength());
            }
            ShapePaintPath& path = itr->second;
            shapePaint->draw(renderer,
                             &path,
                             worldTransform,
                             true,
                             renderPaint);
        }
    }
}

ColorInt TextStylePaint::foregroundColor() const
{
    for (auto shapePaint : m_ShapePaints)
    {
        if (shapePaint->is<Fill>() && shapePaint->paint()->is<SolidColor>())
        {
            return (ColorInt)shapePaint->paint()
                ->as<SolidColor>()
                ->colorValue();
        }
    }
    return 0xFF000000;
}

const Mat2D& TextStylePaint::shapeWorldTransform() const
{
    return parent()->as<Text>()->shapeWorldTransform();
}

Component* TextStylePaint::pathBuilder() { return parent(); }

Core* TextStylePaint::clone() const
{
    TextStylePaint* twin = TextStylePaintBase::clone()->as<TextStylePaint>();
    if (m_fileAsset != nullptr)
    {
        twin->setAsset(m_fileAsset);
    }

    return twin;
}
