#include "gui/scene_ui.hpp"
#include "game/config.hpp"
#include "events.hpp"
#include "gui/guecstra.hpp"
#include <iostream>

#define DEBUG 0

namespace gui {
  void SceneUI::init() {
    $view_sprite.setPosition({0,0});
    $scene.init();
    create_buttons($scene.buttons());
  }

  void SceneUI::create_buttons(nlohmann::json& buttons) {
    // buttons are optional
    if(buttons.size() == 0) return;

    // alright have buttons
    has_buttons = true;

    std::string layout{};
    auto& actions = buttons["actions"];

    for(auto& line : buttons["layout"]) {
      layout.append(line);
    }

    auto& button_cell = $scene.button_cell();

    $ui.position(button_cell.x, button_cell.y, button_cell.w, button_cell.h);
    $ui.layout(layout);

    for(auto& [name, cell] : $ui.cells()) {
      auto ui_id = $ui.entity(name);
      $ui.set<guecs::Text>(ui_id, {guecs::to_wstring(name)});
      $ui.set<guecs::Rectangle>(ui_id, {});
      $ui.set<guecs::Effect>(ui_id, {});

      if(actions.contains(name)) {
        auto event_id = actions[name];
        $ui.set<guecs::Clickable>(ui_id, guecs::make_action(ui_id, event_id));
      }
    }

    $ui.init();
  }

  void SceneUI::render(sf::RenderTarget &target) {
    $scene.render($view_texture);
    target.draw($view_sprite);

    if(has_buttons) {
      $ui.render(target);
      if(DEBUG) $ui.debug_layout(target);
    }
  }

  void SceneUI::update() {
    $scene.update();
  }

  bool SceneUI::mouse(float x, float y, guecs::Modifiers mods) {
    $scene.mouse(x, y, mods);
    $ui.mouse(x, y, mods);
    return false;
  }

  AnimatedScene SceneUI::load_scene(const std::string& name) {
    auto scene_config = settings::get("scenes")[name];
    return components::convert<AnimatedScene>(scene_config);
  }
}
