#include "shmup.hpp"
#include "assets.hpp"

using namespace blit;

#define SCENERY_BIG_SKULL Rect(11, 3, 4, 3)
#define SCENERY_TUSK Rect(10, 3, 1, 3)
#define SCENERY_BIG_TUSK Rect(10, 6, 2, 3)
#define SCENERY_BIG_BONE Rect(12, 6, 3, 2)
#define SCENERY_CLAWS Rect(6, 5, 3, 2)
#define SCENERY_BIG_ROCK Rect(3, 5, 3, 3)

#define SHOT_BIG_RED Rect(6, 0, 2, 1)
#define SHOT_LONG_RED Rect(6, 0, 4, 1)
#define SHOT_BIG_PINK Rect(10, 0, 2, 1)

// These lookup tables include an offset in pixels
// as the first two uint8_t values.
// We offset in pixels rather than tiles to avoid having to
// multiply the values up when the sprite is drawn.
// The following values are bitmasks describing a sprite with
// a maximum of 8 tiles width, and unlimited height.
// Each bit, from left to right, indicates a tile starting from
// the offset that should be included in this sprite.
// This is much more space efficient than storing a point(x, y)
// for each tile we want in a sprite.

// Weird ship with a hole in it
const std::vector<uint8_t> BG_SHIP_1 = { \
                    12 * 8, 5 * 8, \
                    4, \
                    0b00100000, \
                    0b01110000, \
                    0b11110000 };

// Background ship with all the shuttle bays and little winglets on the bottom
const std::vector<uint8_t> BG_SHIP_2{ \
                    9 * 8, 4 * 8, \
                    5, \
                    0b11111000, \
                    0b11111000, \
                    0b01110000 };

// Hog ship!
const std::vector<uint8_t> HOG_SHIP{ \
                    10 * 8, 0, \
                    6, \
                    0b11111100, \
                    0b11111100, \
                    0b11111100, \
                    0b11111100 };

/*
Map

  [] --> [] --> [] --> []
      \
       [] --> [] --> []

Player
  x, y
  vx, vy
  life
Enemy
  x, y
  hit
  life
Projectile
  x, y
  vx, vy
Background Scenery
  x, y

*/
bool hit = false;

Pen hit_palette[2][5] = {
  {},
  {}
};

Size boar_ship_size(32, 32);

Surface* ships;
Surface* background;

Tween tween_bob;
Tween tween_dusk_dawn;
Tween tween_parallax;

void draw_tilebased_sprite(Surface* ss, Point origin, const std::vector<uint8_t> ship, bool hflip = false) {
  // We can use uint8_t everywhere here, but this limits us
  // to a spritesheet of 256*256. That's fine!
  uint8_t o_x = ship[0];
  uint8_t o_y = ship[1];

  // We need to know the width of the ship within our bitmask
  // so we can horizontally flip if needed without it going wonky
  uint8_t w = ship[2];

  for (auto i = 0; i < (uint8_t)ship.size() - 3; i++) {
    uint8_t ship_mask = ship[i + 3]; // Bitmask for tiles in a horizontal row
    uint8_t offset_y = (i * 8);
    uint8_t src_y = o_y + offset_y;
    for (auto j = 0; j < w; j++) {
      uint8_t jj = j;
      if (hflip) {
        jj = w - 1 - jj;
      }
      if (ship_mask & (0b10000000 >> jj)) {
        uint8_t offset_x = (jj * 8);
        uint8_t src_x = o_x + offset_x;
        screen.blit(ss, Rect(src_x, src_y, 8, 8), Point(origin.x + (j * 8), origin.y + offset_y), hflip);
      }
    }
  }
}

void init() {
  set_screen_mode(ScreenMode::hires);

  ships = Surface::load(sprites_ships);
  background = Surface::load(sprites_background);
  tween_bob.init(tween_sine, 0.0f, 1.0f, 2500, -1);
  tween_bob.start();

  tween_dusk_dawn.init(tween_sine, 0.0f, 1.0f, 500, 1);
  tween_dusk_dawn.start();

  tween_parallax.init(tween_linear, 0.0f, 1.0f, 10000, -1);
  tween_parallax.start();
  screen.sprites = background;

  for (int x = 0; x < 5; x++) {
    Pen s_c = screen.sprites->palette[4 + x];
    Pen c = Pen(
      std::min(255, int(s_c.r * 1.8)),
      std::min(255, int(s_c.g * 1.8)),
      std::min(255, int(s_c.b * 1.8))
    );
    hit_palette[0][x] = s_c;
    hit_palette[1][x] = c;
  }

  for (int x = 0; x < 32; x++) {
    background->palette[x] = desert[x];
  }
}

void render(uint32_t time) {
  uint32_t ms_start = blit::now() - time;
  screen.pen = background->palette[21];
  screen.clear();
  screen.sprites = background;

  for (int x = 0; x < 40; x++) {
    screen.sprite(Rect(15, 3, 1, 5), Point(x * 8, 0), 0);
    screen.sprite(Rect(0, 1, 1, 8), Point(x * 8, screen.bounds.h - 64), 0);
  }

  Pen t = background->palette[29];
  background->palette[29] = background->palette[20];

  // Far mountains
  screen.sprite(Rect(1, 2, 15, 1), Point((tween_parallax.value * 60), screen.bounds.h - 80), Point(0, 0), 2.0f, 0);
  screen.sprite(Rect(5, 1, 2, 1), Point((tween_parallax.value * 60) + (8 * 4 * 2.0f), screen.bounds.h - 96), Point(0, 0), 2.0f, 0);
  screen.sprite(Rect(12, 1, 3, 1), Point((tween_parallax.value * 60) + (8 * 11 * 2.0f), screen.bounds.h - 96), Point(0, 0), 2.0f, 0);

  // Try and palette swap in a transparent colour and draw in some reflections?
  background->palette[29] = Pen(background->palette[19].r, background->palette[19].g, background->palette[19].b, 100);
  screen.sprite(Rect(1, 2, 15, 1), Point((tween_parallax.value * 60), screen.bounds.h - 64), Point(0, 0), 2.0f, 2);
  screen.sprite(Rect(5, 1, 2, 1), Point((tween_parallax.value * 60) + (8 * 4 * 2.0f), screen.bounds.h - 48), Point(0, 0), 2.0f, 2);
  screen.sprite(Rect(12, 1, 3, 1), Point((tween_parallax.value * 60) + (8 * 11 * 2.0f), screen.bounds.h - 48), Point(0, 0), 2.0f, 2);
  background->palette[29] = t;

  screen.sprite(Rect(2, 0, 2, 1), Point(0, screen.bounds.h - 72), 0);
  screen.sprite(Rect(1, 2, 3, 1), Point(60, screen.bounds.h - 72), 0);
  screen.sprite(Rect(2, 1, 2, 1), Point(120, screen.bounds.h - 72), 0);

  background->palette[29] = background->palette[18];
  screen.sprite(Rect(2, 0, 2, 1), Point(0, screen.bounds.h - 64), 2);
  screen.sprite(Rect(1, 2, 3, 1), Point(60, screen.bounds.h - 64), 2);
  screen.sprite(Rect(2, 1, 2, 1), Point(120, screen.bounds.h - 64), 2);

  background->palette[29] = t;

  screen.sprite(SCENERY_BIG_SKULL, Point(0, screen.bounds.h - 52), 0);
  screen.sprite(SCENERY_CLAWS, Point(30, screen.bounds.h - 48), 0);
  screen.sprite(SCENERY_BIG_TUSK, Point(70, screen.bounds.h - 32), 0);
  screen.sprite(SCENERY_BIG_BONE, Point(120, screen.bounds.h - 64), 0);
  screen.sprite(SCENERY_BIG_ROCK, Point(230, screen.bounds.h - 32), 0);

  screen.sprite(SHOT_BIG_RED, Point(30, 60), 0);

  // Draw a chessboard so we can count our sprite tiles
  for (int x = 0; x < 128 / 8; x++) {
    for (int y = 0; y < 128 / 8; y++) {
      if ((y + x) & 1) {
        screen.pen = Pen(0, 0, 0, 64);
      }
      else {
        screen.pen = Pen(255, 255, 255, 64);
      }
      screen.rectangle(Rect(x * 8, y * 8, 8, 8));
    }
  }

  // Draw the whole ship spritesheet
  screen.blit(ships, Rect(0, 0, 128, 128), Point(0, 0));

  draw_tilebased_sprite(ships, Point(170, 120 + 5.0f * tween_bob.value), BG_SHIP_1);
  draw_tilebased_sprite(ships, Point(120, 120 + 10.0f * tween_bob.value), BG_SHIP_2);
  draw_tilebased_sprite(ships, Point(200, 160 + 10.0f * tween_bob.value), HOG_SHIP);
  draw_tilebased_sprite(ships, Point(60, 160 + 10.0f * tween_bob.value), HOG_SHIP, true);

  screen.alpha = 200;
  for (auto x = 0; x < 10; x++) {
    for (auto y = 0; y < 10; y++) {
      draw_tilebased_sprite(ships, Point(x * 32, y * 24 + 5.0f * tween_bob.value), BG_SHIP_1, (x + y) & 1);
    }
  }
  screen.alpha = 255;

  uint32_t ms_end = blit::now() - time;

  screen.pen = Pen(255, 100, 100);
  screen.text(std::to_string(ms_end - ms_start), minimal_font, Point(5, 230));
}

void update(uint32_t time) {
  if (buttons & Button::A && tween_dusk_dawn.is_finished()) {
    tween_dusk_dawn.start();
  }

  for (int x = 0; x < 32; x++) {
    Pen original = Pen(
      sprites_background[x * 4 + 20],
      sprites_background[x * 4 + 21],
      sprites_background[x * 4 + 22],
      sprites_background[x * 4 + 23]
    );

    Pen d = desert[x];

    float s = 1.0f - tween_dusk_dawn.value;
    float c = tween_dusk_dawn.value;

    background->palette[x] = Pen(
      std::min(255, int((d.r * s) + (original.r * c))),
      std::min(255, int((d.g * s) + (original.g * c))),
      std::min(255, int((d.b * s) + (original.b * c))),
      original.a
    );
  }
}
