#pragma once

#include "ClientConnexion.h"
#include "ClientGame.h"

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

#include "protocol/Protocol.h"

#include "render/Renderer.h"

#include "network/Network.h"

namespace td {
namespace client {

class Client {
private:
    render::Renderer* m_Renderer;
    ClientConnexion m_Connexion;
    ClientGame m_Game;
    bool m_Connected;
public:
    Client(render::Renderer* renderer) : m_Renderer(renderer), m_Game(this), m_Connected(false) {}

    const ClientGame& getGame() const { return m_Game; }
    const ClientConnexion& getConnexion() const { return m_Connexion; }
    render::Renderer* getRenderer() const { return m_Renderer; }

    ClientGame& getGame() { return m_Game; }
    ClientConnexion& getConnexion() { return m_Connexion; }

    void tick(std::uint64_t delta);

    void render();

    bool connect(const network::IPAddresses& addresses, std::uint16_t port);
    void closeConnection();

    bool isConnected() const { return m_Connexion.getSocketStatus() == network::Socket::Connected; }

    void selectTeam(game::TeamColor team);
    void sendMobs(const std::vector<protocol::MobSend>& mobSends);
    void placeTower(game::TowerType type, const glm::vec2& position);
    void upgradeTower(game::TowerID tower, game::TowerLevel level);
};

} // namespace client
} // namespace td
