/*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_MAIN_MENU_TAB
#define DEF_MAIN_MENU_TAB

#include "Fight/FightRules.hpp"
#include "GUI/Widget/Tab.hpp"
#include "GUI/Widget/TextButton.hpp"
#include <vector>
#include <string>

/// The main menu of the game, handles selection of available options
/// (local game, multiplayer, options, exit, ...) and the game setup for local
/// games (fight mode, number of players/rounds, ...)
class MainMenuTab : public Tab
{
    public:
        /// Eventual result of the selection after the menu was browsed
        enum class Result { None, LocalGame, Multiplayer, Options, Exit };

        /// A menu entry, handled by MenuPhaseTab
        struct Entry
        {
            Entry(std::uint8_t id, const std::string &value) :
            identifier(id), name(value) {}

            std::uint8_t identifier;
            std::string name;
        };

        MainMenuTab(float width, float height, float spacing,
                    const Color &color, const TextButtonSkin &skin);
        void draw() override;

        bool mouseRelease(const Vector &mouseCoords) override;
        bool mouseClick(const Vector &mouseCoords) override;
        bool mouseMove(const Vector &mouseCoords) override;

        void goBack(); ///< Go back to the parent set of entries if any

        bool hasResult() const;
        Result getResult() const;

        /// Get the selected fight rules, relevant if a fight has been selected
        const FightRules &getFightRules() const;

    private:
        enum class Phase { Root, SelectRoundsToWin, SelectPlayerCount };

        /// Represents a single set of entries to be displayed for selection
        class MenuPhaseEntries : public Widget
        {
            public:
                MenuPhaseEntries(const std::vector<Entry> &entries,
                                 const TextButtonSkin &skin,
                                 float spacing);
                void draw() override;

                bool mouseRelease(const Vector &mouseCoords) override;
                bool mouseClick(const Vector &mouseCoords) override;
                bool mouseMove(const Vector &mouseCoords) override;

                void unfocus(); ///< Unfocus all contained text button elements
                void reset(); ///< Reset the menu phase to unselected state
                std::uint8_t getSelection() const;

                float getWidth() const override;
                float getHeight() const override;
                float getSpacing() const;

            private:
                /// Initialize entries and expand skins if needed
                void initEntries(const std::vector<Entry> &entries,
                                 const TextButtonSkin &skin);

                std::vector< std::pair<std::uint8_t, TextButton> > m_entries;
                std::uint8_t m_selection;
                const float m_width, m_height, m_spacing;
        };

        void positionEntries(MenuPhaseEntries &entries);
        void processRootSelection();
        void processPlayerSelection();
        void processRoundSelection();

        Phase m_phase;
        MenuPhaseEntries m_rootEntries;
        MenuPhaseEntries m_selectRoundsEntries;
        MenuPhaseEntries m_selectPlayersEntries;

        Result m_result;
        FightRules m_fightRules;
};

#endif
