#pragma once

#include "blitz/common/Smoothing.h"
#include "blitz/game/Listeners.h"
#include "blitz/misc/ObjectNotifier.h"
#include "blitz/misc/Time.h"

namespace blitz {
namespace game {

class Player;

}  // namespace game

namespace input {

class PlayerController : public utils::ObjectNotifier<game::PlayerListener> {
  private:
	game::Player* m_Player;
	utils::CooldownTimer<float> m_ShootTimer{1.0f};
	EMASmoother m_DxSmoother;
	/// maximum x-axis velocity
	float m_MaxDx;
	/// current (target) x-axis velocity
	float m_Dx;
	EMASmoother m_DySmoother;
	/// maximum (target) y-axis velocity
	float m_MaxDy;
	/// current (target) y-axis velocity
	float m_Dy;
	/// current z-axis velocity
	float m_Dz;
	/// maximum z-axis velocity (velocity at initial keypress)
	float m_MaxDz;
	/// individual gravitational force
	float m_G;
	/// this is reset when the player touches the ground
	bool m_OnGround;

  public:
	PlayerController();

	void Update(float delta);

	void SetAttachedPlayer(game::Player* a_Player) {
		m_Player = a_Player;
	}

	game::Player* GetAttachedPlayer() {
		return m_Player;
	}

  private:
	void MouseMotionEvent(int, int);
	void UpdatePosition(float delta);
};

}  // namespace input
}  // namespace blitz
