#include "holly/background.hpp"
#include "holly/holly.hpp"

#include "scene/emulator/scene.hpp"

#include "holly/ta_bits.hpp"
#include "holly/isp_tsp.hpp"
#include "ta_parameter.hpp"

#include "framebuffer.hpp"
#include "font.hpp"
#include "scene/emulator/sound.hpp"

namespace scene::emulator {
  const struct scene::scene scene = {
    .ta_alloc = ta_alloc_ctrl::pt_opb::_32x4byte
              | ta_alloc_ctrl::tm_opb::no_list
              | ta_alloc_ctrl::t_opb::no_list
              | ta_alloc_ctrl::om_opb::no_list
              | ta_alloc_ctrl::o_opb::_32x4byte,
    .opb_size = {
      .opaque = 32 * 4,
      .opaque_modifier = 0,
      .translucent = 0,
      .translucent_modifier = 0,
      .punch_through = 32 * 4
    },
    .transfer = transfer,
    .interrupt = sound::interrupt,
    .init = init,
    .done = done
  };

  static float intensity = 0.0;

  void draw_title(ta_parameter_writer& writer, int color)
  {
    const font::font& face = font::fonts[font::font::ter_u32n];
    draw_glyph_global(writer, face);

    int h_center = framebuffer.px_width / 2 - (30 * face.width) / 2;
    draw_string(writer, face, "Counterfeit Dreamcast Detected", h_center, 35, 0.1, color << 16);
  }

  void draw_paragraph(ta_parameter_writer& writer, int color)
  {
    const char * paragraph[] = {
      "Your counterfeit Dreamcast failed a CORE",
      "rasterization test.",
      "",
      "Dreamcast emulator behavior is highly divergent",
      "from a genuine Sega Dreamcast. Some emulator",
      "authors deliberately choose to forgo accuracy,",
      "and instead are developing a distinct and",
      "unrelated fantasy-platform.",
      "",
      "This program only supports genuine Sega",
      "Dreamcasts. Other fantasy-platforms and emulators",
      "are not supported."
    };
    const int paragraph_length = (sizeof (paragraph)) / (sizeof (paragraph[0]));

    const font::font& face = font::fonts[font::font::ter_u24n];
    draw_glyph_global(writer, face);

    float x = 26;
    float y = 80;

    int base_color = (color << 16) | (color << 8) | (color << 0);

    for (int i = 0; i < paragraph_length; i++) {
      const char * s = paragraph[i];
      draw_string(writer, face, s, x, y, 0.1, base_color);
      y += face.height;
    }
  }

  void transfer(ta_multiwriter& multi)
  {
    using namespace font;

    if (intensity < 1.0)
      intensity += 0.005;

    int color = (int)(255.0 * intensity);
    if (color > 255)
      color = 255;

    draw_title(multi.pt, color);
    draw_paragraph(multi.pt, color);

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

    quad_type_0(multi.op,
                {0, 0, 0.1},
                {0, 0, 0.1},
                {0, 0, 0.1},
                {0, 0, 0.1},
                0x0);
  }

  void init()
  {
    intensity = 0;

    background_parameter2(texture_memory_alloc.background[1].start,
                          0);
    holly.VO_BORDER_COL = 0;

    ::scene::emulator::sound::init();
  }

  int done()
  {
    return -1;
  }
}
