#include "rive/component.hpp"
#include "rive/artboard.hpp"
#include "rive/container_component.hpp"
#include "rive/core_context.hpp"
#include "rive/importers/artboard_importer.hpp"
#include "rive/importers/import_stack.hpp"
#include <algorithm>

using namespace rive;

StatusCode Component::onAddedDirty(CoreContext* context)
{
    m_Artboard = static_cast<Artboard*>(context);
    if (this == m_Artboard)
    {
        // We're the artboard, don't parent to ourselves.
        return StatusCode::Ok;
    }
    auto coreObject = context->resolve(parentId());
    if (coreObject == nullptr || !coreObject->is<ContainerComponent>())
    {
        return StatusCode::MissingObject;
    }
    m_Parent = reinterpret_cast<ContainerComponent*>(coreObject);
    return StatusCode::Ok;
}

void Component::addDependent(Component* component)
{
    // Make it's not already a dependent.
    if (std::find(m_Dependents.begin(), m_Dependents.end(), component) != m_Dependents.end())
    {
        return;
    }
    m_Dependents.push_back(component);
}

bool Component::addDirt(ComponentDirt value, bool recurse)
{
    if ((m_Dirt & value) == value)
    {
        // Already marked.
        return false;
    }

    // Make sure dirt is set before calling anything that can set more dirt.
    m_Dirt |= value;

    onDirty(m_Dirt);

    m_Artboard->onComponentDirty(this);

    if (!recurse)
    {
        return true;
    }

    for (auto d : m_Dependents)
    {
        d->addDirt(value, true);
    }
    return true;
}

StatusCode Component::import(ImportStack& importStack)
{
    if (is<Artboard>())
    {
        // Artboards are always their first object.
        assert(as<Artboard>()->objects().size() == 0);
        as<Artboard>()->addObject(this);
        return Super::import(importStack);
    }

    auto artboardImporter = importStack.latest<ArtboardImporter>(ArtboardBase::typeKey);
    if (artboardImporter == nullptr)
    {
        return StatusCode::MissingObject;
    }
    artboardImporter->addComponent(this);
    return Super::import(importStack);
}