/*
 * 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 "Base/PlatformEnums.hpp"
#include <functional>

namespace OpenVulkano
{
	class IPlatform;
	class IRenderer;

	/**
	 * \brief Helper class the produces all the platform depending classes
	 */
	class PlatformProducer
	{
	public:

		/**
		 * \brief Creates the renderer for the given render api
		 * \param renderApi The render api that should be used
		 * \return The created Renderer.
		 * \throws std::runtime_error if the render api is not supported
		 */
		static IRenderer* CreateRenderManager(RenderAPI renderApi);

		/**
		 * \brief Creates a platform that fits best for the current environment
		 * \param renderApi The render api that should be used when searching for the best suited platform provider
		 * \return The created platform
		 * \throws std::runtime_error if the render api is not supported
		 */
		static IPlatform* CreatePlatform(RenderAPI renderApi);

		static void RegisterPlatformProducer(RenderAPI renderApi, std::function<IPlatform*()> createMethod);

		static void RegisterRendererProducer(RenderAPI renderApi, std::function<IRenderer*()> createMethod);
	};

	template<class PLATFORM_CLASS>
	struct PlatformProducerRegistration
	{
		PlatformProducerRegistration(RenderAPI renderApi)
		{
			PlatformProducer::RegisterPlatformProducer(renderApi, []() -> IPlatform* { return new PLATFORM_CLASS(); });
		}
	};

	template<class RENDERER_CLASS>
	struct RendererProducerRegistration
	{
		RendererProducerRegistration(RenderAPI renderApi)
		{
			PlatformProducer::RegisterRendererProducer(renderApi, []() -> IRenderer* { return new RENDERER_CLASS(); });
		}
	};
}
