#pragma once

#include <cstddef>
#include <utility.h>
#include <Entities/Components.h>
#include <Entities/EntityMemoryPool.h>

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

	Entity() = delete;
	Entity(EntityMemoryPool& dataLocation, index_t index_in)
		: m_data(dataLocation) 
		, m_index(index_in)
	{ }

	void add()
	{ m_data.getAlive(m_index).setTrue(); }

public:
	// template<typename T>
	// bool hasComponent() const;

	template<typename T>
	T& getComponent() const
	{ return m_data.getComponent<T>(m_index); }

	template<typename T>
	void addComponent(const T& data)
	{
		T& component = m_data.getComponent<T>(m_index);
		component = data;
	}

	template<typename T>
	void removeComponent()
	{
		T& component = m_data.getComponent<T>(m_index);
		component = T();
	}

	size_t id() const
	{ return m_data.getId(m_index); }

	tag_t tag() const
	{ return m_data.getTag(m_index); }

	bool alive() const
	{ return m_data.getAlive(m_index); }

	bool visible() const
	{ return m_data.getVisiblity(m_index); }

	void makeVisible()
	{ m_data.getVisiblity(m_index).setTrue(); }

	void makeInvisible()
	{ m_data.getVisiblity(m_index).setFalse(); }

	void flipVisibility()
	{ m_data.getVisiblity(m_index).flip(); }

	void destroy()
	{ m_data.getAlive(m_index).setFalse(); }

private:
	EntityMemoryPool& m_data;
	index_t m_index;
};