#include <rive/file.hpp>
#include <rive/animation/state_machine_bool.hpp>
#include <rive/animation/state_machine_layer.hpp>
#include <rive/animation/animation_state.hpp>
#include <rive/animation/entry_state.hpp>
#include <rive/animation/state_transition.hpp>
#include <rive/animation/state_machine_instance.hpp>
#include <rive/animation/state_machine_input_instance.hpp>
#include <rive/animation/blend_state_1d.hpp>
#include <rive/animation/blend_animation_1d.hpp>
#include <rive/animation/blend_state_direct.hpp>
#include <rive/animation/blend_state_transition.hpp>
#include "catch.hpp"
#include "rive_file_reader.hpp"
#include <cstdio>

TEST_CASE("file with state machine be read", "[file]") {
    auto file = ReadRiveFile("../../test/assets/rocket.riv");

    auto artboard = file->artboard();
    REQUIRE(artboard != nullptr);
    REQUIRE(artboard->animationCount() == 3);
    REQUIRE(artboard->stateMachineCount() == 1);

    auto stateMachine = artboard->stateMachine("Button");
    REQUIRE(stateMachine != nullptr);

    REQUIRE(stateMachine->layerCount() == 1);
    REQUIRE(stateMachine->inputCount() == 2);

    auto hover = stateMachine->input("Hover");
    REQUIRE(hover != nullptr);
    REQUIRE(hover->is<rive::StateMachineBool>());

    auto press = stateMachine->input("Press");
    REQUIRE(press != nullptr);
    REQUIRE(press->is<rive::StateMachineBool>());

    auto layer = stateMachine->layer(0);
    REQUIRE(layer->stateCount() == 6);

    REQUIRE(layer->anyState() != nullptr);
    REQUIRE(layer->entryState() != nullptr);
    REQUIRE(layer->exitState() != nullptr);

    int foundAnimationStates = 0;
    for (int i = 0; i < layer->stateCount(); i++) {
        auto state = layer->state(i);
        if (state->is<rive::AnimationState>()) {
            foundAnimationStates++;
            REQUIRE(state->as<rive::AnimationState>()->animation() != nullptr);
        }
    }

    REQUIRE(foundAnimationStates == 3);

    REQUIRE(layer->entryState()->transitionCount() == 1);
    auto stateTo = layer->entryState()->transition(0)->stateTo();
    REQUIRE(stateTo != nullptr);
    REQUIRE(stateTo->is<rive::AnimationState>());
    REQUIRE(stateTo->as<rive::AnimationState>()->animation() != nullptr);
    REQUIRE(stateTo->as<rive::AnimationState>()->animation()->name() == "idle");

    auto idleState = stateTo->as<rive::AnimationState>();
    REQUIRE(idleState->transitionCount() == 2);
    for (int i = 0; i < idleState->transitionCount(); i++) {
        auto transition = idleState->transition(i);
        if (transition->stateTo()->as<rive::AnimationState>()->animation()->name() == "Roll_over") {
            // Check the condition
            REQUIRE(transition->conditionCount() == 1);
        }
    }

    auto abi = artboard->instance();
    rive::StateMachineInstance smi(artboard->stateMachine("Button"), abi.get());

    REQUIRE(smi.getBool("Hover")->name() == "Hover");
    REQUIRE(smi.getBool("Press")->name() == "Press");
    REQUIRE(smi.getBool("Hover") != nullptr);
    REQUIRE(smi.getBool("Press") != nullptr);
    REQUIRE(smi.stateChangedCount() == 0);
    REQUIRE(smi.currentAnimationCount() == 0);
}

TEST_CASE("file with blend states loads correctly", "[file]") {
    auto file = ReadRiveFile("../../test/assets/blend_test.riv");

    auto artboard = file->artboard();
    REQUIRE(artboard != nullptr);
    REQUIRE(artboard->animationCount() == 4);
    REQUIRE(artboard->stateMachineCount() == 2);

    auto stateMachine = artboard->stateMachine("blend");
    REQUIRE(stateMachine != nullptr);

    REQUIRE(stateMachine->layerCount() == 1);
    auto layer = stateMachine->layer(0);
    REQUIRE(layer->stateCount() == 5);

    REQUIRE(layer->anyState() != nullptr);
    REQUIRE(layer->entryState() != nullptr);
    REQUIRE(layer->exitState() != nullptr);

    REQUIRE(layer->state(1)->is<rive::BlendState1D>());
    REQUIRE(layer->state(2)->is<rive::BlendState1D>());

    auto blendStateA = layer->state(1)->as<rive::BlendState1D>();
    auto blendStateB = layer->state(2)->as<rive::BlendState1D>();

    REQUIRE(blendStateA->animationCount() == 3);
    REQUIRE(blendStateB->animationCount() == 3);

    auto animation = blendStateA->animation(0);
    REQUIRE(animation->is<rive::BlendAnimation1D>());
    auto animation1D = animation->as<rive::BlendAnimation1D>();
    REQUIRE(animation1D->animation() != nullptr);
    REQUIRE(animation1D->animation()->name() == "horizontal");
    REQUIRE(animation1D->value() == 0.0f);

    animation = blendStateA->animation(1);
    REQUIRE(animation->is<rive::BlendAnimation1D>());
    animation1D = animation->as<rive::BlendAnimation1D>();
    REQUIRE(animation1D->animation() != nullptr);
    REQUIRE(animation1D->animation()->name() == "vertical");
    REQUIRE(animation1D->value() == 100.0f);

    animation = blendStateA->animation(2);
    REQUIRE(animation->is<rive::BlendAnimation1D>());
    animation1D = animation->as<rive::BlendAnimation1D>();
    REQUIRE(animation1D->animation() != nullptr);
    REQUIRE(animation1D->animation()->name() == "rotate");
    REQUIRE(animation1D->value() == 0.0f);

    REQUIRE(blendStateA->transitionCount() == 1);
    REQUIRE(blendStateA->transition(0)->is<rive::BlendStateTransition>());
    REQUIRE(blendStateA->transition(0)->as<rive::BlendStateTransition>()->exitBlendAnimation() !=
            nullptr);
}

TEST_CASE("animation state with no animation doesn't crash", "[file]") {
    auto file = ReadRiveFile("../../test/assets/multiple_state_machines.riv");

    auto artboard = file->artboard();
    REQUIRE(artboard != nullptr);
    REQUIRE(artboard->animationCount() == 1);
    REQUIRE(artboard->stateMachineCount() == 4);

    auto stateMachine = artboard->stateMachine("two");
    REQUIRE(stateMachine != nullptr);

    REQUIRE(stateMachine->layerCount() == 1);
    auto layer = stateMachine->layer(0);
    REQUIRE(layer->stateCount() == 4);

    REQUIRE(layer->anyState() != nullptr);
    REQUIRE(layer->entryState() != nullptr);
    REQUIRE(layer->exitState() != nullptr);

    REQUIRE(layer->state(3)->is<rive::AnimationState>());

    auto animationState = layer->state(3)->as<rive::AnimationState>();
    REQUIRE(animationState->animation() == nullptr);

    auto abi = artboard->instance();
    rive::StateMachineInstance(stateMachine, abi.get()).advance(0.0f);
}
