#pragma once
#include <SDL_keyboard.h>
#include <SDL_mouse.h>

#include "Maths.h"
#include "Timer.h"

namespace dae
{
	struct Camera
	{
		Camera() = default;

		Camera(const Vector3& _origin, float _fovAngle) :
			origin{ _origin },
			fovAngle{ _fovAngle }
		{
		}


		Vector3 origin{};
		float fovAngle{ 90.f };

		Vector3 forward{ Vector3::UnitZ };
		Vector3 up{ Vector3::UnitY };
		Vector3 right{ Vector3::UnitX };

		float totalPitch{ 0.f };
		float totalYaw{ 0.f };

		Matrix cameraToWorld{};

        void SetFOV(float fov)
        {
            fovAngle = fov;
        }

		Matrix CalculateCameraToWorld()
		{
            right = Vector3::Cross(Vector3::UnitY, forward).Normalized();
            up = Vector3::Cross(forward, right).Normalized();

            Matrix matrix {
                    Vector4{right, 0},
                    Vector4{up, 0},
                    Vector4{forward, 0},
                    Vector4{origin, 0},
            };
            return matrix;
		}

		void Update(Timer* pTimer)
		{
			const float deltaTime = pTimer->GetElapsed();



			//Keyboard Input
			const uint8_t* pKeyboardState = SDL_GetKeyboardState(nullptr);
            {



                float speed{10.f};

                if (pKeyboardState[SDL_SCANCODE_W]) {
                    origin += forward * deltaTime * speed;
                }
                if (pKeyboardState[SDL_SCANCODE_S]) {
                    origin -= forward * deltaTime * speed;
                }
                if (pKeyboardState[SDL_SCANCODE_D]) {
                    origin += right * deltaTime * speed;
                }
                if (pKeyboardState[SDL_SCANCODE_A]) {
                    origin -= right * deltaTime * speed;
                }

                if (pKeyboardState[SDL_SCANCODE_Q]) {
                    origin -= Vector3::UnitY * deltaTime * speed;
                }
                if (pKeyboardState[SDL_SCANCODE_E]) {
                    origin += Vector3::UnitY * deltaTime * speed;
                }
            }
            int mouseX{}, mouseY{};
            const uint32_t mouseState = SDL_GetRelativeMouseState(&mouseX, &mouseY);

            bool dirty = false;

            float speed{ 0.15f };

            if(mouseX)
            {
                totalYaw += mouseX * speed;
                totalPitch = std::fmod(totalPitch, 180.f);
                dirty = true;
            }

            if(mouseY)
            {
                totalPitch += mouseY * speed;
                totalPitch = std::clamp(totalPitch, -85.f, 85.f);
                dirty = true;
            }

            if(dirty)
            {
                Matrix rotMat{
                        Matrix::CreateRotationX(-TO_RADIANS * totalPitch) * Matrix::CreateRotationY(-TO_RADIANS * totalYaw)
                };

                forward = rotMat.TransformVector(Vector3::UnitZ);
                right = rotMat.TransformVector(Vector3::UnitX);
            }
        }
	};
}
