/*
 * Copyright 2022 Rive
 */

#include <rive/math/aabb.hpp>
#include <rive/math/hit_test.hpp>
#include <rive/nested_artboard.hpp>
#include <rive/animation/state_machine_instance.hpp>
#include <rive/animation/state_machine_input_instance.hpp>
#include <rive/animation/nested_state_machine.hpp>
#include <rive/animation/animation_state.hpp>
#include "rive_file_reader.hpp"

#include <catch.hpp>
#include <cstdio>

using namespace rive;

TEST_CASE("hittest-basics", "[hittest]")
{
    HitTester tester;
    tester.reset({10, 10, 12, 12});
    tester.move({0, 0});
    tester.line({20, 0});
    tester.line({20, 20});
    tester.line({0, 20});
    tester.close();
    REQUIRE(tester.test());

    IAABB area = {81, 156, 84, 159};

    Vec2D pts[] = {
        {29.9785f, 32.5261f},
        {231.102f, 32.5261f},
        {231.102f, 269.898f},
        {29.9785f, 269.898f},
    };
    tester.reset(area);

    tester.move(pts[0]);
    for (int i = 1; i < 4; ++i)
    {
        tester.line(pts[i]);
    }
    tester.close();
    REQUIRE(tester.test());
}

TEST_CASE("hittest-mesh", "[hittest]")
{

    const IAABB area{10, 10, 12, 12};

    Vec2D verts[] = {
        {0, 0},
        {20, 10},
        {0, 20},
    };
    uint16_t indices[] = {
        0,
        1,
        2,
    };
    REQUIRE(HitTester::testMesh(area, make_span(verts, 3), make_span(indices, 3)));
}

TEST_CASE("hit test on opaque target", "[hittest]")
{
    // This artboard has two rects of size 200 x 200, "red-activate" at [0, 0, 200, 200]
    // and "green-activate" at [0, 100, 200, 300]
    // "red-activate" is above "green-activate" in drawing order
    // Both targets are set as opaque for its listeners
    // "red-activate" sets "toGreen" to false
    // "green-activate" sets "toGreen" to true
    // There is also a "gray-activate" above the other 2 that is not opaque so events should
    // traverse through the other targets
    auto file = ReadRiveFile("../../test/assets/opaque_hit_test.riv");

    auto artboard = file->artboard("main");
    auto artboardInstance = artboard->instance();
    auto stateMachine = artboard->stateMachine("main-state-machine");

    REQUIRE(artboardInstance != nullptr);
    REQUIRE(artboardInstance->stateMachineCount() == 1);

    REQUIRE(stateMachine != nullptr);

    rive::StateMachineInstance* stateMachineInstance =
        new rive::StateMachineInstance(stateMachine, artboardInstance.get());

    stateMachineInstance->advance(0.0f);
    artboardInstance->advance(0.0f);
    REQUIRE(stateMachineInstance->needsAdvance() == true);
    stateMachineInstance->advance(0.0f);

    auto toGreenToggle = stateMachineInstance->getBool("toGreen");
    REQUIRE(toGreenToggle != nullptr);
    auto grayToggle = stateMachineInstance->getBool("grayToggle");
    REQUIRE(grayToggle != nullptr);

    stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 50.0f));
    // "gray-activate" is clicked
    REQUIRE(grayToggle->value() == true);
    // Pointer only over "red-activate"
    REQUIRE(toGreenToggle->value() == false);

    stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 250.0f));
    // "gray-activate" is clicked
    REQUIRE(grayToggle->value() == false);
    // Pointer over "green-activate"
    REQUIRE(toGreenToggle->value() == true);

    stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 110.0f));
    // "gray-activate" is clicked
    REQUIRE(grayToggle->value() == true);
    // Pointer over "red-activate" and "green-activate", but "red-activate" is opaque and above
    // so green activate does not trigger
    REQUIRE(toGreenToggle->value() == false);
    delete stateMachineInstance;
}

TEST_CASE("hit test on opaque nested artboard", "[hittest]")
{
    // This artboard (300x300) has a main rect at [0, 0, 300, 300]
    // this rect has a listener that toggles "second-gray-toggle"
    // and a nested artboard at [0, 0, 150, 150]
    // the nested artboard and the rect have opaque targets
    auto file = ReadRiveFile("../../test/assets/opaque_hit_test.riv");

    auto artboard = file->artboard("second");
    auto artboardInstance = artboard->instance();
    auto stateMachine = artboard->stateMachine("second-state-machine");

    REQUIRE(artboardInstance != nullptr);
    REQUIRE(artboardInstance->stateMachineCount() == 1);

    REQUIRE(stateMachine != nullptr);

    rive::StateMachineInstance* stateMachineInstance =
        new rive::StateMachineInstance(stateMachine, artboardInstance.get());

    auto nestedArtboard =
        stateMachineInstance->artboard()->find<rive::NestedArtboard>("second-nested");
    REQUIRE(nestedArtboard != nullptr);
    auto nestedArtboardStateMachine =
        nestedArtboard->nestedAnimations()[0]->as<NestedStateMachine>();
    REQUIRE(nestedArtboardStateMachine != nullptr);
    auto nestedArtboardStateMachineInstance = nestedArtboardStateMachine->stateMachineInstance();

    auto secondNestedBoolTarget = nestedArtboardStateMachineInstance->getBool("bool-target");
    REQUIRE(secondNestedBoolTarget != nullptr);

    artboardInstance->advance(0.0f);
    stateMachineInstance->advanceAndApply(0.0f);

    REQUIRE(secondNestedBoolTarget->value() == false);

    auto secondGrayToggle = stateMachineInstance->getBool("second-gray-toggle");
    REQUIRE(secondGrayToggle != nullptr);

    stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 250.0f));
    // toggle changes value because it is not under an opaque nested artboard
    REQUIRE(secondGrayToggle->value() == true);

    stateMachineInstance->pointerDown(rive::Vec2D(301.0f, 50.0f));
    // toggle does not change because it is beyond the area of the square by 1 pixel
    // And the 2px padding is unly used after the coarse grained test passes
    REQUIRE(secondGrayToggle->value() == true);

    stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 50.0f));
    // toggle does not change because it is under an opaque nested artboard
    REQUIRE(secondGrayToggle->value() == true);

    // nested toggle changes because it's on top of shape
    REQUIRE(secondNestedBoolTarget->value() == true);

    // A timeline switches draw order and the nested artboard is now below the rect
    stateMachineInstance->advanceAndApply(1.0f);
    stateMachineInstance->advance(0.0f);

    stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 50.0f));
    // So now the pointer down is captured by the rect
    REQUIRE(secondGrayToggle->value() == false);

    // nested toggle does not change because it's below shape
    REQUIRE(secondNestedBoolTarget->value() == true);
    delete stateMachineInstance;
}

TEST_CASE("early out on listeners", "[hittest]")
{
    auto file = ReadRiveFile("../../test/assets/pointer_events.riv");

    auto artboard = file->artboard("art-1");
    auto artboardInstance = artboard->instance();
    auto stateMachine = artboard->stateMachine("sm-1");

    REQUIRE(artboardInstance != nullptr);
    REQUIRE(artboardInstance->stateMachineCount() == 1);

    REQUIRE(stateMachine != nullptr);

    rive::StateMachineInstance* stateMachineInstance =
        new rive::StateMachineInstance(stateMachine, artboardInstance.get());

    stateMachineInstance->advance(0.0f);
    artboardInstance->advance(0.0f);
    REQUIRE(stateMachineInstance->needsAdvance() == true);
    stateMachineInstance->advance(0.0f);
    REQUIRE(stateMachineInstance->hitComponentsCount() == 4);
    // Hit component with only pointer down and pointer up listeners
    auto hitComponentWithEarlyOut = stateMachineInstance->hitComponent(0);
    // Hit component that can't early out because it has a pointer enter event
    auto hitComponentWithNoEarlyOut = stateMachineInstance->hitComponent(1);
    // Hit component that can't early out because it is an opaque target
    auto hitComponentOpaque = stateMachineInstance->hitComponent(2);
    // Hit component that can early out on all and pointer up
    auto hitComponentOnlyPointerDown = stateMachineInstance->hitComponent(3);
    REQUIRE(hitComponentWithEarlyOut->earlyOutCount == 0);
    REQUIRE(hitComponentWithNoEarlyOut->earlyOutCount == 0);
    REQUIRE(hitComponentOpaque->earlyOutCount == 0);
    REQUIRE(hitComponentOnlyPointerDown->earlyOutCount == 0);
    stateMachineInstance->pointerMove(rive::Vec2D(100.0f, 250.0f));
    REQUIRE(hitComponentWithEarlyOut->earlyOutCount == 1);
    REQUIRE(hitComponentWithNoEarlyOut->earlyOutCount == 0);
    REQUIRE(hitComponentOpaque->earlyOutCount == 0);
    REQUIRE(hitComponentOnlyPointerDown->earlyOutCount == 1);
    stateMachineInstance->pointerExit(rive::Vec2D(100.0f, 250.0f));
    REQUIRE(hitComponentWithEarlyOut->earlyOutCount == 2);
    REQUIRE(hitComponentWithNoEarlyOut->earlyOutCount == 0);
    REQUIRE(hitComponentOnlyPointerDown->earlyOutCount == 2);
    REQUIRE(hitComponentOpaque->earlyOutCount == 0);
    stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 250.0f));
    REQUIRE(hitComponentWithEarlyOut->earlyOutCount == 2);
    REQUIRE(hitComponentWithNoEarlyOut->earlyOutCount == 0);
    REQUIRE(hitComponentOpaque->earlyOutCount == 0);
    REQUIRE(hitComponentOnlyPointerDown->earlyOutCount == 2);
    stateMachineInstance->pointerUp(rive::Vec2D(100.0f, 250.0f));
    REQUIRE(hitComponentWithEarlyOut->earlyOutCount == 2);
    REQUIRE(hitComponentWithNoEarlyOut->earlyOutCount == 0);
    REQUIRE(hitComponentOpaque->earlyOutCount == 0);
    REQUIRE(hitComponentOnlyPointerDown->earlyOutCount == 3);
    stateMachineInstance->pointerMove(rive::Vec2D(105.0f, 205.0f));
    REQUIRE(hitComponentWithEarlyOut->earlyOutCount == 3);
    REQUIRE(hitComponentWithNoEarlyOut->earlyOutCount == 0);
    REQUIRE(hitComponentOpaque->earlyOutCount == 0);
    REQUIRE(hitComponentOnlyPointerDown->earlyOutCount == 4);

    delete stateMachineInstance;
}

TEST_CASE("click event", "[hittest]")
{
    // This test has two rectangles of size [200, 200]
    // positioned at [100,100] and [200, 200]
    // they overlap between coordinates [100,100]-[200, 200]
    // they are inside a group that has a listener attached to it
    // that listener should fire an event on "Click"
    auto file = ReadRiveFile("../../test/assets/click_event.riv");

    auto artboard = file->artboard("art-1");
    auto artboardInstance = artboard->instance();
    auto stateMachine = artboard->stateMachine("sm-1");

    REQUIRE(artboardInstance != nullptr);
    REQUIRE(artboardInstance->stateMachineCount() == 1);

    REQUIRE(stateMachine != nullptr);

    rive::StateMachineInstance* stateMachineInstance =
        new rive::StateMachineInstance(stateMachine, artboardInstance.get());

    stateMachineInstance->advance(0.0f);
    artboardInstance->advance(0.0f);
    REQUIRE(stateMachineInstance->needsAdvance() == true);
    stateMachineInstance->advance(0.0f);
    // There is a single listener with two shapes in it
    REQUIRE(stateMachineInstance->hitComponentsCount() == 2);
    auto layerCount = stateMachine->layerCount();
    REQUIRE(layerCount == 1);
    REQUIRE(stateMachineInstance->reportedEventCount() == 0);
    // Click in place should trigger a click event
    stateMachineInstance->pointerDown(rive::Vec2D(75.0f, 75.0f));
    stateMachineInstance->pointerUp(rive::Vec2D(75.0f, 75.0f));
    REQUIRE(stateMachineInstance->reportedEventCount() == 1);
    // Pointer down inside shape but Pointer up outside the shape
    // should not trigger a click event
    stateMachineInstance->pointerDown(rive::Vec2D(75.0f, 75.0f));
    stateMachineInstance->pointerUp(rive::Vec2D(300.0f, 75.0f));
    REQUIRE(stateMachineInstance->reportedEventCount() == 1);
    // Pointer down outside shape but Pointer up inside the shape
    // should not trigger a click event
    stateMachineInstance->pointerDown(rive::Vec2D(300.0f, 75.0f));
    stateMachineInstance->pointerUp(rive::Vec2D(75.0f, 75.0f));
    REQUIRE(stateMachineInstance->reportedEventCount() == 1);
    // Pointer down in shape 1 Pointer up in shape 2 of the same group
    // should trigger a click event
    stateMachineInstance->pointerDown(rive::Vec2D(75.0f, 75.0f));
    stateMachineInstance->pointerUp(rive::Vec2D(225.0f, 225.0f));
    REQUIRE(stateMachineInstance->reportedEventCount() == 2);
    // Pointer down and up in area where both shapes overlap
    // should trigger a single click event
    stateMachineInstance->pointerDown(rive::Vec2D(150.0f, 150.0f));
    stateMachineInstance->pointerUp(rive::Vec2D(150.0f, 150.0f));
    REQUIRE(stateMachineInstance->reportedEventCount() == 3);

    delete stateMachineInstance;
}

TEST_CASE("multiple shapes with mouse movement behavior", "[hittest]")
{
    // This test has two rectangles of size [200, 200]
    // positioned at [100,100] and [100, 200]
    // they overlap between coordinates [100,0]-[200, 200]
    // they are inside a group that has a Pointer enter and a Pointer out
    // listeners that toggle between two states (red and green)
    // starting at "red"
    auto file = ReadRiveFile("../../test/assets/click_event.riv");

    auto artboard = file->artboard("art-2");
    auto artboardInstance = artboard->instance();
    auto stateMachine = artboard->stateMachine("sm-1");

    REQUIRE(artboardInstance != nullptr);
    REQUIRE(artboardInstance->stateMachineCount() == 1);

    REQUIRE(stateMachine != nullptr);

    rive::StateMachineInstance* stateMachineInstance =
        new rive::StateMachineInstance(stateMachine, artboardInstance.get());

    stateMachineInstance->advance(0.0f);
    artboardInstance->advance(0.0f);
    REQUIRE(stateMachineInstance->needsAdvance() == true);
    stateMachineInstance->advance(0.0f);
    // There is a single listener with two shapes in it
    REQUIRE(stateMachineInstance->hitComponentsCount() == 2);
    auto layerCount = stateMachine->layerCount();
    REQUIRE(layerCount == 1);
    // Move over the first shape
    stateMachineInstance->pointerMove(rive::Vec2D(75.0f, 75.0f));
    artboardInstance->advance(0.0f);
    stateMachineInstance->advanceAndApply(0.0f);

    {
        auto state = stateMachineInstance->layerState(0);
        REQUIRE(state->is<rive::AnimationState>());
        auto animation = state->as<rive::AnimationState>()->animation();
        REQUIRE(animation->name() == "green");
    }
    // Move over the second shape, nothing should change
    stateMachineInstance->pointerMove(rive::Vec2D(200.0f, 75.0f));
    artboardInstance->advance(0.0f);
    stateMachineInstance->advanceAndApply(0.0f);

    {
        auto state = stateMachineInstance->layerState(0);
        REQUIRE(state->is<rive::AnimationState>());
        auto animation = state->as<rive::AnimationState>()->animation();
        REQUIRE(animation->name() == "green");
    }
    // Move out of the second shape, should go back to red
    stateMachineInstance->pointerMove(rive::Vec2D(400.0f, 75.0f));
    artboardInstance->advance(0.0f);
    stateMachineInstance->advanceAndApply(0.0f);

    {
        auto state = stateMachineInstance->layerState(0);
        REQUIRE(state->is<rive::AnimationState>());
        auto animation = state->as<rive::AnimationState>()->animation();
        REQUIRE(animation->name() == "red");
    }
    // Move back into the second shape, should go to green
    stateMachineInstance->pointerMove(rive::Vec2D(200.0f, 75.0f));
    artboardInstance->advance(0.0f);
    stateMachineInstance->advanceAndApply(0.0f);

    {
        auto state = stateMachineInstance->layerState(0);
        REQUIRE(state->is<rive::AnimationState>());
        auto animation = state->as<rive::AnimationState>()->animation();
        REQUIRE(animation->name() == "green");
    }

    delete stateMachineInstance;
}