#include <daguerre/psf.hpp>
#include "renderer.hpp"
#include "window.hpp"
#include <cassert>

//TODO: make these statically intialized once that is implemented
bool have_initialized_decoration_stuff;
daguerre::fixed_font<bool> *title_font;
daguerre::hilbert_color border_color_top;
daguerre::hilbert_color border_color_not_top;
daguerre::hilbert_color title_color;

void window::set_size(int width, int height) {
  int center_x = x + contents_with_decorations. width / 2;
  int center_y = y + contents_with_decorations.height / 2;
  contents_with_decorations =
    daguerre::image<daguerre::hilbert_color>(width + 4, height + 18);
  contents = daguerre::image<daguerre::hilbert_color>(
    width, height,
    &contents_with_decorations.at(2, 16),
    contents_with_decorations.buffer_pitch, false);
  x = center_x - contents_with_decorations. width / 2;
  y = center_y - contents_with_decorations.height / 2;
}

void title_converter(
  daguerre::hilbert_color &out, const bool &in, const bool &top) {
  out = in ? title_color : top ? border_color_top : border_color_not_top;
}

void window::draw_decorations(bool top) {

  //TODO: handle error loading font.
  //see also comment on title_font declaration.
  if (!have_initialized_decoration_stuff) {
    title_font = new daguerre::fixed_font<bool>(
      *daguerre::try_load_psf("/assets/terminus/6x12.psf"));
    assert(title_font->glyph_height == 12);
    border_color_top     = euler::syscall::encode_color(0x00, 0x3f, 0xff);
    border_color_not_top = euler::syscall::encode_color(0x22, 0x22, 0x22);
    title_color          = euler::syscall::encode_color(0xff, 0xff, 0xff);
    have_initialized_decoration_stuff = true;
  }

  static_assert( decorations_extra_width ==  4);
  static_assert(decorations_extra_height == 18);
  static_assert(            title_height == 16);

  auto border_color = top ? border_color_top : border_color_not_top;

  contents_with_decorations.fill(border_color, 0, 0,
    contents_with_decorations.width, 16);
  contents_with_decorations.fill(
    border_color, 0, contents_with_decorations.height - 2,
    contents_with_decorations.width, 2);
  contents_with_decorations.fill(border_color, 0, 16,
    2, contents_with_decorations.height - 18);
  contents_with_decorations.fill(border_color,
    contents_with_decorations.width - 2, 16,
    2, contents_with_decorations.height - 18);

  //TODO: make UTF-8--safe
  unsigned max_title_length =
    contents_with_decorations.width / title_font->glyph_width;
  std::string *title_to_draw;
  std::string shortened_title;
  if (title.size() > max_title_length) {
    shortened_title.resize(max_title_length - 3);
    memcpy(shortened_title.data(), title.data(), max_title_length - 3);
    shortened_title[max_title_length - 3] = '.';
    shortened_title[max_title_length - 2] = '.';
    shortened_title[max_title_length - 1] = '.';
    title_to_draw = &shortened_title;
  }
  else
    title_to_draw = &title;

  contents_with_decorations.render_text(*title_font, top,
    contents_with_decorations.width / 2 -
      (title_to_draw->size() * title_font->glyph_width) / 2,
    2, title_to_draw->data(), title_converter);

}
