//
// Created by sfd on 25-5-12.
//

#include "Hazel/Renderer/OrthographicCameraController.h"

#include <Hazel/Core/Application.h>
#include <Hazel/Debug/Instrumentor.h>


namespace Hazel
{
    OrthographicCameraController::OrthographicCameraController(float aspectRatio, bool isRotation)
		: m_AspectRatio(aspectRatio), m_isRotation(isRotation),
		  m_Bounds(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel),
	      m_Camera(m_Bounds.left, m_Bounds.right, m_Bounds.bottom, m_Bounds.top)
    {
    }

    void OrthographicCameraController::OnResize(const float width, const float height)
    {
		    m_AspectRatio = width / height;
	    	CalculateView();
    }

    void OrthographicCameraController::OnUpdate(TimeStep ts)
    {
        HZ_PROFILE_FUNCTION();
	    static const bool* state = SDL_GetKeyboardState(NULL);
    	float       time  = ts;

	    if (state[SDL_SCANCODE_A])
		    m_CameraPosition.x -= m_CameraTranslationSpeed * time;
	    else if (state[SDL_SCANCODE_D])
		    m_CameraPosition.x += m_CameraTranslationSpeed * time;

	    if (state[SDL_SCANCODE_W])
		    m_CameraPosition.y += m_CameraTranslationSpeed * time;
	    else if (state[SDL_SCANCODE_S])
		    m_CameraPosition.y -= m_CameraTranslationSpeed * time;

    	if (m_isRotation)
	    {
		    if (state[SDL_SCANCODE_Q])
			    m_CameraRotation += m_CameraRotationSpeed * time;
		    else if (state[SDL_SCANCODE_E])
			    m_CameraRotation -= m_CameraRotationSpeed * time;

    		m_Camera.SetRotation(m_CameraRotation);
	    }


    	m_Camera.SetPosition(m_CameraPosition);

    	m_CameraTranslationSpeed = m_ZoomLevel;
    }

    void OrthographicCameraController::OnEvent(SDL_Event& e)
    {
		    HZ_PROFILE_FUNCTION();
		    OnMouseScrolled(e);
		    OnWindowResized(e);
    }

    void OrthographicCameraController::CalculateView()
    {
	    m_Bounds = {-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel};
	    m_Camera.SetProjection(m_Bounds.left, m_Bounds.right, m_Bounds.bottom, m_Bounds.top);
    }

    bool OrthographicCameraController::OnMouseScrolled(SDL_Event& e)
    {
	    HZ_PROFILE_FUNCTION();
	    if (e.type == SDL_EVENT_MOUSE_WHEEL)
	    {
		    m_ZoomLevel -= e.wheel.y * 0.25f;
		    m_ZoomLevel = std::max(m_ZoomLevel, 0.25f);
			CalculateView();
		    return false;
	    }
	    return true;
    }

    bool OrthographicCameraController::OnWindowResized(SDL_Event& e)
    {
	    HZ_PROFILE_FUNCTION();
	    if (e.type == SDL_EVENT_WINDOW_RESIZED)
	    {
		    OnResize(static_cast<float>(e.window.data1), static_cast<float>(e.window.data2));
		    return false;
	    }
	    return true;
    }
}
