#pragma once
#include <vector>
#include <utility>
#include <string>
#include <algorithm>
#include <fmt/core.h>
#include "point.hpp"
#include "matrix.hpp"
#include "config.hpp"
#include "components.hpp"

typedef std::vector<components::Tile> TileRow;
typedef std::vector<TileRow> TileGrid;

class TileMap {
public:
  Config $config;
  size_t $width;
  size_t $height;
  matrix::Matrix $tile_ids;
  TileGrid $display;

  TileMap(size_t width, size_t height);

  // disable copying
  TileMap(TileMap &map) = delete;

  size_t width() { return $width; }
  size_t height() { return $height; }
  void load(matrix::Matrix &walls);
  const components::Tile &at(size_t x, size_t y);
  void set_tile(size_t x, size_t y, std::string tile_name);
  std::vector<std::string> tile_names(bool collision);

  void dump(int show_x=-1, int show_y=-1);
  bool INVARIANT();
};