/*
 * 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 <fstream>
#include <string>
#include <ryml.hpp>
#include <ryml_std.hpp>

#include "EngineConfiguration.hpp"
#include "IO/AppFolders.hpp"
#include "Utils.hpp"

namespace OpenVulkano
{
	namespace
	{
		const char* NUM_THREADS_STR                    = "NumThreads";
		const char* FRAMEBUFFER_CLEAR_COLOR_STR        = "FramebufferClearColor";
		const char* PREFER_FRAMEBUFFER_FORMAT_SRGB_STR = "PreferFramebufferFormatSRGB";
		const char* LAZY_RENDERING_STR                 = "LazyRendering";
		const char* VSYNC_STR                          = "VSync";
		const char* FPSCAP_STR                         = "FpsCap";
		const char* PREFERRED_IMAGE_COUNT_STR          = "PreferredImageCount";
	}

	EngineConfiguration::EngineConfiguration()
	{
		const std::string filePath = (AppFolders::GetAppConfigHomeDir() / "EngineConfig.yml").string();
		Array<char> fileContents = Utils::ReadFile(filePath, true, true);
		if(fileContents.Size() == 0)
			return;

		ryml::Tree tree = ryml::parse_in_arena(ryml::to_csubstr(fileContents.Data()));
		ryml::NodeRef root = tree.rootref();

		if (root.has_child(NUM_THREADS_STR) && root[NUM_THREADS_STR].val().is_integer())
		{
			root[NUM_THREADS_STR] >> m_numThreads;
		}

		if (root.has_child(FRAMEBUFFER_CLEAR_COLOR_STR) && root[FRAMEBUFFER_CLEAR_COLOR_STR].is_seq() && root[FRAMEBUFFER_CLEAR_COLOR_STR].num_children() == 4)
		{
			auto clearColorNode = root[FRAMEBUFFER_CLEAR_COLOR_STR];
			for (size_t i = 0; i < 4; ++i)
			{
				clearColorNode[i] >> m_frameBufferClearColor[i];
			}
		}

		if (root.has_child(PREFER_FRAMEBUFFER_FORMAT_SRGB_STR))
		{
			root[PREFER_FRAMEBUFFER_FORMAT_SRGB_STR] >> m_preferFramebufferFormatSRGB;
		}

		if (root.has_child(LAZY_RENDERING_STR))
		{
			root[LAZY_RENDERING_STR] >> m_lazyRendering;
		}

		if (root.has_child(VSYNC_STR)) { root[VSYNC_STR] >> m_vSync; }
		if (root.has_child(FPSCAP_STR) && root[FPSCAP_STR].val().is_integer())
		{
			root[FPSCAP_STR] >> m_fpsCap;
		}
		if (root.has_child(PREFERRED_IMAGE_COUNT_STR) && root[PREFERRED_IMAGE_COUNT_STR].val().is_integer())
		{
			root[PREFERRED_IMAGE_COUNT_STR] >> m_preferredImageCount;
		}
	}

	EngineConfiguration* EngineConfiguration::GetEngineConfiguration()
	{
		static EngineConfiguration config;
		return &config;
	}
}