//
// Created by dancrosby on 3/22/20.
//

#ifndef EAGLE0_SHARDOK_LIBRARY_ACTION_COST_HPP
#define EAGLE0_SHARDOK_LIBRARY_ACTION_COST_HPP

#include <cstdint>

#include "ShardokCTypes.h"

namespace shardok {
struct ActionCost {
    enum class ActionCostType : uint8_t {
        impossible,  // This action cannot be performed at any price.
        standard,    // This is a normal action, that requires and consumes the specified number of
                     // points.
        usesAll      // This action requires the minimum points, but consumes anything that is left.
    };

    static constexpr ActionCostType impossible = ActionCostType::impossible;
    static constexpr ActionCostType standard = ActionCostType::standard;
    static constexpr ActionCostType usesAll = ActionCostType::usesAll;

    ActionCostType type;
    ActionPoints points;

    constexpr ActionCost(const ActionCostType type, const ActionPoints points) noexcept
        : type(type),
          points(points) {}

    [[nodiscard]] constexpr auto IsPossible(const ActionPoints cmpPoints) const noexcept -> bool {
        return type != impossible && cmpPoints >= points;
    }

    [[nodiscard]] constexpr auto operator==(const ActionCost &rhs) const noexcept -> bool {
        return type == rhs.type && points == rhs.points;
    }

    [[nodiscard]] static constexpr auto StandardActionCost(const ActionPoints points) noexcept
            -> ActionCost {
        return ActionCost{ActionCost::standard, points};
    }

    [[nodiscard]] static constexpr auto UsesAllActionCost(const ActionPoints points) noexcept
            -> ActionCost {
        return {ActionCost::usesAll, points};
    }
};

inline constexpr ActionCost IMPOSSIBLE_ACTION_COST{ActionCost::impossible, 0};

}  // namespace shardok

#endif  // EAGLE0_SHARDOK_LIBRARY_ACTION_COST_HPP
