#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); }

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)
		{
			const Mat2D& transform = worldTransform();
			renderer->transform(transform);
		}
		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);
}