/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

#include "MorphableCameraController.hpp"
#include "Input/InputManager.hpp"
#include "Input/InputKey.hpp"
#include "Base/FrameMetadata.hpp"
#include "Scene/Camera.hpp"

namespace OpenVulkano::Scene
{
	MorphableCameraController::MorphableCameraController(MorphableCamera* camera)
	    : CameraController(camera)
	    , m_animationDuration(1.0f)
	    , m_currentTime(0.0f)
	    , m_isMorphing(false)
	    , m_targetMorphStatePerspective(true)
	{
		auto input = OpenVulkano::Input::InputManager::GetInstance();
		m_actionMorph = input->GetAction("morph");
	}

	void MorphableCameraController::Init(MorphableCamera* camera)
	{
		CameraController::Init(camera);
		m_actionMorph->BindKey(Input::InputKey::Keyboard::KEY_P);
	}

	void MorphableCameraController::Tick()
	{
		auto input = OpenVulkano::Input::InputManager::GetInstance();

		bool isMorphingDown = input->GetButton(m_actionMorph);
		if (!m_wasMorphingKeyDown && isMorphingDown)
		{
			m_isMorphing = true;
			m_currentTime = 0.0f;
			m_targetMorphStatePerspective = !m_targetMorphStatePerspective;
		}
		m_wasMorphingKeyDown = isMorphingDown;

		if (m_isMorphing)
		{
			m_currentTime += CURRENT_FRAME.frameTime;
			if (m_currentTime > m_animationDuration) m_currentTime = m_animationDuration;
			float t = m_currentTime / m_animationDuration;
			if (t >= 1.0f)
			{
				t = 1.0f;
				m_isMorphing = false;
			}
			float newState = m_targetMorphStatePerspective ? (1.0f - t) : t;
			static_cast<MorphableCamera*>(GetCamera())->SetMorphState(newState);
		}
	}

	void MorphableCameraController::SetTargetState(bool toPerspective)
	{
		if (toPerspective == m_targetMorphStatePerspective) return;
		m_targetMorphStatePerspective = toPerspective;
		m_isMorphing = true;
	}
}