#include "guecs/sfml/components.hpp"
#include "guecs/ui.hpp"
#include <fmt/xchar.h>
#include <deque>
#include <iostream>
#include <nlohmann/json.hpp>
#include "dbc.hpp"
#include <memory>
#include <filesystem>
#include <fstream>
#include <iostream>
#include "constants.hpp"
#include "control.hpp"

ControlUI::ControlUI(sf::RenderWindow& presenter) :
    $presenter(presenter)
{

  $gui.position(0, 0, CONTROL_WIDTH, CONTROL_HEIGHT);
  $gui.layout(
      "[status|=%(100,100)current]"
      "[docs|=%(100,100)next]"
      );
}

void ControlUI::init() {
  auto status_id = $gui.entity("status");
  $gui.set<guecs::Text>(status_id, {L""});

  auto docs_id = $gui.entity("docs");
  $gui.set<guecs::Text>(docs_id, {L"A: win left\nD: win right\nQ: quit"});

  auto current = $gui.entity("current");
  $gui.set<guecs::Text>(current, {L"Current Slide"});

  auto next = $gui.entity("next");
  $gui.set<guecs::Text>(next, {L"Next Slide"});

  $gui.init();

  // warning! must come after init so the thing is there
  $status = $gui.get_if<guecs::Text>(status_id);
  dbc::check($status != nullptr, "failed to setup the status text");
}

void ControlUI::render(sf::RenderWindow& window) {
  dbc::check($status != nullptr, "called render before init?");

  auto pos = $presenter.getPosition();
  auto size = $presenter.getSize();

  $status->update(fmt::format(L"pos={},{}\nsize={},{}",
        pos.x, pos.y, size.x, size.y));
  window.clear();

  $gui.render(window);
}

void ControlUI::handle_events(sf::RenderWindow& controller, const sf::Event& event) {
  dbc::check($status != nullptr, "handle_events called before init?!");

  if(event.is<sf::Event::Closed>()) {
    controller.close();
    return;
  }

  if(const auto* key = event.getIf<sf::Event::KeyPressed>()) {
    auto pos = $presenter.getPosition();
    auto size = $presenter.getSize();

    using KEY = sf::Keyboard::Scan;
    switch(key->scancode) {
      case KEY::A: {
          pos.x -= size.x;
          $presenter.setPosition(pos);
        } break;
      case KEY::D: {
        pos.x += int(size.x);
        $presenter.setPosition(pos);
       } break;
      case KEY::Q:
        controller.close();
        break;
      default:
        break;
    }

    fmt::println("window pos: {},{}", pos.x, pos.y);
  }
}
