#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define LED_PIN_1 2
#define LED_PIN_2 12
#define LED_PIN_3 13

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const int sutunNo = 8;
const int satirNo = 8;
const int potPin = A0;
const int paddleBoy = 16;
const int baslangicHizi = 20;
const int ivmePerLevel = 20;
const int seviyeSayisi = 5;
const int canSayisi = 3;

unsigned long sonHareket;
int topRow = 0;
int topCol = 0;
int topHizi = baslangicHizi;
int topEksenX = 1;
int topEksenY = 1;
int paddlePos;
bool gameRunning = true;
int currentLevel = 1;
int hp = canSayisi;
int score = 0;

const int segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9};
const int commonCathodePin = 10;

bool bricks[sutunNo][satirNo];

const int numBricksPerLevel[] = {2, 3, 4, 5, 6};

void setup() {
  Serial.begin(9600);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;) ;
  }


  for (int pin : segmentPins) {
    pinMode(pin, OUTPUT);
  }
  pinMode(commonCathodePin, OUTPUT);
  digitalWrite(commonCathodePin, LOW);

  for (int i = 0; i < canSayisi; i++) {
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);
  }

  pinMode(LED_PIN_1, OUTPUT);
  pinMode(LED_PIN_2, OUTPUT);
  pinMode(LED_PIN_3, OUTPUT);

  digitalWrite(LED_PIN_1, HIGH);
  digitalWrite(LED_PIN_2, HIGH);
  digitalWrite(LED_PIN_3, HIGH);

  pinMode(potPin, INPUT);

  sonHareket = millis();
  randomSeed(analogRead(0));

  paddlePos = map(analogRead(potPin), 0, 1023, 0, SCREEN_WIDTH - paddleBoy);

  topRow = SCREEN_HEIGHT - 18;
  topCol = paddlePos + paddleBoy / 2;

  initBricks(numBricksPerLevel[0]);

  display.display();
  delay(1000);
  display.clearDisplay();
}


void loop() {
  if (gameRunning) {
    handleInput();
    topHareket();
    drawGame();
    delay(topHizi);
  }
}

void handleInput() {

  paddlePos = map(analogRead(potPin), 0, 1023, 0, SCREEN_WIDTH - paddleBoy);
}
void topHareket() {
  unsigned long currentTime = millis();
  if (currentTime - sonHareket >= topHizi) {
    sonHareket = currentTime;

    topCol += topEksenX;
    topRow += topEksenY;

    if (topCol >= SCREEN_WIDTH || topCol < 0) {
      topEksenX = -topEksenX;
    }
    if (topRow < 0) {
      topEksenY = -topEksenY;
    }

    if (topRow == SCREEN_HEIGHT - 8 && topCol + 1 >= paddlePos && topCol <= paddlePos + paddleBoy) {
      topEksenY = -topEksenY;
    }

   
  int brickCol = topCol / (SCREEN_WIDTH / sutunNo);
  int brickRow = topRow / (SCREEN_HEIGHT / satirNo);
  if (brickRow >= 0 && brickRow < satirNo && brickCol >= 0 && brickCol < sutunNo && bricks[brickCol][brickRow]) {
    bricks[brickCol][brickRow] = false;
    topEksenY = -topEksenY;
    score++;
  }


    if (topRow >= SCREEN_HEIGHT) {
      canKaybi();
      topRow = SCREEN_HEIGHT - 12;
      topCol = paddlePos + paddleBoy / 2;
      return;
    }
  }
}

void drawScore() {

  display.clearDisplay();

  display.setCursor(0, 0);

  display.setTextSize(2);

  display.print(score);

  display.display();
}


void canKaybi() {

  static int currentLED = 0;

 switch (currentLED) {
    case 0:
      digitalWrite(LED_PIN_2, LOW);
      break;
    case 1:
      digitalWrite(LED_PIN_3, LOW);
      break;
    case 2:
      digitalWrite(LED_PIN_1, LOW);
      break;
  }

  currentLED++;

 
  if (currentLED >= canSayisi) {
    gameRunning = false;
    return;
  }
 
  topRow = 0;
  topEksenY = 1;
  topCol = random(0, SCREEN_WIDTH);
}

void initBricks(int numBricks) {

  for (int i = 0; i < sutunNo; i++) {
    for (int j = 0; j < satirNo; j++) {
      bricks[i][j] = false;
    }
  }


  for (int i = 0; i < numBricks; i++) {
    int col = random(0, sutunNo);
    int row = random(0, satirNo / 2);
    bricks[col][row] = true;
  }
}

void drawGame() {
  display.clearDisplay();


  display.fillRect(paddlePos, SCREEN_HEIGHT - 8, paddleBoy, 2, WHITE);


  display.fillCircle(topCol, topRow, 3, WHITE);


  for (int i = 0; i < sutunNo; i++) {
    for (int j = 0; j < satirNo / 2; j++) {
      if (bricks[i][j]) {
        display.fillRect(i * (SCREEN_WIDTH / sutunNo), j * (SCREEN_HEIGHT / satirNo), SCREEN_WIDTH / sutunNo, SCREEN_HEIGHT / satirNo, WHITE);
      }
    }
  }

  display.display();
}