//
//  Unit.hpp
//  eagle0
//
//  Created by Dan Crosby on 8/20/18.
//  Copyright © 2018 none. All rights reserved.
//

#ifndef EAGLE0_SHARDOK_LIBRARY_UNIT_UNIT_HPP
#define EAGLE0_SHARDOK_LIBRARY_UNIT_UNIT_HPP

#include <map>

#include "src/main/cpp/net/eagle0/shardok/library/ShardokCTypes.h"
#include "src/main/cpp/net/eagle0/shardok/library/settings/GameSettings.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/unit/Battalion.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/unit/Hero.hpp"
#include "src/main/flatbuffer/net/eagle0/shardok/storage/unit.hpp"

namespace shardok {

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

[[nodiscard]] auto IsDestroyed(const Unit &unit) -> bool;

[[nodiscard]] auto MaxActionPoints(const Unit &unit) -> ActionPoints;

[[nodiscard]] auto OpponentKnowledge(const Unit &unit, PlayerId toPlayer) -> int;
[[nodiscard]] auto OpponentKnowledge(const Unit *unit, PlayerId toPlayer) -> int;

// Returns the casualty count.
auto MutatingApplyDamageFrom(
        Unit *recipient,
        Unit *from,
        const CombatDamage &damage,
        const Terrain &terrain,
        AttackOrientation direction,
        bool isAmbush,
        double moralePerCasualty,
        double baseDeadliness,
        const BattalionTypeSPtr &recipientType,
        const BattalionTypeSPtr &fromType) -> int32_t;

auto MutatingApplyEnvironmentalDamage(
        Unit *recipient,
        const CombatDamage &damage,
        const Terrain &terrain,
        double moralePerCasualty,
        double baseDeadliness,
        const BattalionTypeSPtr &type) -> int32_t;

[[nodiscard]] auto WithTakenDamageFb(
        const Unit *victim,
        const CombatDamage &amount,
        const Terrain &terrain,
        AttackOrientation orientation,
        bool isAmbush,
        bool shouldReduceForFortified,
        const SettingsGetter &settings) -> Unit;

void MutatingSpendActionPoints(Unit *unit, const ActionCost &cost);

void MutatingAdjustMorale(Unit *unit, const BattalionTypeSPtr &battalionType, double amount);

void MutatingBumpStrengthXp(Unit *unit, int newXp);
void MutatingBumpAgilityXp(Unit *unit, int newXp);
void MutatingBumpWisdomXp(Unit *unit, int newXp);
void MutatingBumpCharismaXp(Unit *unit, int newXp);

void MutatingBumpOpponentKnowledge(Unit *unit, PlayerId pid, int bump);
void MutatingBumpAllKnowledgeToMinimum(Unit *unit, int bump);

[[nodiscard]] auto ReserveUnitsForPlayer(const Units *units, PlayerId pid)
        -> std::map<UnitId, const Unit *>;
[[nodiscard]] auto PlacedUnitsForPlayer(const Units *units, PlayerId pid)
        -> std::map<UnitId, const Unit *>;

}  // namespace shardok

#endif  // EAGLE0_SHARDOK_LIBRARY_UNIT_UNIT_HPP
