#ifndef CENTITY_HPP
#define CENTITY_HPP

#include <forward_list>
#include <memory>
#include "../Utils/CSerializable.hpp"
#include <entt/entt.hpp>

namespace CosmicCore
{
    class CScene;
    
    class CEntity : public CSerializable {
        using ECManager = entt::registry;
        using EntityId = entt::entity;

        private:

            /**
            * @brief A pointer to the scene containing the entity.
            */
            std::weak_ptr<CScene> m_scene;

            ECManager& m_registryReference;

            EntityId m_handle;

        public:

            /**
            * @brief CEntity's default constructor, disabled.
            */
            CEntity() = delete;

            CEntity(ECManager& registry, EntityId handle);

            CEntity(const CEntity& cop);
            /**
            * @brief CEntity's destructor.
            */
            ~CEntity(void) = default;

            /**
            * @brief Getter to the parent entity.
            * @return a pointer to the parent entity m_parent. nullptr if there is not.
            */
            CEntity getParent();

            template<typename compType, typename... Args>
            void addComponent(std::forward_list<Args...> args)
            {
                m_registryReference.emplace<compType>(m_handle, *this, args);
            }

            template<typename compType>
            void addComponent()
            {
                m_registryReference.emplace<compType>(m_handle, *this);
            }

            /**
            * @brief Getter to the entity's scene.
            * @return The pointer m_scene.
            */
            std::weak_ptr<CScene> getScene();

            /**
            * @brief Setter of the scene.
            * @param[in, out] e The scene in which the entity will be set.
            */
            void setScene(std::weak_ptr<CScene> s);

            nlohmann::json to_json();
    };

}
#endif