
#include "rive/foreground_layout_drawable.hpp"
#include "rive/layout_component.hpp"
#include "rive/shapes/paint/fill.hpp"
#include "rive/shapes/paint/stroke.hpp"

using namespace rive;

void ForegroundLayoutDrawable::buildDependencies()
{
    Super::buildDependencies();
    // Set the blend mode on all the shape paints. If we ever animate this
    // property, we'll need to update it in the update cycle/mark dirty when the
    // blend mode changes.
    auto parentLayout = (parent()->as<LayoutComponent>());
    if (parentLayout != nullptr)
    {
        parentLayout->registerForegroundDrawable();
        for (auto paint : m_ShapePaints)
        {
            paint->blendMode(parentLayout->blendMode());
        }
    }
}

void ForegroundLayoutDrawable::update(ComponentDirt value)
{
    Super::update(value);
    auto parentLayout = (parent()->as<LayoutComponent>());
    if (parentLayout != nullptr)
    {
        if (hasDirt(value, ComponentDirt::RenderOpacity))
        {
            propagateOpacity(parentLayout->childOpacity());
        }
        if (hasDirt(value, ComponentDirt::Path | ComponentDirt::WorldTransform))
        {
            invalidateStrokeEffects();
        }
    }
}

void ForegroundLayoutDrawable::draw(Renderer* renderer)
{
    auto parentLayoutComponent = (parent()->as<LayoutComponent>());

    for (auto shapePaint : m_ShapePaints)
    {
        if (!shapePaint->shouldDraw())
        {
            continue;
        }
        auto shapePaintPath = shapePaint->pickPath(parentLayoutComponent);
        if (shapePaintPath == nullptr)
        {
            continue;
        }
        shapePaint->draw(renderer,
                         shapePaintPath,
                         parentLayoutComponent->worldTransform());
    }
}

Core* ForegroundLayoutDrawable::hitTest(HitInfo* hinfo, const Mat2D& xform)
{
    return nullptr;
}

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

ShapePaintPath* ForegroundLayoutDrawable::worldPath()
{
    return parent()->as<LayoutComponent>()->worldPath();
}

ShapePaintPath* ForegroundLayoutDrawable::localPath()
{
    return parent()->as<LayoutComponent>()->localPath();
}

ShapePaintPath* ForegroundLayoutDrawable::localClockwisePath()
{
    return parent()->as<LayoutComponent>()->localClockwisePath();
}