/*
 * 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 "Math/Math.hpp"
#include <ryml.hpp>
#include <ryml_std.hpp>
#include <c4/format.hpp>

namespace c4
{
	template<class T>
	size_t to_chars(ryml::substr buf, const OpenVulkano::Math::Vector2<T>& v)
	{ return ryml::format(buf, "({},{})", v.x, v.y); }

	template<class T>
	size_t to_chars(ryml::substr buf, const OpenVulkano::Math::Vector3<T>& v)
	{ return ryml::format(buf, "({},{},{})", v.x, v.y, v.z); }

	template<class T>
	size_t to_chars(ryml::substr buf, const OpenVulkano::Math::Vector4<T>& v)
	{ return ryml::format(buf, "({},{},{},{})", v.x, v.y, v.z, v.w); }

	template<class T>
	size_t to_chars(ryml::substr buf, const OpenVulkano::Math::Vector2_SIMD<T>& v)
	{ return ryml::format(buf, "({},{})", v.x, v.y); }

	template<class T>
	size_t to_chars(ryml::substr buf, const OpenVulkano::Math::Vector3_SIMD<T>& v)
	{ return ryml::format(buf, "({},{},{})", v.x, v.y, v.z); }

	template<class T>
	size_t to_chars(ryml::substr buf, const OpenVulkano::Math::Matrix3<T>& m)
	{
		return ryml::format(buf, "({},{},{}),({},{},{}),({},{},{})", m[0][0], m[1][0], m[2][0], m[0][1], m[1][1], m[2][1], m[0][2], m[1][2], m[2][2]); }

	template<class T>
	size_t to_chars(ryml::substr buf, const OpenVulkano::Math::Matrix3_SIMD<T>& m)
	{ return ryml::format(buf, "({},{},{}),({},{},{}),({},{},{})", m[0][0], m[1][0], m[2][0], m[0][1], m[1][1], m[2][1], m[0][2], m[1][2], m[2][2]); }

	template<class T>
	size_t to_chars(ryml::substr buf, const OpenVulkano::Math::Matrix4<T>& m)
	{
		return ryml::format(buf, "({},{},{},{}),({},{},{},{}),({},{},{},{}),({},{},{},{})", m[0][0], m[1][0], m[2][0], m[3][0], m[0][1], m[1][1], m[2][1], m[3][1], m[0][2], m[1][2], m[2][2], m[3][2], m[0][3],
							m[1][3], m[2][3], m[3][3]);
	}

	template<class T>
	bool from_chars(ryml::csubstr buf, OpenVulkano::Math::Vector2<T>* v)
	{
		size_t ret = ryml::unformat(buf, "({},{})", v->x, v->y);
		return ret != ryml::yml::npos;
	}

	template<class T>
	bool from_chars(ryml::csubstr buf, OpenVulkano::Math::Vector3<T>* v)
	{
		size_t ret = ryml::unformat(buf, "({},{},{})", v->x, v->y, v->z);
		return ret != ryml::yml::npos;
	}

	template<class T>
	bool from_chars(ryml::csubstr buf, OpenVulkano::Math::Vector4<T>* v)
	{
		size_t ret = ryml::unformat(buf, "({},{},{},{})", v->x, v->y, v->z, v->w);
		return ret != ryml::yml::npos;
	}

	template<class T>
	bool from_chars(ryml::csubstr buf, OpenVulkano::Math::Vector2_SIMD<T>* v)
	{
		size_t ret = ryml::unformat(buf, "({},{})", v->x, v->y);
		return ret != ryml::yml::npos;
	}

	template<class T>
	bool from_chars(ryml::csubstr buf, OpenVulkano::Math::Vector3_SIMD<T>* v)
	{
		size_t ret = ryml::unformat(buf, "({},{},{})", v->x, v->y, v->z);
		return ret != ryml::yml::npos;
	}

	template<class T>
	size_t from_chars(ryml::csubstr buf, OpenVulkano::Math::Matrix3<T>* mp)
	{
		auto& m = *mp;
		size_t ret = ryml::unformat(buf, "({},{},{}),({},{},{}),({},{},{})", m[0][0], m[1][0], m[2][0], m[0][1], m[1][1], m[2][1], m[0][2], m[1][2], m[2][2]);
		return ret != ryml::yml::npos;
	}

	template<class T>
	size_t from_chars(ryml::csubstr buf, OpenVulkano::Math::Matrix3_SIMD<T>* mp)
	{
		auto& m = *mp;
		size_t ret = ryml::unformat(buf, "({},{},{}),({},{},{}),({},{},{})", m[0][0], m[1][0], m[2][0], m[0][1], m[1][1], m[2][1], m[0][2], m[1][2], m[2][2]);
		return ret != ryml::yml::npos;
	}

	template<class T>
	size_t from_chars(ryml::csubstr buf, OpenVulkano::Math::Matrix4<T>* mp)
	{
		auto& m = *mp;
		size_t ret = ryml::unformat(buf, "({},{},{},{}),({},{},{},{}),({},{},{},{}),({},{},{},{})", m[0][0], m[1][0], m[2][0], m[3][0], m[0][1], m[1][1], m[2][1], m[3][1], m[0][2], m[1][2], m[2][2], m[3][2], m[0][3],
							m[1][3], m[2][3], m[3][3]);
		return ret != ryml::yml::npos;
	}
}