#include "rive/shapes/paint/shape_paint.hpp"
#include "rive/shapes/shape_paint_container.hpp"
#include "rive/shapes/paint/feather.hpp"
#include "rive/artboard.hpp"
#include "rive/factory.hpp"
#include "rive/shapes/paint/fill.hpp"

using namespace rive;

StatusCode ShapePaint::onAddedClean(CoreContext* context)
{
    auto container = ShapePaintContainer::from(parent());
    if (container == nullptr)
    {
        return StatusCode::MissingObject;
    }

    // If the paint mutator wasn't compatible with this runtime it's possible we
    // get a ShapePaint with no mutator (not children).
    if (m_PaintMutator != nullptr)
    {
        container->addPaint(this);
    }

    return StatusCode::Ok;
}

RenderPaint* ShapePaint::initRenderPaint(ShapePaintMutator* mutator)
{
    assert(m_RenderPaint == nullptr);
    m_PaintMutator = mutator;

    auto factory = mutator->component()->artboard()->factory();
    m_RenderPaint = factory->makeRenderPaint();
    return m_RenderPaint.get();
}

void ShapePaint::blendMode(BlendMode parentValue)
{
    assert(m_RenderPaint != nullptr);
    // 127 means inherit
    if (blendModeValue() == 127)
    {
        m_RenderPaint->blendMode(parentValue);
    }
    else
    {
        m_RenderPaint->blendMode((BlendMode)blendModeValue());
    }
}

void ShapePaint::feather(Feather* feather) { m_feather = feather; }

Feather* ShapePaint::feather() const { return m_feather; }

void ShapePaint::draw(Renderer* renderer,
                      ShapePaintPath* shapePaintPath,
                      const Mat2D& transform,
                      bool usePathFillRule,
                      RenderPaint* overridePaint)
{
    ShapePaintPath* pathToDraw = shapePaintPath;
    bool saved = false;
    if (m_feather != nullptr)
    {
        bool offsetInArtboard = m_feather->space() == TransformSpace::world;
        if (offsetInArtboard && !m_feather->inner())
        {
            if (m_feather->offsetX() != 0 || m_feather->offsetY() != 0)
            {
                if (!saved)
                {
                    saved = true;
                    renderer->save();
                }
                renderer->translate(m_feather->offsetX(), m_feather->offsetY());
            }
        }
    }
    if (shapePaintPath->isLocal())
    {
        if (!saved)
        {
            saved = true;
            renderer->save();
        }
        renderer->transform(transform);
    }

    if (m_feather != nullptr)
    {
        if (m_feather->inner())
        {
            if (m_feather->innerPath() == nullptr)
            {
                return;
            }
            pathToDraw = m_feather->innerPath();
            if (!saved)
            {
                saved = true;
                renderer->save();
            }
            auto renderPath = shapePaintPath->renderPath(this);
            if (renderPath != nullptr)
            {
                renderer->clipPath(renderPath);
            }
        }

        // If we're offseting in world space, apply the offset last.
        if (m_feather->space() != TransformSpace::world &&
            !m_feather->inner() &&
            (m_feather->offsetX() != 0 || m_feather->offsetY() != 0))
        {
            if (!saved)
            {
                saved = true;
                renderer->save();
            }
            renderer->translate(m_feather->offsetX(), m_feather->offsetY());
        }
    }

    auto renderPath = pathToDraw->renderPath(this);
    if (renderPath != nullptr)
    {
        // Ugh, can't we make fillRule part of the Paint?
        if (!usePathFillRule && is<Fill>())
        {
            renderPath->fillRule((FillRule)as<Fill>()->fillRule());
        }

        renderer->drawPath(renderPath,
                           overridePaint != nullptr ? overridePaint
                                                    : renderPaint());
    }

    if (saved)
    {
        renderer->restore();
    }
}