#pragma once

#include "game/World.h"

#include "render/Renderer.h"
#include "render/VertexCache.h"

#include "render/gui/TowerPlacePopup.h"
#include "render/gui/MobTooltip.h"
#include "render/gui/CastleTooltip.h"

#include "render/gui/imgui/imgui.h"

#include <glm/glm.hpp>

namespace td {

namespace client {

class ClientGame;

} // namespace client


namespace render {

class WorldRenderer : public game::WorldListener {
private:
    client::ClientGame* m_Client;
    Renderer* m_Renderer;
    game::World* m_World;
    std::unique_ptr<GL::VertexArray> m_WorldVao, m_MobVao, m_SelectTileVao;
    glm::vec2 m_CamPos;
    glm::vec2 m_CursorPos;
    glm::vec2 m_HoldCursorPos;
    glm::vec2 m_LastClicked;
    float m_Zoom;
    float m_CamSensibility = 1;
    bool m_PopupOpened = false;
    VertexCache m_TowersCache;

    std::unique_ptr<gui::TowerPlacePopup> m_TowerPlacePopup;
    std::unique_ptr<gui::MobTooltip> m_MobTooltip;
    std::unique_ptr<gui::CastleTooltip> m_CastleTooltip;
public:
    WorldRenderer(game::World* world, client::ClientGame* client);
    ~WorldRenderer();

    void LoadModels();

    static ImVec4 GetImGuiTeamColor(game::TeamColor color);

    void Update();
    void Render();

    void SetCamPos(float camX, float camY);

    void MoveCam(float relativeX, float relativeY, float aspectRatio);
    void ChangeZoom(float zoom);

    // WorldListener

    virtual void OnTowerAdd(game::TowerPtr tower);
    virtual void OnTowerRemove(game::TowerPtr tower);
private:
    void Click();
    void RenderWorld() const;
    void RenderTowers() const;
    void RenderMobs() const;
    void RenderTileSelect() const;
    void RenderPopups();
    void RenderTowerUpgradePopup();
    void RenderMobTooltip() const;
    void RenderCastleTooltip() const;
    void DetectClick();
    void DetectMobHovering() const;
    void DetectCastleHovering() const;
    void RenderTooltips() const;
    void RemoveTower();
    glm::vec2 GetCursorWorldPos() const;
    glm::vec2 GetClickWorldPos() const;

    void UpdateCursorPos();
};

} // namespace render
} // namespace td
