/*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_NET_CLIENT_CONTROLLER
#define DEF_NET_CLIENT_CONTROLLER

#include "Player/Control/InputReadingController.hpp"

class PlayerStatus;
class PlayerActionSender;

/// Contains the current input state of a NetClientController
struct ClientInputState
{
    explicit ClientInputState(bool last_moveleft = false,
                              bool last_moveright = false,
                              bool last_crouch = false,
                              bool moveleft = false,
                              bool moveright = false,
                              bool crouch = false) :
    lastMoveLeft(last_moveleft), lastMoveRight(last_moveright),
    lastCrouch(last_crouch), moveLeftDown(moveleft), moveRightDown(moveright),
    crouchDown(crouch)
    {

    }

    bool lastMoveLeft = false;
    bool lastMoveRight = false;
    bool lastCrouch = false;
    bool moveLeftDown = false;
    bool moveRightDown = false;
    bool crouchDown = false;
};

/// Interface to pass an updated player status to a client controller
/// Useful to export/import and thus maintain the input state of the local
/// client when re-ordering players (causing NetClientController re-allocations)

class ClientPlayerInterface
{
    public:
        virtual ~ClientPlayerInterface() {}

        virtual void playerStatusReceived(const PlayerStatus &status) = 0;
        virtual ClientInputState getInputState() const = 0;
};

class NetClientController : public InputReadingController,
                            public ClientPlayerInterface
{
    public:
        explicit NetClientController(PlayerActionSender *actionSender,
                                     const ClientInputState &initialState);
        void act() override;

        //ClientPlayerInterface callback
        void playerStatusReceived(const PlayerStatus &status) override;
        ClientInputState getInputState() const override;

    private:
        void punchPressed() override;
        void kickPressed() override;
        void throwPressed() override;
        void jumpPressed() override;

        bool m_lastKnownMoveLeft, m_lastKnownMoveRight, m_lastKnownCrouch;

        /// To generate and send player actions,
        /// not nullptr only for the locally controlled client player
        PlayerActionSender *m_actionSender;
};

#endif
