#include "rive/nested_artboard.hpp"
#include "rive/artboard.hpp"
#include "rive/backboard.hpp"
#include "rive/importers/import_stack.hpp"
#include "rive/importers/backboard_importer.hpp"
#include "rive/nested_animation.hpp"

using namespace rive;

NestedArtboard::~NestedArtboard() {
    if (m_NestedInstance->isInstance()) {
        delete m_NestedInstance;
    }
}
Core* NestedArtboard::clone() const {
    NestedArtboard* nestedArtboard =
        static_cast<NestedArtboard*>(NestedArtboardBase::clone());
    if (m_NestedInstance == nullptr) {
        return nestedArtboard;
    }
    nestedArtboard->nest(m_NestedInstance->instance());
    return nestedArtboard;
}

void NestedArtboard::nest(Artboard* artboard) {
    assert(artboard != nullptr);
    m_NestedInstance = artboard;
    m_NestedInstance->advance(0.0f);
}

void NestedArtboard::draw(Renderer* renderer) {
    if (m_NestedInstance == nullptr) {
        return;
    }
    renderer->save();
    renderer->transform(worldTransform());
    renderer->translate(-m_NestedInstance->originX() * m_NestedInstance->width(),
                        -m_NestedInstance->originY() * m_NestedInstance->height());
    m_NestedInstance->draw(renderer);
    renderer->restore();
}

StatusCode NestedArtboard::import(ImportStack& importStack) {
    auto backboardImporter =
        importStack.latest<BackboardImporter>(Backboard::typeKey);
    if (backboardImporter == nullptr) {
        return StatusCode::MissingObject;
    }
    backboardImporter->addNestedArtboard(this);

    return Super::import(importStack);
}

void NestedArtboard::addNestedAnimation(NestedAnimation* nestedAnimation) {
    m_NestedAnimations.push_back(nestedAnimation);
}

StatusCode NestedArtboard::onAddedClean(CoreContext* context) {
    // N.B. The nested instance will be null here for the source artboards.
    // Instances will have a nestedInstance available. This is a good thing as
    // it ensures that we only instance animations in artboard instances. It
    // does require that we always use an artboard instance (not just the source
    // artboard) when working with nested artboards, but in general this is good
    // practice for any loaded Rive file.
    if (m_NestedInstance != nullptr) {
        for (auto animation : m_NestedAnimations) {
            animation->initializeAnimation(m_NestedInstance);
        }
    }
    return Super::onAddedClean(context);
}

bool NestedArtboard::advance(float elapsedSeconds) {
    if (m_NestedInstance == nullptr) {
        return false;
    }
    for (auto animation : m_NestedAnimations) {
        animation->advance(elapsedSeconds, m_NestedInstance);
    }
    return m_NestedInstance->advance(elapsedSeconds);
}

void NestedArtboard::update(ComponentDirt value) {
    Super::update(value);
    if (hasDirt(value, ComponentDirt::WorldTransform) &&
        m_NestedInstance != nullptr)
    {
        m_NestedInstance->opacity(renderOpacity());
    }
}
