/*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_PLAYER_ACTION
#define DEF_PLAYER_ACTION

#include <cstdint>
#include <list>

class Player;

/// Describes an action that could be performed by a player, used
/// in networked games for clients to request the server to perform actions.
class PlayerAction
{
    public:
        enum class Index : std::uint8_t
        {
            Jump = 0,
            MoveLeft = 1,
            MoveRight = 2,
            StopMoving = 3,
            Crouch = 4,
            Uncrouch = 5,
            Punch = 6,
            Kick = 7,
            ThrowShuriken = 8
        };

        enum : std::uint8_t
        {
            IndexLimit = static_cast<std::uint8_t>(Index::ThrowShuriken)
        };

        PlayerAction();
        PlayerAction(Index actionIx);

        /// Apply to Player if the action triggers a punctual state change
        /// (No state change of indefinite duration like crouching or moving,
        /// which is handled directly by NetServerController)
        void applyPunctual(Player &player) const;

        /// Read/write from buffer
        bool readFromBuffer(std::list<std::uint8_t> &bytes);
        bool writeToBuffer(std::list<std::uint8_t> &dst) const;

        Index getIndex() const;

    private:
        Index m_actionIndex;
};

/// To receive requests to send a PlayerAction over the network
class PlayerActionSender
{
    public:
        virtual ~PlayerActionSender() {}
        virtual void sendPlayerAction(PlayerAction::Index actionIx) = 0;
};

#endif
