//
// Created by Dan Crosby on 4/5/20.
//

#ifndef EAGLE0_MOVECOMMAND_HPP
#define EAGLE0_MOVECOMMAND_HPP

#include "src/main/cpp/net/eagle0/shardok/library/BattalionType.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/ShardokCommand.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/map/CoordsSet.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/settings/GameSettings.hpp"
#include "src/main/flatbuffer/net/eagle0/shardok/storage/unit.hpp"
#include "src/main/protobuf/net/eagle0/shardok/common/command_type.pb.h"

namespace shardok {
using net::eagle0::shardok::common::MOVE_COMMAND;
using net::eagle0::shardok::storage::fb::Unit;
using Units = flatbuffers::Vector<const Unit*>;

class MoveCommand : public ShardokCommand {
protected:
    [[nodiscard]] auto InternalExecute(
            const GameStateW& currentState,
            const std::shared_ptr<RandomGenerator>& generator) const
            -> vector<ActionResult> override;

    const ActionPoints pointCost;
    const Unit* moverBefore;
    const SettingsGetter settings;
    const vector<Coords> interimTargets;
    const Units* allUnits;
    const vector<PlayerId> allyPids;
    const HexMap* map;
    std::unordered_set<CommandType> followUpCommandTypes;
    const bool willUnhide;
    const CoordsSet enemyZocCoords;

public:
    MoveCommand(
            ActionPoints pointCost,
            const Unit* mover,
            const SettingsGetter& settingsGetter,
            vector<Coords> interimTargets,
            const Units* units,
            vector<PlayerId> allyPids,
            const HexMap* inMap,
            bool unhide,
            const CoordsSet& enemyZocCoords);

    ~MoveCommand() override = default;

    [[nodiscard]] auto GetCommandType() const -> CommandType override {
        return net::eagle0::shardok::common::MOVE_COMMAND;
    }

    [[nodiscard]] auto GetCommandProto() const -> CommandProto override;

    [[nodiscard]] auto CanBeFollowUp() const -> bool override { return false; };
    [[nodiscard]] auto CanDoWithLowMorale() const -> bool override { return true; }

    void AddFollowUpCommandTypes(const std::unordered_set<CommandType>& newTypes) override;
};
}  // namespace shardok

#endif  // EAGLE0_MOVECOMMAND_HPP
