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