#pragma once

#include "game/Team.h"
#include "game/World.h"
#include "game/Player.h"

namespace td {
namespace game {

enum class GameState : std::uint8_t {
    Lobby,
    Game,
    EndGame,
    Disconnected,
};

typedef std::map<std::uint8_t, Player> PlayerList;

class Game {
protected:
    World* m_World;
    std::array<Team, 2> m_Teams = { Team{TeamColor::Red}, Team{TeamColor::Blue} };
    GameState m_GameState = GameState::Lobby;
    PlayerList m_Players;
public:
    Game(World* world);
    virtual ~Game();

    virtual void tick(std::uint64_t delta);

    Team& getRedTeam() { return m_Teams[(std::uint8_t)TeamColor::Red]; }
    const Team& getRedTeam() const { return m_Teams[(std::uint8_t)TeamColor::Red]; }

    Team& getBlueTeam() { return m_Teams[(std::uint8_t)TeamColor::Blue]; }
    const Team& getBlueTeam() const { return m_Teams[(std::uint8_t)TeamColor::Blue]; }

    Team& getTeam(TeamColor team) { return m_Teams[(std::uint8_t)team]; }
    const Team& getTeam(TeamColor team) const { return m_Teams[(std::uint8_t)team]; }

    GameState getGameState() const { return m_GameState; }
    void setGameState(GameState gameState) { m_GameState = gameState; };

    const World* getWorld() const { return m_World; }
    World* getWorld() { return m_World; }

    const PlayerList& getPlayers() const { return m_Players; }
    PlayerList& getPlayers() { return m_Players; }

    const Player& getPlayerById(PlayerID id) const { return m_Players.find(id)->second; }
    Player& getPlayerById(PlayerID id) { return m_Players.find(id)->second; }

};

} // namespace game 
} // namespace td
