#include "EntityAdmin.h"

#include "DespawnAtComponent.h"
#include "DynamicBodyComponent.h"
#include "FacingComponent.h"
#include "FactionComponent.h"
#include "HealthComponent.h"
#include "HqProxyComponent.h"
#include "MovementIntentComponent.h"
#include "PositionComponent.h"
#include "DebrisComponent.h"
#include "SensorRangeComponent.h"
#include "ShipIdentityComponent.h"
#include "StationBodyComponent.h"

entt::entity EntityAdmin::createEntity()
{
    return m_registry.create();
}

entt::entity EntityAdmin::createModuleEntity()
{
    return m_registry.create();
}

bool EntityAdmin::isValid(entt::entity entity) const
{
    return m_registry.valid(entity);
}

void EntityAdmin::destroy(entt::entity entity)
{
    m_registry.destroy(entity);
}

void EntityAdmin::clear()
{
    m_registry.clear();
}

entt::entity EntityAdmin::spawnShip(QVector2D position, float hp, float maxHp,
                                    float maxSpeed_tpt, float mainAcceleration_tptt,
                                    float maneuveringAcceleration_tptt, float maxAngularAcceleration_rptt,
                                    float maxRotationSpeed_rpt, float sensorRange_tiles,
                                    const std::string& schematicId, bool isEnemy)
{
    entt::entity entity = createEntity();
    addComponent<PositionComponent>(entity, PositionComponent{position});
    addComponent<HealthComponent>(entity, HealthComponent{hp, maxHp});
    addComponent<FactionComponent>(entity, FactionComponent{isEnemy});
    addComponent<FacingComponent>(entity, FacingComponent{0.0f});
    addComponent<DynamicBodyComponent>(entity, DynamicBodyComponent{
        maxSpeed_tpt,
        mainAcceleration_tptt,
        maneuveringAcceleration_tptt,
        maxAngularAcceleration_rptt,
        maxRotationSpeed_rpt,
        QVector2D(0.0f, 0.0f),  // velocity_tpt
        0.0f,                    // angularVelocity_rpt
        QVector2D(0.0f, 0.0f),  // linearAcceleration_tptt
        0.0f                     // angularAcceleration_rptt
    });
    addComponent<SensorRangeComponent>(entity, SensorRangeComponent{sensorRange_tiles});
    addComponent<ShipIdentityComponent>(entity, ShipIdentityComponent{schematicId});
    addComponent<MovementIntentComponent>(entity, MovementIntentComponent{0, QVector2D(0.0f, 0.0f)});
    return entity;
}

entt::entity EntityAdmin::spawnStation(QPoint anchor, QSize footprint,
                                       const std::vector<QPoint>& bodyCells,
                                       float hp, float maxHp, bool isEnemy)
{
    entt::entity entity = createEntity();
    QVector2D center(anchor.x() + footprint.width() / 2.0f,
                     anchor.y() + footprint.height() / 2.0f);
    addComponent<PositionComponent>(entity, PositionComponent{center});
    addComponent<HealthComponent>(entity, HealthComponent{hp, maxHp});
    addComponent<FactionComponent>(entity, FactionComponent{isEnemy});
    addComponent<StationBodyComponent>(entity, StationBodyComponent{anchor, footprint, bodyCells});
    return entity;
}

entt::entity EntityAdmin::spawnDebris(QVector2D position, int amount, Tick despawnAt)
{
    entt::entity entity = createEntity();
    addComponent<PositionComponent>(entity, PositionComponent{position});
    addComponent<DebrisComponent>(entity, DebrisComponent{amount});
    addComponent<DespawnAtComponent>(entity, DespawnAtComponent{despawnAt});
    return entity;
}

entt::entity EntityAdmin::spawnHqProxy(QVector2D position, float hp, float maxHp)
{
    entt::entity entity = createEntity();
    addComponent<PositionComponent>(entity, PositionComponent{position});
    addComponent<HealthComponent>(entity, HealthComponent{hp, maxHp});
    addComponent<FactionComponent>(entity, FactionComponent{false});
    addComponent<HqProxyComponent>(entity);
    return entity;
}
