// Flappy: any key = flap. Fly through the gaps between the pipes.
#pragma once

const int16_t FLAPPY_X = 24;
const uint8_t PIPE_W = 12;

struct FlappyState {
  int16_t y16, vy16;
  int16_t pipe_x[3];
  uint8_t gap_y[3];
  bool passed[3];
  bool started;
};

uint8_t flappy_gap() {
  return score < 20 ? 26 - score / 4 : 21;
}

void flappy_pipe(FlappyState &g, uint8_t i, int16_t x) {
  g.pipe_x[i] = x;
  g.gap_y[i] = 6 + random(64 - 12 - flappy_gap());
  g.passed[i] = false;
}

void flappy_init(FlappyState &g) {
  memset(&g, 0, sizeof g);
  g.y16 = 28 * 16;

  for (uint8_t i = 0; i < 3; i++) {
    flappy_pipe(g, i, 128 + i * 52);
  }
}

void flappy_update(FlappyState &g) {
  if (any_tap()) {
    g.started = true;
    g.vy16 = -46;
  }

  if (!g.started) {
    return;
  }

  g.vy16 += 5;

  if (g.vy16 > 60) {
    g.vy16 = 60;
  }

  g.y16 += g.vy16;
  int16_t y = g.y16 / 16;

  for (uint8_t i = 0; i < 3; i++) {
    g.pipe_x[i] -= 2;

    if (g.pipe_x[i] < -PIPE_W) {
      flappy_pipe(g, i, g.pipe_x[i] + 156);
    }

    if (!g.passed[i] && g.pipe_x[i] + PIPE_W < FLAPPY_X) {
      g.passed[i] = true;
      score++;
    }

    bool in_column = FLAPPY_X + 8 > g.pipe_x[i] && FLAPPY_X < g.pipe_x[i] + PIPE_W;

    if (in_column && (y < g.gap_y[i] || y + 6 > g.gap_y[i] + flappy_gap())) {
      end_game();
    }
  }

  if (y < 0 || y + 6 > 64) {
    end_game();
  }
}

void flappy_draw(FlappyState &g) {
  for (uint8_t i = 0; i < 3; i++) {
    int16_t x = g.pipe_x[i];
    uint8_t gy = g.gap_y[i];
    uint8_t gap = flappy_gap();
    box(x, 0, PIPE_W, gy);
    box(x - 1, gy - 3, PIPE_W + 2, 3);
    box(x, gy + gap, PIPE_W, 64 - gy - gap);
    box(x - 1, gy + gap, PIPE_W + 2, 3);
  }

  int16_t y = g.y16 / 16;
  box(FLAPPY_X, y, 8, 6);
  box(FLAPPY_X + 8, y + 2, 2, 2);
  oled.setDrawColor(0);
  oled.drawPixel(FLAPPY_X + 5, y + 1);
  box(FLAPPY_X, y + (g.vy16 < 0 ? 1 : 3), 3, 1);
  oled.setDrawColor(1);
  oled.setFont(u8g2_font_7x14B_tr);
  oled.setDrawColor(0);
  box(54, 0, 20, 12);
  oled.setDrawColor(1);
  char s[6];
  utoa(score, s, 10);
  text_center(s, 11);

  if (!g.started) {
    oled.setFont(u8g2_font_5x7_tr);
    oled.setDrawColor(0);
    box(30, 54, 68, 9);
    oled.setDrawColor(1);
    text_center("any key: flap", 61);
  }
}
