#include "rive/animation/state_machine_instance.hpp"
#include "rive/animation/state_machine_listener_single.hpp"
#include "rive/component.hpp"
#include "rive/constraints/draggable_constraint.hpp"

using namespace rive;

std::vector<ListenerGroupWithTargets*> DraggableConstraint::listenerGroups()
{
  std::vector<ListenerGroupWithTargets*> result;
  for (auto dragProxy : draggables())
  {
    auto listener = new StateMachineListenerSingle();
    listener->listenerTypeValue(
        static_cast<uint32_t>(ListenerType::componentProvided));
    auto* listenerGroup = new DraggableConstraintListenerGroup(
        listener,
        this,
        dragProxy);
    auto hittable = dragProxy->hittable();
    if (hittable != nullptr && hittable->is<Component>())
    {
      auto* target = new HitTarget(
          hittable->as<Component>(),
          dragProxy->isOpaque());
      auto* groupWithTargets = new ListenerGroupWithTargets(
          listenerGroup,
          std::vector<HitTarget*>{target});
      result.push_back(groupWithTargets);
    }
  }
  return result;
}

// Mirrors the down -> clicked/out teardown in processEvent, which cancellation
// bypasses by clearing the phase before processEvent can observe the change.
bool DraggableConstraintListenerGroup::cancelPointer(
    int pointerId,
    Vec2D position,
    float timeStamp)
{
  auto pointer = findPointerData(pointerId);
  bool wasDown = pointer != nullptr &&
                 pointer->phase == GestureClickPhase::down;
  bool wasDragging = ListenerGroup::cancelPointer(
      pointerId,
      position,
      timeStamp);
  if (wasDown)
  {
    m_draggable->endDrag(position, timeStamp);
    if (m_scrollingPointerId == pointerId)
    {
      m_scrollingPointerId = -1;
      wasDragging = true;
    }
  }
  return wasDragging;
}

ProcessEventResult DraggableConstraintListenerGroup::processEvent(
    Component* component,
    Vec2D position,
    int pointerId,
    ListenerType hitEvent,
    PointerButton button,
    bool canHit,
    float timeStamp,
    StateMachineInstance* stateMachineInstance)
{
  if ((hitEvent == ListenerType::down || hitEvent == ListenerType::up) &&
      button != PointerButton::primary)
  {
    return ProcessEventResult::none;
  }
  auto pointer = pointerData(pointerId);
  auto prevPhase = pointer->phase;
  ListenerGroup::processEvent(
      component,
      position,
      pointerId,
      hitEvent,
      button,
      canHit,
      timeStamp,
      stateMachineInstance);
  if (prevPhase == GestureClickPhase::down &&
      (pointer->phase == GestureClickPhase::clicked ||
       pointer->phase == GestureClickPhase::out))
  {
    m_draggable->endDrag(position, timeStamp);
    if (m_scrollingPointerId == pointerId)
    {
      stateMachineInstance->dragEnd(position, timeStamp, pointerId);
      m_scrollingPointerId = -1;
      return ProcessEventResult::scroll;
    }
  }
  else if (
      prevPhase != GestureClickPhase::down &&
      pointer->phase == GestureClickPhase::down)
  {
    m_draggable->startDrag(position, timeStamp);
    m_scrollingPointerId = -1;
  }
  else if (
      hitEvent == ListenerType::move &&
      pointer->phase == GestureClickPhase::down)
  {
    auto hasDragged = m_draggable->drag(position, timeStamp);
    if (hasDragged)
    {
      if (m_scrollingPointerId != pointerId)
      {
        stateMachineInstance->dragStart(position, timeStamp, false, pointerId);
      }
      m_scrollingPointerId = pointerId;
      return ProcessEventResult::scroll;
    }
  }
  return ProcessEventResult::none;
}