/*Copyright (C) 2010-2023 Duncan Deveaux

This file is part of Hikou no mizu.

Hikou no mizu is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Hikou no mizu is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Hikou no mizu.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef DEF_NAME_TAGS
#define DEF_NAME_TAGS

#include "Graphics/Viewport.hpp"
#include "GUI/ShadowText.hpp"
#include "Network/Serialization/PeerData.hpp"
#include <vector>
#include <string>
#include <cassert>

class Player;
class FontManager;

/// Utility struct containing a reference to a player
/// and the username that it should be tagged with
struct TaggedPlayer
{
    TaggedPlayer(const Player &target, const Utf8::utf8_string &targetUsername) :
    player(&target), username(targetUsername) {}

    const Player *player;
    Utf8::utf8_string username;

    /// Makes a list of TaggedPlayer from known non-nullptr players
    /// and associated peer data
    static std::vector<TaggedPlayer> make(const std::vector<PeerData> &peers,
                                    const std::vector<const Player*> &players)
    {
        assert(peers.size() == players.size());

        std::vector<TaggedPlayer> tagged;
        tagged.reserve(peers.size());
        for (std::size_t i = 0; i < peers.size(); i++)
            tagged.emplace_back((*players[i]), peers[i].username);

        return tagged;
    }
};

/// Associates a TaggedPlayer with the text field used to draw its name tag
struct PlayerTag
{
    explicit PlayerTag(const TaggedPlayer &player) : tag(player), width(0.f) {}

    TaggedPlayer tag;
    ShadowText text;
    float width;
};

/// Utility that draws username tags on top of players in networked games
class NameTags
{
    public:
        NameTags(const Vector &viewSize, FontManager &fontManager);
        void draw();
        void update(); ///< Update the position of name tags over each player

        void setPlayers(const std::vector<TaggedPlayer> &players);
        void setCameraView(const Box &view); ///< Update the current camera view

    private:
        void updatePositions();

        std::vector<PlayerTag> m_tags;
        Viewport m_viewport;
        Font *m_font;
};

#endif
