//
//  ChargeCommand.hpp
//  eagle0_engine
//
//  Created by Dan Crosby on 1/3/19.
//  Copyright © 2019 none. All rights reserved.
//

#ifndef EAGLE0_SHARDOK_LIBRARY_COMMANDS_CHARGE_COMMAND_HPP
#define EAGLE0_SHARDOK_LIBRARY_COMMANDS_CHARGE_COMMAND_HPP

#include "src/main/cpp/net/eagle0/shardok/library/ActionCost.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/ShardokCommand.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/settings/GameSettings.hpp"

namespace shardok {
using Coords = net::eagle0::shardok::storage::fb::Coords;

class ChargeCommand : public ShardokCommand {
private:
    [[nodiscard]] auto ExecuteWithRolls(
            const GameStateW& currentState,
            double attackerRoll,
            double defenderRoll) const -> vector<ActionResult>;

protected:
    [[nodiscard]] auto InternalExecuteWithRoll(
            const GameStateW& currentState,
            const std::shared_ptr<RandomGenerator>& generator,
            std::optional<int32_t> roll) const -> vector<ActionResult> override;

    const ActionCost cost;
    const SettingsGetter settings;
    const UnitId attackerId;
    const UnitId defenderId;
    const Coords defenderCoords;
    const AttackOrientation attackOrientation;

public:
    ChargeCommand(
            const ActionCost& cost,
            const SettingsGetter& settingsGetter,
            PlayerId playerId,
            UnitId attackerId,
            UnitId defenderId,
            const Coords& defenderLocation,
            AttackOrientation attackOrientation);
    ~ChargeCommand() override = default;

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

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

    [[nodiscard]] auto IsRequiredToEndTurn() const -> bool override { return true; }
    [[nodiscard]] auto CanBeFollowUp() const -> bool override { return true; }
    [[nodiscard]] auto CanDoWithLowMorale() const -> bool override { return false; }
    [[nodiscard]] auto CanDoWhileStunned() const -> bool override { return false; }
    [[nodiscard]] auto CanDoWithLowVigor() const -> bool override { return false; }
    [[nodiscard]] auto CanDoAfterMovingIntoZoc() const -> bool override { return true; }
    [[nodiscard]] auto CanUseClientRoll() const -> bool override { return true; }

    [[nodiscard]] int GetActorUnitId() const override { return attackerId; }
    [[nodiscard]] MapIndex GetTargetRow() const override { return defenderCoords.row(); }
    [[nodiscard]] MapIndex GetTargetColumn() const override { return defenderCoords.column(); }
};
}  // namespace shardok

#endif  // EAGLE0_SHARDOK_LIBRARY_COMMANDS_CHARGE_COMMAND_HPP
