#include "guecs/sfml/textures.hpp"
#include "guecs/sfml/config.hpp"
#include <SFML/Graphics/Image.hpp>
#include <fmt/core.h>
#include <memory>

namespace textures {
  using std::shared_ptr, std::make_shared;

  static TextureManager TMGR;
  static bool initialized = false;

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

    for(auto& [name, settings] : assets["sprites"].items()) {
      auto texture = make_shared<sf::Texture>(settings["path"]);

      texture->setSmooth(assets["graphics"]["smooth_textures"]);
      auto sprite = make_shared<sf::Sprite>(*texture);

      int width = settings["frame_width"];
      int height = settings["frame_height"];
      sprite->setTextureRect({{0,0}, {width, height}});

      TMGR.sprite_textures.try_emplace(name, sprite, texture);
    }
  }

  void init() {
    if(!initialized) {
      load_sprites();
      initialized = true;
    }
  }

  SpriteTexture get(const std::string& name) {
    assert(initialized && "you forgot to call textures::init()");
    assert(TMGR.sprite_textures.contains(name) &&
        "!!!!! texture pack does not contain sprite");

    auto result = TMGR.sprite_textures.at(name);

    assert(result.sprite != nullptr &&
        "bad sprite from textures::get named can't be null");
    assert(result.texture != nullptr &&
        "bad texture from textures::get named can't be null");

    return result;
  }

  sf::Image load_image(const std::string& filename) {
    sf::Image texture;
    bool good = texture.loadFromFile(filename);
    assert(good && "failed to load image file");
    return texture;
  }
};
