#include "scene/GameMapTestScene.h"
#include <SDL2/SDL.h>
#include <frostbite2D/scene/scene_manager.h>
#include <frostbite2D/utils/startup_trace.h>

namespace frostbite2D {

namespace {

constexpr char kTestMapPath[] = "map/elvengard/d_elvengard.map";

} // namespace

GameMapTestScene::GameMapTestScene() = default;

void GameMapTestScene::onEnter() {
  ScopedStartupTrace startupTrace("GameMapTestScene::onEnter");
  Scene::onEnter();

  if (!debugScene_) {
    debugScene_ = MakePtr<GameDebugUIScene>();
  }
  SceneManager::get().RemoveUIScene(debugScene_.Get());
  SceneManager::get().PushUIScene(debugScene_);

  if (initialized_) {
    debugScene_->SetDebugContext(map_.Get(), character_.Get());
    return;
  }

  {
    ScopedStartupTrace stageTrace("GameMapTestScene map load");
    map_ = MakePtr<GameMap>();
    if (!map_->LoadMap(kTestMapPath)) {
      SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                   "GameMapTestScene: failed to load map %s", kTestMapPath);
      map_.Reset();
      debugScene_->ClearDebugContext();
      return;
    }
  }
  AddChild(map_);

  {
    ScopedStartupTrace stageTrace("GameMapTestScene character construction");
      character_ = MakePtr<CharacterObject>();
      if (!character_->Construction(0)) {
        SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
                  "GameMapTestScene: failed to construct default character");
      character_.Reset();
    } else {
      Vec2 spawnPos =
          map_->ClampCameraFocus(map_->GetDefaultCameraFocus(), 1.0f);
      character_->SetCharacterPosition(spawnPos);
      character_->EnableEventReceive();
      character_->SetEventPriority(-100);
      map_->AddObject(character_);
    }
  }

  cameraController_.SetMap(map_.Get());
  cameraController_.SetTarget(character_.Get());
  cameraController_.SetDebugEnabled(false);
  if (character_) {
    cameraController_.SetFocus(character_->GetPosition());
  } else {
    cameraController_.ClearTarget();
    cameraController_.SnapToDefaultFocus();
  }
  {
    ScopedStartupTrace stageTrace("GameMap::Enter");
    map_->Enter();
  }
  debugScene_->SetDebugContext(map_.Get(), character_.Get());
  initialized_ = true;
}

void GameMapTestScene::onExit() {
  if (debugScene_) {
    debugScene_->ClearDebugContext();
    SceneManager::get().RemoveUIScene(debugScene_.Get());
  }

  Scene::onExit();
}

void GameMapTestScene::Update(float deltaTime) {
  Scene::Update(deltaTime);
  cameraController_.Update(deltaTime);
}

} // namespace frostbite2D
