#ifndef __GAME_H__
#define __GAME_H__
#include <memory>
#include <vector>
#include "output.h"
#include "input.h"
#include "rng.h"
#include "characters.h"
#include "level.h"
#include "player.h"
#include "result.h"

enum game_status : int;

class game final {
private:
        static const size_t MAX_LEVEL_CNT = 50;
        static const size_t MIN_LEVEL_CNT = 30;
        static const size_t DEFAULT_MAX_LEVEL = 5;
        static const size_t MAX_MSG_LENGTH = 300;
        inline static const float SHADE_SCORE_MUL = 1.5f;

        const feature enabled_features;
        const std::vector<level_data> &lvls;

        input   *in;
        output *out;
        RNG     *rng;

        unsigned int curr_turn;

        std::unique_ptr<player_base> player;
        std::vector<std::unique_ptr<level>> levels;

        size_t max_level;
        size_t curr_level;

        bool the_world;
        bool star_platinum;
        bool hostile_merchants;

        // shrink if over 300
        std::string msg;
public:
        game(const enum race starting_race,
             const feature enabled_features,
             input   *new_in,
             output *new_out,
             RNG     *new_rng,
             const std::vector<level_data> &lvls);
        game_result run();
        size_t get_curr_level() const;
        size_t get_curr_turn() const;
        const character *get_player() const;
        void print();
private:
        void new_level();
        character *move_enemies();
        enemy_list sort_enemies(const enemy_list &elist);
        std::string str_score() const;
};

#endif
