/*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_LOCAL_FIGHT_CONTROLLER
#define DEF_LOCAL_FIGHT_CONTROLLER

#include "Fight/ClientFightScene.hpp"
#include "Fight/FightCameraHandler.hpp"
#include "Fight/Referee.hpp"
#include <SDL2/SDL.h>
#include <string>

class Configuration;
class JoystickManager;
class TextureManager;
class AmbientPlayer;
class SoundEngine;
class Player;
class FightRules;
class RoundAnnouncer;
class FightInterface;
class RoundResultInfo;
class PauseTab;
class EndTab;

struct Character;
struct Vector;

/// Handles a local fight, with a fight scene constrained by a referee's
/// instructions. Attaches to external elements to keep the interface updated
class LocalFightController : public RefereeListener
{
    public:
        LocalFightController(TextureManager &textureManager,
                             AmbientPlayer &ambientPlayer,
                             SoundEngine &soundEngine,
                             const ClientFightScene::DisplayOptions &options,
                             float viewWidth);

        void attach(RoundAnnouncer &announcer, FightInterface &fightInterface,
                    RoundResultInfo &roundResultInfo,
                    PauseTab &pauseTab, EndTab &endTab);

        void initialize(const std::string &arena, const FightRules &rules,
                        const std::vector<Character> &characters,
                        const Configuration &configuration,
                        const JoystickManager &joystickManager);

        void reset(); ///< Reset the game to its initial state
        void togglePause(); ///< Request to pause / unpause the game

        void keyInput(const SDL_Event &event);
        void update(float frameTime);
        void draw(float frameTime, const Vector &viewSize);

        /// Referee instructions
        void readyRound(unsigned int roundId) override;
        void startRound() override;
        void roundOver(std::size_t winnerIx, const Player &winner,
                       std::uint8_t wonRounds) override;
        void roundOverDraw() override;
        void gameOver() override;

    private:
        void updateFightInterfaceResults();
        void loadPlayers(const std::vector<Character> &characters,
                         const Configuration &configuration,
                         const JoystickManager &joystickManager);

        Referee m_referee;
        ClientFightScene m_fightScene;
        bool m_paused;

        RoundAnnouncer *m_announcer;
        FightInterface *m_fightInterface;
        RoundResultInfo *m_roundResultInfo;
        PauseTab *m_pauseTab;
        EndTab *m_endTab;

        TextureManager *m_textureManager;
        const float m_viewWidth;
};

#endif
