#pragma once
#include "scene.hpp"
//#include "level/level-sky.hpp"
//#include "level/level-dummy.hpp"
#include "level/level-dummy-2.hpp"
#include "UI/Radar.hpp"
//! сцена игрового процесса
class Scene_game: public Scene {
protected:
  void init() {
    free();
    #ifdef DEBUG
    debuger::init(Game::X, Game::Y);
    #endif
    camera = {Game::X/2.0f, Game::Y/2.0f};
    mask_light_config(); // не сдвигать вниз
    init_enity();
    multicore_init();
    p_plr = add_plr(PLR_DARK);
    p_level = new Level_dummy_2("bruh");
    //p_level = new Level_dummy(Game::current_dir + "level/dummy/config.ini");
    //p_level = new Level_sky(Game::current_dir + "TODO");
    check();
    // dbg_info_enity(); TODO DEL
  } // init
  //! грузит то, что можно грузить в многопотоке
  void multicore_init() {
    #pragma omp parallel sections
    {
      #pragma omp section
      { load_prt("particle/"); }
      #pragma omp section
      { load_blt("bullet/"); }
      #pragma omp section
      { load_plr("player/"); }
      #pragma omp section
      { load_ene("enemy/"); }
      #pragma omp section
      { warning.init(); }
    }
  } // multicore_init
  void check() {
    #define PTR_CHECK(PTR) \
    IFERROR( !PTR, "Scene_game::init(): "#PTR" is null");
    PTR_CHECK(p_level)
    PTR_CHECK(p_plr)
    PTR_CHECK(Game::font)
    #undef PTR_CHECK
  } // check
  void free() {
    zdelete(p_level);
    free_enity();
    free_mp_info();
    bank_anim.free();
  }
public:
  explicit Scene_game(Scene* pv = 0): Scene(pv) {
    a83::log("goto scene GAME");
    init();
  }
  ~Scene_game() {
    a83::log("exit from scene GAME");
    free();
  }
  void update(float dt) override {
    using namespace a83;
    Scene::update(dt);
    input();
    update_enity(dt);
    process_plr(dt);
    p_level->update(g_offset, dt);
    g_update(dt);
  }
  void draw() override {
    using namespace a83;
    if (UI::radar_enabled) {
      UI::radar.draw(Game::screen);
      return;
    }
    p_level->print_d(Game::screen); // нижний слой уровня
    draw_enity(Game::screen);
    p_level->print_u(Game::screen); // верхний слой уровня
    UI::draw_HUD(Game::screen);
    #ifdef DEBUG
    debuger::draw(Game::screen);
    #endif
  } // draw
private:
  nocopy(Scene_game);
  void input() {
    // открывается менюшка паузы
    if (Game::menu_press(KEY_ESCAPE))
      set_scene(scene_st::PAUSE);
    // вкл/выкл радара
    if (Game::menu_press(KEY_RADAR))
      UI::radar_enabled = !UI::radar_enabled;
    // изменить разрешение радара
    if (UI::radar_enabled && Game::menu_press(KEY_RADAR_MODE))
      UI::radar.next_dist_mode();
    #ifdef DEBUG
    if (Game::menu_press(KEY_RESET))
      init();
    if (Game::menu_press(KEY_DEBUG))
      set_scene(scene_st::DEBUGER);
    #endif
  } // input
  //! настройка маски подсветки
  void mask_light_config() {
    switch (Game::difficulty) {
      default:
      case Difficulty::EASY: mask_light_ratio = 1; break;
      case Difficulty::NORMAL: mask_light_ratio = 0.25f; break;
      case Difficulty::HARD: mask_light_ratio = 0.25f; break;
      case Difficulty::DIE: mask_light_ratio = 0; break;
    }
  } // mask_light_config
  //! обрабатывает торможение камеры при смерти и т.д
  void g_update(float dt) {
    if (p_plr->is_dead()) {
      // замедление при смерти
      constexpr float rst = 0.8f;
      g_offset.spd = std::max(g_offset.spd - g_offset.spd * rst * dt, 0.f);
      return;
    }
  } // g_update
  //! обрабатывает таймеры рестарта и т.д
void process_plr(float dt) {
  // проверка на смерть
  if (p_plr->is_dead()) {
    UI::radar_enabled = false; // в радар нельзя смотреть после смерти
    // 4 skip
    if (Game::menu_press(KEY_ENABLE) or restart_timer()) {
      set_scene(scene_st::GAME_OVER);
      p_plr->reset();
      return;
    }
    restart_timer.update(dt);
  } // if dead
  // проверка на неуязвимость
  if (plr_nokill) {
    if (nokill_timer()) {
      p_plr->flags &= ~EF_NO_KILL;
      plr_nokill = false;
    } else
      p_plr->flags |= EF_NO_KILL;
    nokill_timer.update(dt);
  }
  // включить мигание при бессмертии
  p_plr->blend_mode = (p_plr->flags & EF_NO_KILL) ? BM::blink : BM::past;
} // process_plr
}; // Scene_game