#include "backend.hpp"
#include "shaders.hpp"
#include "sound.hpp"
#include "textures.hpp"
#include "config.hpp"

namespace sfml {
  using namespace nlohmann;

  guecs::SpriteTexture Backend::texture_get(const string& name) {
    auto sp = textures::get(name);
    return {sp.sprite, sp.texture};
  }

  Backend::Backend() {
    sound::init();
    shaders::init();
    textures::init();
  }

  void Backend::sound_play(const string& name) {
    sound::play(name);
  }

  void Backend::sound_stop(const string& name) {
    sound::stop(name);
  }

  std::shared_ptr<sf::Shader> Backend::shader_get(const std::string& name) {
    return shaders::get(name);
  }

  bool Backend::shader_updated() {
    if(shaders::updated($shaders_version)) {
      $shaders_version = shaders::version();
      return true;
    } else {
      return false;
    }
  }

  inline sf::Color to_color(json& config, const std::string& name) {
    json& val = config[name];
    if(val.type() == json::value_t::array) {
      return sf::Color{val[0], val[1], val[2], val[3]};
    } else if(val.type() == json::value_t::string) {
      json& array = config[val];
      return sf::Color{array[0], array[1], array[2], array[3]};
    } else {
      dbc::sentinel(fmt::format(
            "theme config {} has invalid color setting,"
            "either use an array of 4 ints or a string"
            "referencing another config with 4 ints.", name));
    }
  }

  guecs::Theme Backend::theme() {
    auto config = Config("assets/config.json")["theme"];

    guecs::Theme theme {
      .BLACK=to_color(config, "black"),
      .DARK_DARK=to_color(config, "dark_dark"),
      .DARK_MID=to_color(config, "dark_mid"),
      .DARK_LIGHT=to_color(config, "dark_light"),
      .MID=to_color(config, "mid"),
      .LIGHT_DARK=to_color(config, "light_dark"),
      .LIGHT_MID=to_color(config, "light_mid"),
      .LIGHT_LIGHT=to_color(config, "light_light"),
      .WHITE=to_color(config, "white"),
      .TRANSPARENT = sf::Color::Transparent
    };

    theme.PADDING = config["padding"];
    theme.BORDER_PX = config["border_px"];
    theme.TEXT_SIZE = config["text_size"];
    theme.LABEL_SIZE = config["label_size"];
    theme.FILL_COLOR = to_color(config, "fill_color");
    theme.TEXT_COLOR = to_color(config, "text_color");
    theme.BG_COLOR = to_color(config, "bg_color");
    theme.BORDER_COLOR = to_color(config, "border_color");
    theme.BG_COLOR_DARK = to_color(config, "bg_color_dark");
    theme.FONT_FILE_NAME = Config::path_to(config["font_file_name"]).string();

    return theme;
  }
}
