/*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_CHARACTER
#define DEF_CHARACTER

#include "Tools/I18n.hpp" ///< _ macro for i18n
#include "Tools/BuildValues.hpp" ///< Generated at build time
#include <pugixml.hpp> ///< fetchNames method
#include <algorithm>
#include <string>
#include <vector>

struct Character
{
    enum class Type { Human, AI };

    Character() : type(Type::Human) {}

    Character(const std::string &charName, Type charType) :
    name(charName), type(charType)
    {

    }

    std::string getFullName() const
    {
        if (name.empty())
            return _(CharacterSelectionNoName);
        else if (type == Type::AI)
            return _f(CharacterSelectionAIName, std::make_pair("name", name));

        return name;
    }

    bool operator==(const Character& other) {
        return name == other.name && type == other.type;
    }

    bool operator!=(const Character& other) {
        return !((*this) == other);
    }

    std::string name;
    Type type;

    static std::vector<std::string> fetchNames()
    {
        const std::string xmlPath = BuildValues::data("cfg/characters.xml");
        pugi::xml_document xmlFile;
        if (!xmlFile.load_file(xmlPath.c_str()))
            return std::vector<std::string>();

        std::vector<std::string> characters;
        pugi::xml_node characterNode;
        for (characterNode = xmlFile.child("main").child("character");
             characterNode;
             characterNode = characterNode.next_sibling("character"))
        {
            characters.emplace_back(characterNode.attribute("name").value());
        }

        return characters;
    }

    static bool validateName(const std::vector<std::string> &names,
                             const std::string &value)
    {
        return (std::find(names.begin(), names.end(), value) != names.end());
    }
};

#endif
