#include "graphics_primitive.hpp"
#include "metadata.hpp"
#include "interpreter.hpp"
#include "playlist.hpp"
#include "ta_parameter.hpp"

namespace scene::tracker::metadata {

  void draw_labels(ta_parameter_writer& writer, float x, float y)
  {
    transfer_string(writer, "artist:",
                    x, y, 1.0 / 10.0,
                    0xa7a7a7);
    transfer_string(writer, "artist:",
                    x+1, y+1, 1.0 / 11.0,
                    0x000000);

    y += glyph::vert_advance + 8;

    transfer_string(writer, " title:",
                    x, y, 1.0 / 10.0,
                    0xa7a7a7);
    transfer_string(writer, " title:",
                    x+1, y+1, 1.0 / 11.0,
                    0x000000);
  }

  void draw_values(ta_parameter_writer& writer, float x, float y)
  {
    using namespace interpreter;

    const char * artist = playlist::playlist[playlist::state.playlist_ix].artist;

    transfer_string(writer, artist,
                    x, y, 1.0 / 10.0,
                    0xffffff);

    y += glyph::vert_advance + 8;

    const char * title = (const char *)state.xm.header->module_name;

    transfer_string(writer, title,
                    x, y, 1.0 / 10.0,
                    0xffffff);
  }

  const float border_width = 20 * glyph::hori_advance + 2 * 2;
  const float border_height = 1 * glyph::vert_advance + 2 * 2;

  const float outer_top_depth = 1.0 / 20;
  const int outer_top_color = 0x101414;

  const float inner_top_depth = 1.0 / 18;
  const int inner_top_color = 0x1d2326;

  const float inner_middle_depth = 1.0 / 16;
  const int inner_middle_color = 0x161b1d;

  const float inner_bottom_depth = 1.0 / 19;
  const int inner_bottom_color = 0x060808;

  const float outer_bottom_depth = 1.0 / 21;
  const float outer_bottom_color = 0x2a3536;

  void draw_value_border_outer_top(ta_parameter_writer& writer, float x, float y)
  {
    float x0 = x;
    float x1 = x + border_width - 1;
    float y0 = y;
    float y1 = y + border_height - 1;

    quad_type_0(writer,
                {x0, y0, outer_top_depth},
                {x1, y0, outer_top_depth},
                {x1, y1, outer_top_depth},
                {x0, y1, outer_top_depth},
                outer_top_color);
  }

  void draw_value_border_inner_top(ta_parameter_writer& writer, float x, float y)
  {
    float x0 = x + 1;
    float x1 = x + border_width - 2;
    float y0 = y + 1;
    float y1 = y + border_height - 2;

    quad_type_0(writer,
                {x0, y0, inner_top_depth},
                {x1, y0, inner_top_depth},
                {x1, y1, inner_top_depth},
                {x0, y1, inner_top_depth},
                inner_top_color);
  }

  void draw_value_border_inner_bottom(ta_parameter_writer& writer, float x, float y)
  {
    float x0 = x + 1;
    float x1 = x + border_width - 1;
    float y0 = y + 1;
    float y1 = y + border_height - 1;

    quad_type_0(writer,
                {x0, y0, inner_bottom_depth},
                {x1, y0, inner_bottom_depth},
                {x1, y1, inner_bottom_depth},
                {x0, y1, inner_bottom_depth},
                inner_bottom_color);
  }

  void draw_value_border_inner_middle(ta_parameter_writer& writer, float x, float y)
  {
    float x0 = x + 2;
    float x1 = x + border_width - 2;
    float y0 = y + 2;
    float y1 = y + border_height - 2;

    quad_type_0(writer,
                {x0, y0, inner_middle_depth},
                {x1, y0, inner_middle_depth},
                {x1, y1, inner_middle_depth},
                {x0, y1, inner_middle_depth},
                inner_middle_color);
  }

  void draw_value_border_outer_bottom(ta_parameter_writer& writer, float x, float y)
  {
    float x0 = x;
    float x1 = x + border_width;
    float y0 = y;
    float y1 = y + border_height;

    quad_type_0(writer,
                {x0, y0, outer_bottom_depth},
                {x1, y0, outer_bottom_depth},
                {x1, y1, outer_bottom_depth},
                {x0, y1, outer_bottom_depth},
                outer_bottom_color);
  }

  void draw_border(ta_parameter_writer& writer, float x, float y)
  {
    draw_value_border_outer_top(writer, x, y);
    draw_value_border_inner_top(writer, x, y);
    draw_value_border_inner_bottom(writer, x, y);
    draw_value_border_inner_middle(writer, x, y);
    draw_value_border_outer_bottom(writer, x, y);
  }

  void draw(ta_multiwriter& multi, float x, float y)
  {
    transfer_global_polygon_glyph(multi.pt);

    draw_labels(multi.pt, x + 5, y + 3);

    float x_values = x + 5 + glyph::hori_advance * 8;
    draw_values(multi.pt, x_values + 3, y + 3);

    global_polygon_untextured(multi.op,
                              para_control::list_type::translucent,
                              tsp_instruction_word::dst_alpha_instr::zero);

    draw_border(multi.op, x_values, y);
    draw_border(multi.op, x_values, y + glyph::vert_advance + 8);
  }
}
