// =====================================================================================================================
//  fennec, a free and open source game engine
//  Copyright © 2025 - 2026  Medusa Slockbower
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================


#ifndef FENNEC_MATH_VECTOR_BASE_H
#define FENNEC_MATH_VECTOR_BASE_H

#include <fennec/math/detail/_forward.h>

#include <fennec/math/swizzle.h>
#include <fennec/math/vector_storage.h>

#include <fennec/containers/array.h>

namespace fennec::detail
{

///
/// \brief helper class for generating vectors
/// \tparam scalar base scalar type
/// \tparam size size of the vector type
template<typename scalar, size_t size>
struct vector_base_type_helper
{
	///
	/// \var SizeV
	/// \brief size of the vector type
	inline static constexpr size_t SizeV = size;


	///
	/// \brief Base scalar type
	using ScalarT = scalar;

	///
	/// \brief Base vector type
	using VectorT = vec<ScalarT, SizeV>;

	///
	/// \brief Backing array holding the elements
	using DataT = array<ScalarT, SizeV>;

	///
	/// \brief Helper for generating a swizzle from a set of indices
	/// \tparam IndicesV Indices of the vector to pull from
	template<size_t...IndicesV> struct SwizzleGen
	{
		/// \brief generated swizzle type
		using type = swizzle<VectorT, DataT, ScalarT, IndicesV...>;
	};

	///
	/// \tparam IndicesV Indices of the vector to pull from
	template<size_t IndexV> struct SwizzleGen<IndexV>
	{
		/// \brief decayed scalar type
		using type = ScalarT;
	};

	///
	/// \brief backing storage type
	using StorageT = vector_storage<SizeV, SwizzleGen, DataT>;
};

///
/// \brief helper for getting the storage type of the vector constructed with the provided size and scalar type
template<typename ScalarT, size_t SizeV>
using vector_base_type = typename vector_base_type_helper<ScalarT, SizeV>::StorageT;

}

#endif // FENNEC_MATH_VECTOR_BASE_H
