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

#include "particle.hpp"

using namespace blit;



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

struct test_particle {
  Vec2 pos;
  Vec2 vel;
  int age;
  bool generated = false;
};


struct smoke_particle : Particle {
  float age_boost;

  smoke_particle(Vec2 pos, Vec2 vel, float age_boost) : Particle(pos, vel), age_boost(age_boost) {};
};

Particle* generate_smoke() {
  return new smoke_particle(
    Vec2((rand() % 20) - 10, (rand() % 20) - 10),
    Vec2(((rand() % 40) - 20) / 2, (rand() % 20) - 60),
    (rand() % 3000) / 3000.0f
  );
}

ParticleGenerator smoke_generator(150, 4000, generate_smoke);

void render_smoke() {
  for (auto p : smoke_generator.particles) {
    smoke_particle *sp = static_cast<smoke_particle*>(p);
    float age = sp->age + sp->age_boost;
    int alpha = (255 - (age * 75.0f)) / 8.0f;
    int radius = (age * 150.0f) / 16.0f;
    screen.pen = Pen(255, 255, 255, alpha);
    screen.circle(p->pos + Point(50, 240), radius);
  }
}


void smoke_generate(test_particle &p) {
  p.pos = Vec2((rand() % 20) - 10, (rand() % 20) - 10);
  p.vel = Vec2(((rand() % 40) - 20) / 2, (rand() % 20) - 60);
  p.age = rand() % 200;
  p.generated = true;
};

void smoke(uint32_t time_ms) {
  static test_particle s[150];
  static int generate_index = 0;
  static uint32_t last_time_ms = time_ms;

  int elapsed_ms = time_ms - last_time_ms;
  float td = (elapsed_ms) / 1000.0f;

  smoke_generate(s[generate_index++]);
  if (generate_index >= 150)
    generate_index = 0;

  float w = sinf(time_ms / 1000.0f) * 0.05f;

  for (auto &p : s) {
    if (p.generated) {
      p.pos += p.vel * td;
      p.vel += Vec2(w, 0);
      p.age++;

      int alpha = (255 - (p.age / 2)) / 8.0f;
      int radius = (p.age) / 16.0f;
      screen.pen = Pen(255, 255, 255, alpha);
      screen.circle(p.pos + Point(50, 240), radius);
    }
  }

  
  last_time_ms = time_ms;
};


void spark_generate(test_particle &p) {
  p.pos = Vec2((rand() % 10) - 5, -100);
  p.vel = Vec2(((rand() % 40) - 20), (rand() % 80) - 70);
  p.age = 0;// rand() % 255;
  p.generated = true;
};

void spark(uint32_t time_ms) {
  static test_particle s[500];
  static int generate_index = 0;
  static uint32_t last_time_ms = time_ms;

  int elapsed_ms = time_ms - last_time_ms;
  float td = (elapsed_ms) / 1000.0f;

  spark_generate(s[generate_index++]);
  if (generate_index >= 500)
    generate_index = 0;

  float w = sinf(time_ms / 1000.0f) * 0.05f;

  Vec2 gravity = Vec2(0, 9.8f * 2) * td;

  for (auto &p : s) {
    if (p.generated) {
      p.vel += gravity;
      p.pos += p.vel * td;
      if (p.pos.y > 0)
        p.vel.y *= -0.7f;
      p.age++;

      int a = p.age / 2;
      int r = 255 - (p.age / 2);
      int g = 255 - (a * 2);
      g = g < 0 ? 0 : g;
      int b = 255 - (a * 4);
      b = b < 0 ? 0 : b;

      int bloom = (255 - a) / 64;
      screen.pen = Pen(r, g, b, 16);
      screen.circle(p.pos + Point(160, 240), bloom);
      screen.pen = Pen(r, g, b, 16);
      screen.circle(p.pos + Point(160, 240), bloom / 2);

      screen.pen = Pen(r, g, b);
      screen.pixel(p.pos + Point(160, 240));

    }
  }
  
  last_time_ms = time_ms;
};


void rain_generate(test_particle &p) {
  p.pos = Vec2((rand() % 80) - 40, (rand() % 10) - 250);
  p.vel = Vec2(0, 140);
  p.age = 0;// rand() % 255;
  p.generated = true;
};

Vec2 g = Vec2(0, 9.8 * 5);

void rain(uint32_t time_ms) {
  static test_particle s[200];
  static int generate_index = 0;
  static uint32_t last_time_ms = time_ms;

  int elapsed_ms = time_ms - last_time_ms;
  float td = (elapsed_ms) / 1000.0f;

  rain_generate(s[generate_index++]);
  if (generate_index >= 200)
    generate_index = 0;

  float w = sinf(time_ms / 1000.0f) * 0.05f;

  Vec2 gravity = g * td;

  for (auto &p : s) {
    if (p.generated) {
      p.vel += gravity;
      p.pos += p.vel * td;
      
      int floor = -3;
      if (p.pos.x > 20 && p.pos.x < 46)
        floor = -33;

      if (p.pos.y >= floor) {
        p.pos.y = floor;
        float bounce = ((rand() % 10)) / 80.0f;
        p.vel.y *= -bounce;
        p.vel.x = ((rand() % 30) - 15);
      }
      p.age++;

      int a = p.age / 2;
      int r = 150 - (a / 2);
      int g = 150 - (a / 2);
      int b = 255;// -(a * 4);

      if(p.vel.length() > 20) {
        screen.pen = Pen(r, g, b, 100);
        screen.pixel(p.pos + Point(270, 239));
        screen.pen = Pen(r, g, b, 160);
        screen.pixel(p.pos + Point(270, 241));
      }
      screen.pen = Pen(r, g, b, 180);
      screen.pixel(p.pos + Point(270, 242));
    }
  }

  last_time_ms = time_ms;
};



Particle* generate_basic_rain() {  
  return new Particle(
    Vec2((std::rand() % 120) + 100, 0),
    Vec2(0, 100)
  );
}

ParticleGenerator basic_rain_generator(250, 4000, generate_basic_rain);

void render_basic_rain() {
  for (auto p : basic_rain_generator.particles) {
    Particle *sp = static_cast<Particle*>(p);
    if (sp->pos.y >= 239) {
      sp->pos.y = 239;
    }
    screen.pen = Pen(128, 128, 255);
    screen.pixel(sp->pos);
  }
}

uint32_t prev_buttons = blit::buttons;

void render(uint32_t time_ms) {
  if ((blit::buttons ^ prev_buttons) & blit::Button::A) {
      blit::set_screen_mode(blit::lores);
  }
  else if ((blit::buttons ^ prev_buttons) & blit::Button::B) {
      blit::set_screen_mode(blit::hires);
  }
  prev_buttons = blit::buttons;

  screen.pen = Pen(0, 0, 0, 255);
  screen.clear();

  //render_smoke();

  uint32_t ms_start = now();
  spark(time_ms);
  smoke(time_ms); 
  rain(time_ms);
  //render_basic_rain();
  uint32_t ms_end = now();

  // draw grid
  screen.alpha = 255;
  screen.pen = Pen(255, 255, 255);
  screen.rectangle(Rect(0, 0, 320, 14));
  screen.pen = Pen(0, 0, 0);
  screen.text("Rain demo", minimal_font, Point(5, 4));

 /* screen.pen = Pen(255, 255, 255);  
  screen.text("Smoke:", minimal_font, point(10, 20));
  screen.text("Sparks:", minimal_font, point(120, 20));
  screen.text("Rain:", minimal_font, point(220, 20));  */

  // draw FPS meter
  /*screen.alpha = 255;
  screen.pen = Pen(0, 0, 0);
  screen.rectangle(rect(1, 240 - 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, 240 - 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.watermark();
}

void update(uint32_t time_ms) {
//  smoke_generator.update(time_ms);
  basic_rain_generator.update(time_ms);

  if (pressed(Button::DPAD_LEFT)) {
    g.rotate(0.1f);
  }
}