#pragma once

#include <tuple>

#include <Entities/Components.h>
#include <Containers.h>
#include <utility.h>

class EntityManager;
class Entity;

using ComponentsContainer = std::tuple
<
	container::HeapArray<Transform, util::MAX_ENTITIES>,
	container::HeapArray<BoundingBox, util::MAX_ENTITIES>,
	container::HeapArray<Sprite, util::MAX_ENTITIES>
>;

class EntityMemoryPool
{
private:
	friend class EntityManager;
	friend class Entity;

	ComponentsContainer m_components;
	container::HeapArray<tag_t, util::MAX_ENTITIES> m_tags;
	container::HeapArray<subtag_t, util::MAX_ENTITIES> m_subTags;
	container::HeapArray<bool, util::MAX_ENTITIES> m_aliveStates;
	container::HeapArray<bool, util::MAX_ENTITIES> m_visibility;
	container::HeapArray<size_t, util::MAX_ENTITIES> m_ids;
	
private:
	EntityMemoryPool();

	EntityMemoryPool(const EntityMemoryPool&) = delete;

	template<typename T>
	T& getComponent(index_t index) 
	{ return std::get<container::HeapArray<T, util::MAX_ENTITIES>>(m_components)[index]; }

	auto getAlive(index_t index)
	{ return m_aliveStates[index]; }

	auto getVisiblity(index_t index)
	{ return m_visibility[index]; }
	
	tag_t getTag(index_t) const;
	
	size_t getId(index_t) const;

};
