#include "game/server/ServerWorld.h"
#include "game/server/Server.h"
#include "misc/Random.h"

#define MOB_SPAWN_PRECISION 100.0f

namespace td {
namespace server {

ServerWorld::ServerWorld(Server* server, ServerGame* game) : game::World(game), m_CurrentMobID(0), m_Server(server) {

}

void ServerWorld::spawnMobs(game::MobType type, std::uint8_t level, game::PlayerID sender, std::uint8_t count) {
    for (int i = 0; i < count; i++) {
        game::TeamColor senderTeam = m_Game->getPlayers().at(sender).getTeamColor();
        game::Spawn* enemyMobSpawn;

        if (senderTeam == game::TeamColor::Red) {
            enemyMobSpawn = &getTeam(game::TeamColor::Blue).getSpawn();
        } else {
            enemyMobSpawn = &getTeam(game::TeamColor::Red).getSpawn();
        }

        float spawnWidth = enemyMobSpawn->getWidth();
        float spawnHeight = enemyMobSpawn->getHeight();

        float spawnCenterX = enemyMobSpawn->getCenterX();
        float spawnCenterY = enemyMobSpawn->getCenterY();

        auto mobStats = getMobStats(type, level);
        auto mobSize = mobStats->getSize();

        float minSpawnX = spawnCenterX - spawnWidth / 2.0f + mobSize.x / 2.0f;
        float maxSpawnX = spawnCenterX + spawnWidth / 2.0f - mobSize.x / 2.0f;

        float minSpawnY = spawnCenterY - spawnHeight / 2.0f + mobSize.y / 2.0f;
        float maxSpawnY = spawnCenterY + spawnHeight / 2.0f - mobSize.y / 2.0f;

        float mobX = utils::getRandomReal<float>(minSpawnX, maxSpawnX);
        float mobY = utils::getRandomReal<float>(minSpawnY, maxSpawnY);

        spawnMobAt(m_CurrentMobID, type, level, sender, mobX, mobY, enemyMobSpawn->getDirection());

        protocol::SpawnMobPacket packet(m_CurrentMobID, type, level, sender, mobX, mobY, enemyMobSpawn->getDirection());
        m_Server->broadcastPacket(&packet);

        m_CurrentMobID++;
    }
}

game::TowerPtr ServerWorld::placeTowerAt(game::TowerType type, std::int32_t x, std::int32_t y, game::PlayerID builder) {
    game::TowerPtr tower = World::placeTowerAt(m_CurrentTowerID, type, x, y, builder);
    m_CurrentTowerID++;
    return tower;
}

} // namespace server
} // namespace td
