#include "character/states/common/IdleState.h"
#include "character/CharacterObject.h"
#include <cmath>

namespace frostbite2D {
namespace {

bool HasMoveIntent(const CharacterIntent& intent) {
  return intent.moveMode != CharacterMoveMode::None
      && (std::abs(intent.moveX) > 0.01f || std::abs(intent.moveY) > 0.01f);
}

} // namespace

IdleState::IdleState()
    : CharacterStateBase(CharacterStateId::Idle) {
}

void IdleState::OnEnter(CharacterStateMachine& machine,
                        CharacterStateContext& context,
                        CharacterStateId previousState) {
  (void)previousState;
  context.owner.PlayAnimationTag("rest");
  InvokeHook(machine, context.owner, context.owner.FindAction("idle"), "on_enter");
}

void IdleState::OnUpdate(CharacterStateMachine& machine,
                         CharacterStateContext& context) {
  auto& owner = context.owner;
  auto& motor = owner.GetMotorMutable();
  if (!motor.grounded) {
    ChangeState(machine, context, CharacterStateId::Fall);
    return;
  }

  if (TryStartRegisteredAction(machine, context)) {
    return;
  }
  if (context.commandBuffer.HasBuffered(CharacterCommandType::JumpPressed)) {
    context.commandBuffer.Consume(CharacterCommandType::JumpPressed);
    motor.Jump();
    ChangeState(machine, context, CharacterStateId::Jump);
    return;
  }

  if (HasMoveIntent(context.intent)) {
    ChangeState(machine, context, CharacterStateId::Move);
    return;
  }

  motor.StopGroundMovement();
}

} // namespace frostbite2D
