//
// Created by Dan Crosby on 3/14/21.
//

#ifndef EAGLE0_COMMANDFACTORY_HPP
#define EAGLE0_COMMANDFACTORY_HPP

#include "src/main/cpp/net/eagle0/shardok/library/ShardokCommand.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/map/Coordinates.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/settings/GameSettings.hpp"
#include "src/main/flatbuffer/net/eagle0/shardok/storage/hex_map.hpp"
#include "src/main/flatbuffer/net/eagle0/shardok/storage/unit.hpp"

namespace shardok {

using PossibleChargees = vector<UnitId>;
using Unit = net::eagle0::shardok::storage::fb::Unit;
using Units = flatbuffers::Vector<const Unit*>;
using HexMap = net::eagle0::shardok::storage::fb::HexMap;
using WeatherFb = net::eagle0::shardok::storage::fb::Weather;

// An abstract class representing a Factory capable of producing Commands based on the game state
class CommandFactory {
public:
    virtual ~CommandFactory() = default;

    struct CommandParams {
        const Unit* unit;
        const ActionPoints remainingActionPoints;
        const Coords& position;
        const WeatherFb* weatherFb;
        const bool isEligibleCharger;
        const PossibleChargees& possibleChargees;
        const HexMap* hexMap;
        const Units* units;
        const vector<PlayerId>& allyPids;
        const bool isAttacker;
        const bool unitMovedIntoZoc;
    };

    virtual void AddAvailableCommands(CommandList& commands, const CommandParams& params) const = 0;

    virtual auto IncludeInFollowUps() const -> bool { return true; }
};
}  // namespace shardok

#endif  // EAGLE0_COMMANDFACTORY_HPP
