#include "rive/shapes/shape.hpp"
#include "rive/shapes/clipping_shape.hpp"
#include "rive/shapes/paint/blend_mode.hpp"
#include "rive/shapes/paint/shape_paint.hpp"
#include "rive/shapes/path_composer.hpp"
#include <algorithm>

using namespace rive;

Shape::Shape() : m_PathComposer(this) {}

void Shape::addPath(Path* path) {
    // Make sure the path is not already in the shape.
    assert(std::find(m_Paths.begin(), m_Paths.end(), path) == m_Paths.end());
    m_Paths.push_back(path);
}

void Shape::update(ComponentDirt value) {
    Super::update(value);

    if (hasDirt(value, ComponentDirt::RenderOpacity)) {
        for (auto shapePaint : m_ShapePaints) {
            shapePaint->renderOpacity(renderOpacity());
        }
    }
}

void Shape::pathChanged() {
    m_PathComposer.addDirt(ComponentDirt::Path, true);
    invalidateStrokeEffects();
}

void Shape::draw(Renderer* renderer) {
    if (renderOpacity() == 0.0f) {
        return;
    }
    auto shouldRestore = clip(renderer);

    for (auto shapePaint : m_ShapePaints) {
        if (!shapePaint->isVisible()) {
            continue;
        }
        renderer->save();
        bool paintsInLocal =
            (shapePaint->pathSpace() & PathSpace::Local) == PathSpace::Local;
        if (paintsInLocal) {
            renderer->transform(worldTransform());
        }
        shapePaint->draw(renderer,
                         paintsInLocal ? m_PathComposer.localPath()
                                       : m_PathComposer.worldPath());
        renderer->restore();
    }

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

void Shape::buildDependencies() {
    // Make sure to propagate the call to PathComposer as it's no longer part of
    // Core and owned only by the Shape.
    m_PathComposer.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.
    for (auto paint : m_ShapePaints) {
        paint->blendMode(blendMode());
    }
}

void Shape::addDefaultPathSpace(PathSpace space) {
    m_DefaultPathSpace |= space;
}

StatusCode Shape::onAddedDirty(CoreContext* context) {
    auto code = Super::onAddedDirty(context);
    if (code != StatusCode::Ok) {
        return code;
    }
    // This ensures context propagates to path composer too.
    return m_PathComposer.onAddedDirty(context);
}
