//
//  PercentileRollOdds.cpp
//  eagle0_tests
//
//  Created by Dan Crosby on 3/25/18.
//  Copyright © 2018 none. All rights reserved.
//

#include "PercentileRollOdds.hpp"

#include <cmath>

#include "src/main/cpp/net/eagle0/common/RandomGenerator.hpp"

namespace shardok {
double BonusFromStat(const double stat) { return pow(((double)stat - 50.0), 3.0) / 5000.0; }

int16_t AverageBonusFromStats(const std::vector<double> &stats) {
    double totalBonus = 0.0;
    for (const double stat : stats) { totalBonus += BonusFromStat(stat); }

    return totalBonus / stats.size();
}

int16_t GetSuccessChance(const PercentileRollOdds &odds) {
    return int16_t(std::floor(
            100.0 * RandomGenerator::ChanceOpenEndedPercentileAtOrAbove(100 - GetTotalOdds(odds)) +
            0.5));
}

OtherFactor MakeOtherFactor(const int value, const std::string &id) {
    OtherFactor of;
    of.set_value(value);
    of.set_identifier(id);

    return of;
}

PercentileRollOdds MakeOdds(
        const int base,
        const int terr,
        const int weath,
        const int wind,
        const int statF,
        const std::vector<OtherFactor> &others) {
    PercentileRollOdds odds;

    odds.set_base_difficulty(base);
    odds.set_terrain_factor(terr);
    odds.set_weather_factor(weath);
    odds.set_wind_factor(wind);
    odds.set_stat_factor(statF);
    for (const auto &of : others) { *odds.add_other_factors() = of; }

    return odds;
}

PercentileRollOdds MakeOdds(
        const int base,
        const int terr,
        const int weath,
        const int wind,
        const std::vector<double> &stats,
        const std::vector<OtherFactor> &others) {
    return MakeOdds(base, terr, weath, wind, AverageBonusFromStats(stats), others);
}

int16_t GetTotalOdds(const PercentileRollOdds &odds) {
    int16_t diff = odds.base_difficulty() + odds.terrain_factor() + odds.weather_factor() +
                   odds.wind_factor() + odds.stat_factor();
    for (const OtherFactor &fac : odds.other_factors()) { diff += fac.value(); }

    return diff;
}

bool PercentileRollSucceeds(const PercentileRollOdds &odds, const double roll) {
    return roll < GetTotalOdds(odds);
}
}  // namespace shardok
