#include <string>
#include <cstring>
#include <memory>
#include <cstdlib>

#include "tilemap-test.hpp"
#include "assets.hpp"

using namespace blit;

TileMap* environment;

/* setup */
void init() {
  blit::set_screen_mode(ScreenMode::lores);

  screen.sprites = Surface::load(asset_platformer);
  environment = new TileMap((uint8_t*)asset_tilemap, nullptr, Size(64, 64), screen.sprites);
}


float deg2rad(float a) {
  return a * (pi / 180.0f);
}

uint32_t current_time;


static Mat3 dream(uint8_t y) {
  float progress = (sinf(current_time / 2000.0f) + 1.0f) * 0.6f;  // two second animation
  progress = progress > 1.0f ? 1.0f : progress;

  screen.alpha = progress * 255.0f;
  float step = (current_time / 200.0f) + (y / 10.0f);
  float x_offset = (sinf(step) * (cosf(step) * 50.0f)) * (1.0f - progress);

  Mat3 transform = Mat3::translation(
    Vec2(256, 156) +    // offset to middle of world
    Vec2(x_offset, 0) + // apply dream effect wave
    Vec2(-80, -60)      // transform to centre of framebuffer
  );

  return transform;
};

static Mat3 rotozoom(uint8_t y) {
  float progress = (sinf(current_time / 2000.0f) + 1.0f) / 2.0f;  // two second animation

  float angle = (1.0f - progress) * 360.0f;
  float scale = progress;

  Mat3 transform = Mat3::identity();
  transform *= Mat3::translation(Vec2(256, 156)); // offset to middle of world
  transform *= Mat3::rotation(deg2rad(angle)); // apply rotation
  transform *= Mat3::scale(Vec2(scale, scale)); // apply scaling
  transform *= Mat3::translation(Vec2(-80, -60)); // transform to centre of framebuffer

  return transform;
};

static Mat3 zoom(uint8_t y) {
  float progress = (sinf(current_time / 1000.0f) + 1.0f) / 2.0f;  // two second animation

  float scale = progress;

  Mat3 transform = Mat3::identity();
  transform *= Mat3::translation(Vec2(256, 156)); // offset to middle of world
  transform *= Mat3::scale(Vec2(scale, scale)); // apply zoom effect using scaling
  transform *= Mat3::translation(Vec2(-80, -60)); // transform to centre of framebuffer

  return transform;
};


static Mat3 perspective(uint8_t y) {
  float progress = (sinf(current_time / 2000.0f) + 1.0f) / 2.0f;  // two second animation
  progress = progress > 1.0f ? 1.0f : progress;

  screen.alpha = y + (255 - 120);
  float scale = (y + 1) / 30.0f;

  Mat3 transform = Mat3::identity();
  transform *= Mat3::translation(Vec2(156, 130 + progress * 80.0f)); // offset to middle of world
  transform *= Mat3::scale(Vec2(1.0f / scale, 1.0f / scale)); // apply scaling- increases with y to give a depth effect
  transform *= Mat3::translation(Vec2(-80, -60)); // transform to centre of framebuffer

  return transform;
};


static Mat3 water(uint8_t y) {
  float step = (current_time / 200.0f) + (y / 10.0f);
  float x_offset = (sinf(step) + sinf(step / 3.0f) + sinf(step * 2.0f)) * 2.0f;

  Mat3 transform = Mat3::translation(
    Vec2(156, 130) +    // offset to middle of world
    Vec2(x_offset, 0) + // apply a water ripple effect
    Vec2(-80, -60)      // transform to centre of framebuffer
  );

  return transform;
};

static Mat3 warp(uint8_t y) {
  float step = (current_time / 1000.0f) + (y / 100.0f);
  float x_offset = (sinf(step) * (cosf(step) * 50.0f));

  float angle = sinf(current_time / 500.0f) * 50.0f;

  Mat3 transform = Mat3::identity();
  transform *= Mat3::translation(Vec2(140, 140)); // offset to middle of world
  transform *= Mat3::translation(Vec2(x_offset, 0)); // apply dream effect wave
  transform *= Mat3::rotation(deg2rad(angle)); // apply dream effect wave
  transform *= Mat3::translation(Vec2(-80, -60)); // transform to centre of framebuffer

  return transform;
};

static Mat3 ripple(uint8_t y) {
  float step = (current_time / 250.0f) + (y / 25.0f);

  float scale = (sinf(step) / 4.0f) + 1.0f;

  Mat3 transform = Mat3::identity();
  transform *= Mat3::translation(Vec2(256, 156)); // offset to middle of world
  transform *= Mat3::scale(Vec2(scale, scale)); // apply dream effect wave
  transform *= Mat3::translation(Vec2(-80, -60)); // transform to centre of framebuffer

  return transform;
};

static Mat3 betamax(uint8_t y) {
  float step = (current_time / 250.0f) + (y / 25.0f);
  Point shake(0, 0);

  int8_t scale = int8_t((sinf(step) + 1.0f) * 5);
  if (scale > 0) {
    shake = Point((blit::random() % scale) - scale / 2, (blit::random() % scale) - scale / 2);
  }

  Mat3 transform = Mat3::translation(
    Vec2(256, 156) + // offset to middle of world
    Vec2(shake) +    // apply shake
    Vec2(-80, -60)   // transform to centre of framebuffer
  );

  return transform;
};

static Mat3 shake(uint8_t y) {
  static uint32_t last_time = 0;
  static Point shake(0, 0);

  if (current_time != last_time) {
    last_time = current_time;

    uint8_t clamp = 20;
    shake = Point(blit::random() % clamp, blit::random() % clamp);
    float scale = sinf(current_time / 300.0f);

    scale = scale < 0.0f ? 0.0f : scale;
    shake *= scale;
  }

  Mat3 transform = Mat3::translation(
    Vec2(256, 156) + // offset to middle of world
    Vec2(shake) +    // apply shake
    Vec2(-80, -60)   // transform to centre of framebuffer
  );

  return transform;
};

const std::function<Mat3(uint8_t)> effect_callbacks[]{
  zoom,
  dream,
  ripple,
  rotozoom,
  warp,
  perspective,
  water,
  betamax,
  shake
};

const std::array<std::string, 9> effect_names{
  "zoom",
  "dream",
  "ripple",
  "rotozoom",
  "warp",
  "perspective",
  "water",
  "betamax",
  "shake"
};

uint8_t effect = 0;

void render(uint32_t time_ms) {
  current_time = time_ms;

  screen.alpha = 255;
  screen.pen = Pen(39, 39, 54);
  screen.clear();

  screen.alpha = 255;
  screen.mask = nullptr;

  uint32_t ms_start = now();

  environment->draw(&screen, Rect(0, 0, 160, 120), effect_callbacks[effect]);


  screen.alpha = 255;
  for (auto i = 0u; i < effect_names.size(); i++) {
    if (effect == i)
      screen.pen = Pen(255, 255, 255);
    else
      screen.pen = Pen(255, 255, 255, 100);

    screen.text(effect_names[i], minimal_font, Rect(5, 19 + (i * 10), 100, 10));
  }

  uint32_t ms_end = now();

  /*
  // draw FPS meter
  screen.alpha = 255;
  screen.pen = Pen(0, 0, 0);
  screen.rectangle(Rect(1, 120 - 10, 12, 9));
  screen.pen = Pen(255, 255, 255, 200);
  std::string fms = std::to_string(ms_end - ms_start);
  screen.text(fms, minimal_font, Rect(3, 120 - 9, 10, 16));

  int block_size = 4;
  for (int i = 0; i < (ms_end - ms_start); i++) {
    screen.pen = Pen(i * 5, 255 - (i * 5), 0);
    screen.rectangle(Rect(i * (block_size + 1) + 1 + 13, screen.bounds.h - block_size - 1, block_size, block_size));
  }
  */

  screen.pen = Pen(255, 255, 255);
  screen.rectangle(Rect(0, 0, 320, 14));

  screen.pen = Pen(0, 0, 0);
  screen.text("Tilemap demo", minimal_font, Point(5, 4));
  screen.watermark();
}

void update(uint32_t time) {
  auto last_effect = uint8_t(effect_names.size() - 1);

  if (buttons.pressed & Button::DPAD_DOWN) {
    effect = effect == last_effect ? 0 : effect + 1;
  }
  if (buttons.pressed & Button::DPAD_UP) {
    effect = effect == 0 ? last_effect : effect - 1;
  }
}
