#include "texture.hpp"
#include <SFML/Graphics/Image.hpp>
#include "dbc.hpp"
#include <fmt/core.h>
#include "config.hpp"
#include "constants.hpp"

using std::shared_ptr, std::make_shared;

sf::Image TexturePack::load_image(std::string filename) {
  sf::Image texture;
  bool good = texture.loadFromFile(filename);
  dbc::check(good, fmt::format("failed to load {}", filename));
  return texture;
}

void TexturePack::load_sprites() {
  Config assets("assets/config.json");

  for(auto& el : assets["sprites"].items()) {
    string path = el.value();
    auto texture = make_shared<sf::Texture>(path);

    texture->setSmooth(false);
    auto sprite = make_shared<sf::Sprite>(*texture);

    string name = el.key();
    sprite_textures[name] = {sprite, texture};
  }

  sword = sprite_textures["sword"];

  floor = load_image(assets["sprites"]["floor"]);
  ceiling = load_image(assets["sprites"]["ceiling"]);
}

void TexturePack::load_tiles() {
  Config assets("assets/tiles.json");
  auto &tiles = assets.json();

  for(auto &el : tiles.items()) {
    auto &config = el.value();
    surfaces.emplace_back(load_image(config["texture"]));

    std::wstring display = assets.wstring(el.key(), "display");
    int surface_i = surfaces.size() - 1;
    wchar_t tid = display[0];

    char_to_texture[tid] = surface_i;
  }
}

const uint32_t* TexturePack::get_surface(size_t num) {
  return (const uint32_t *)surfaces[num].getPixelsPtr();
}

matrix::Matrix TexturePack::convert_char_to_texture(matrix::Matrix &tile_ids) {
  auto result = matrix::make(matrix::width(tile_ids), matrix::height(tile_ids));

  for(matrix::each_cell it(tile_ids); it.next();) {
    wchar_t tid = tile_ids[it.y][it.x];
    result[it.y][it.x] = char_to_texture.at(tid);
  }

  return result;
}
