/*
 * 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/.
 */

#pragma once

#include "CameraController.hpp"
#include "Math/Math.hpp"
#include <memory>
#include <mutex>
#include <atomic>

namespace OpenVulkano
{
	namespace AR
	{
		class ArSession;
	}

	class ArCameraController final : public CameraController
	{
		std::shared_ptr<AR::ArSession> m_arSession;
		Math::Matrix4f m_registration;
		Math::Matrix4f m_viewMatrixToUpdate;
		std::mutex m_mutex;
		std::atomic<bool> m_updated;

	public:
		ArCameraController();

		ArCameraController(Scene::Camera* camera, const std::shared_ptr<AR::ArSession>& session = nullptr, const Math::Matrix4f& registration = Math::Matrix4f (1));

		~ArCameraController() override;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Woverloaded-virtual"
		void Init(Scene::Camera* camera, const std::shared_ptr<AR::ArSession>& session = nullptr, const Math::Matrix4f& registration = Math::Matrix4f (1));
#pragma clang diagnostic pop

		void Tick() override;

		void Close() override;

		void SetRegistration(const Math::Matrix4f& reg) { m_registration = reg; }

		[[nodiscard]] std::shared_ptr<AR::ArSession> GetArSession() const { return m_arSession; }

	private:
		void CommonInit();

		void UpdateCameraViewMatrix(const Math::Matrix4f& transform);
	};
}