#include "rive/animation/scripted_transition_condition.hpp"
#include "rive/animation/state_machine_instance.hpp"
#include "rive/importers/state_machine_importer.hpp"

using namespace rive;

ScriptedTransitionCondition::~ScriptedTransitionCondition()
{
    disposeScriptInputs();
}

void ScriptedTransitionCondition::disposeScriptInputs()
{
    auto props = m_customProperties;
    ScriptedObject::disposeScriptInputs();
    for (auto prop : props)
    {
        auto scriptInput = ScriptInput::from(prop);
        if (scriptInput != nullptr)
        {
            // ScriptedDataConverters need to delete their own inputs
            // because they are not components
            delete scriptInput;
        }
    }
}

// Note: evaluateStateful is the actual instance of the
// ScriptedTransitionCondition that will run the script. evaluate itself will
// look for the map between the stateless and the stateful instances of this
// class.
bool ScriptedTransitionCondition::evaluateStateful(
    const StateMachineInstance* stateMachineInstance,
    StateMachineLayerInstance* layerInstance) const
{
    bool result = false;
#ifdef WITH_RIVE_SCRIPTING
    if (m_vm != nullptr && m_vm->valid())
    {
        result = m_vm->callBooleanMethod(
            const_cast<ScriptedTransitionCondition*>(this),
            m_self,
            "evaluate");
    }
#endif
    return result;
}

bool ScriptedTransitionCondition::evaluate(
    const StateMachineInstance* stateMachineInstance,
    StateMachineLayerInstance* layerInstance) const
{
#ifdef WITH_RIVE_SCRIPTING
    auto scriptedObject = stateMachineInstance->scriptedObject(this);
    if (scriptedObject != nullptr)
    {
        auto statefulListenerAction =
            static_cast<ScriptedTransitionCondition*>(scriptedObject);
        return statefulListenerAction->evaluateStateful(stateMachineInstance,
                                                        layerInstance);
    }
#endif
    return false;
}

StatusCode ScriptedTransitionCondition::import(ImportStack& importStack)
{
    auto result = registerReferencer(importStack);
    if (result != StatusCode::Ok)
    {
        return result;
    }
    auto stateMachineImporter =
        importStack.latest<StateMachineImporter>(StateMachine::typeKey);
    if (stateMachineImporter == nullptr)
    {
        return StatusCode::MissingObject;
    }
    stateMachineImporter->addScriptedObject(this);
    return Super::import(importStack);
}

Core* ScriptedTransitionCondition::clone() const
{
    ScriptedTransitionCondition* twin = ScriptedTransitionConditionBase::clone()
                                            ->as<ScriptedTransitionCondition>();
    if (m_fileAsset != nullptr)
    {
        twin->setAsset(m_fileAsset);
    }
    return twin;
}

ScriptedObject* ScriptedTransitionCondition::cloneScriptedObject(
    DataBindContainer* dataBindContainer) const
{
    auto clonedScriptedObject = clone()->as<ScriptedTransitionCondition>();
    cloneProperties(clonedScriptedObject, dataBindContainer);
    clonedScriptedObject->reinit();
    return clonedScriptedObject;
}

void ScriptedTransitionCondition::addProperty(CustomProperty* prop)
{
    auto scriptInput = ScriptInput::from(prop);
    if (scriptInput != nullptr)
    {
        scriptInput->scriptedObject(this);
    }
    CustomPropertyContainer::addProperty(prop);
}