text: #pragma once
  
  #include <Euclid.hpp>
  #include <Math.hpp>
  #include <Input.hpp>
  
  struct Camera
  {
  	euclid::float3 Pos{0.0, 0.0, 0.0};
  	euclid::quat Rot{0.0, 0.0, 0.0, 1.0};
  
  	inline void rotate(float t_Amount, euclid::float3 t_Axis)
  	{
  		Rot *= euclid::quat::FromAxisAngle(t_Amount, t_Axis);
  	}
  
  	inline void lookAt(euclid::float3 t_Point)
  	{
  		Rot = euclid::quat::FromAxisAngle(Rad(180.0f), (t_Point - Pos).Normalized());
  	}
  
  	inline euclid::mat4 view()
  	{
  		return euclid::mat4::MakeLookAt(Pos, Pos + Rot.Axis(), euclid::float3(0.0f, 1.0f, 0.0f));
  	}
  
  	inline void move(float t_Amount, euclid::float3 t_Dir)
  	{
  		Pos += t_Dir * t_Amount;
  	}
  
  	inline euclid::float3 at()
  	{
  		auto forwar = Forward(Rot);
  		return {forwar.x, forwar.y, forwar.z};
  	}
  
  	euclid::float3 up()
      {
  		return euclid::float3{ 0, 1, 0 };
      }
  
  	inline euclid::float3 left()
  	{
  		return -(euclid::Cross(at(), up())).Normalized();
  	}
  };
  
  enum CameraControlMode
  {
  	CCM_FPS,
  	CCM_Orbital,
  	CCM_Count,
  };
  
  struct CameraControlState
  {
  	bool InitialClick{false};
  	euclid::float2 Look{0,0};
  	euclid::float2 Orbit{0.0f, 0.0f};
  	float Radius{1.0f};
  
  	float MaxRadius{10.0f};
  	float MinRadius{0.05f};
  
  	int FastSpeed{15};
  	int SlowSpeed{1};
  
  	CameraControlMode Mode{CCM_FPS};
  };
  
  void ControlCameraFPS(CameraControlState& state, Camera& t_Camera, float dt = 1.0f);
  void ControlCameraOrbital(CameraControlState& state, Camera& t_Camera, float dt = 1.0f);
  void ControlCameraStateImgui(CameraControlState& state);
  
  inline void ControlCamera(CameraControlState& state, Camera& t_Camera, float dt = 1.0f)
  {
  	switch (state.Mode) {
  	  case CCM_FPS: 
  		  ControlCameraFPS(state, t_Camera, dt);
  		  break;
  	 case CCM_Orbital:
  		 ControlCameraOrbital(state, t_Camera, dt);
  		 break;
  	}
  }
  
  