/*
 * 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 <magic_enum.hpp>
#include <string>

namespace OpenVulkano
{
	class RenderAPI
	{
	public:
		enum RenderApi : uint8_t
		{
			Vulkan = 0,
			//DirectX12,
			//Metal,
		};

		constexpr RenderAPI(RenderApi api) : api(api) {}

		[[nodiscard]] constexpr std::string_view ToString() const
		{
			return magic_enum::enum_name(api);
		}

		[[nodiscard]] constexpr static RenderAPI GetFromName(std::string_view name)
		{
			return magic_enum::enum_cast<RenderApi>(name).value_or(Vulkan);
		}

		constexpr operator std::string_view() const { return ToString(); }

		constexpr operator RenderApi() const { return api; }

		constexpr bool operator==(const RenderAPI other)
		{
			return other.api == api;
		}

		constexpr bool operator==(const RenderApi other)
		{
			return other == api;
		}

		constexpr bool operator!=(const RenderAPI other)
		{
			return !(*this == other);
		}

		constexpr bool operator!=(const RenderApi other)
		{
			return !(*this == other);
		}

	private:
		RenderApi api;
	};

	class Platform
	{
	public:
		enum OS : uint8_t
		{
			Windows = 0, MacOS, Linux, Android, iOS, Unknown
		};

		constexpr Platform(OS os) : os(os) {}

		[[nodiscard]] constexpr std::string_view ToString() const
		{
			return magic_enum::enum_name(os);
		}

		[[nodiscard]] constexpr static Platform GetFromName(std::string_view name)
		{
			return magic_enum::enum_cast<OS>(name).value_or(Unknown);
		}

		constexpr operator std::string_view() const { return ToString(); }

		constexpr operator OS() const { return os; }

		constexpr bool operator==(const Platform other)
		{
			return other.os == os;
		}

		constexpr bool operator==(const OS other)
		{
			return other == os;
		}

		constexpr bool operator!=(const Platform other)
		{
			return !(*this == other);
		}

		constexpr bool operator!=(const OS other)
		{
			return !(*this == other);
		}

	private:
		OS os;
	};
}