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

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