#include "map_view.hpp"
#include <functional>
#include <string>
#include "dbc.hpp"
#include "components.hpp"
#include "rand.hpp"
#include "animation.hpp"
#include "systems.hpp"
#include "rand.hpp"
#include <codecvt>
#include <iostream>
#include <fmt/xchar.h>
#include <fstream>
#include "palette.hpp"

constexpr const int MAP_WIDTH=13;
constexpr const int MAP_HEIGHT=13;

namespace gui {
  using namespace components;
  using namespace guecs;

  MapViewUI::MapViewUI(GameLevel &level) :
    $level(level),
    $map_render(std::make_shared<sf::RenderTexture>()),
    $map_sprite($map_render->getTexture()),
    $map_tiles(matrix::make(MAP_WIDTH, MAP_HEIGHT))
  {
    auto player = $level.world->get_the<Player>();
    $player_display = $level.world->get<Tile>(player.entity).display;
  }

  void MapViewUI::update_level(GameLevel &level) {
    $level = level;
  }

  void MapViewUI::init() {
    $gui.position(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
    $gui.layout("[log_view| *%(200)map_grid | _ ]");
    $gui.set<Background>($gui.MAIN, {$gui.$parser, palette::get("tiles/fg:wall_plain")});

    $log_to = $gui.entity("log_view");
    $gui.set<Rectangle>($log_to, {10, THEME.DARK_MID, THEME.BORDER_COLOR, 10});
    $gui.set<Text>($log_to, {L"Welcome to the Game!", 25, THEME.TEXT_COLOR, 10});

    auto map_cell = lel::center(MAP_TILE_DIM * MAP_WIDTH, MAP_TILE_DIM * MAP_HEIGHT, $gui.cell_for("map_grid"));
    $map_sprite.setPosition({(float)map_cell.x, (float)map_cell.y + 30});

    $gui.init();
  }

  void MapViewUI::render(sf::RenderWindow &window, int compass_dir) {
    $gui.render(window);
    System::draw_map($level, $map_tiles, $entity_map);
    System::render_map($map_tiles, $entity_map, *$map_render, compass_dir, $player_display);
    $map_sprite.setTexture($map_render->getTexture(), true);
    window.draw($map_sprite);
    // $gui.debug_layout(window);
  }

  void MapViewUI::update() {
    if(auto text = $gui.get_if<Text>($log_to)) {
      //BUG: I'm calling this what it is, fix it
      wstring log_garbage;
      for(auto msg : $messages) {
        log_garbage += msg + L"\n";
      }
      text->update(log_garbage);
    }
  }

  void MapViewUI::log(wstring msg) {
    $messages.push_front(msg);
    if($messages.size() > MAX_LOG_MESSAGES) {
      $messages.pop_back();
    }
    update();
  }
}
