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

#ifndef Unit_hpp
#define Unit_hpp

#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 std::begin;
using std::end;
using std::find_if;
using std::map;
using std::optional;
using std::remove_if;

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

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

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

auto OpponentKnowledge(const Unit &unit, PlayerId toPlayer) -> int;
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;

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);

auto ReserveUnitsForPlayer(const Units *units, PlayerId pid) -> map<UnitId, const Unit *>;
auto PlacedUnitsForPlayer(const Units *units, PlayerId pid) -> map<UnitId, const Unit *>;

}  // namespace shardok

#endif /* Unit_hpp */
