#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <SPI.h>

#define TFT_CS   17  // CS-pin voor TFT (connecteer met RPi Pico GPIO)
#define TFT_DC   15  // DC-pin voor TFT (connecteer met RPi Pico GPIO)
#define TFT_RST  14  // RESET-pin voor TFT (connecteer met RPi Pico GPIO)
#define TFT_LED  21  // LED-pin (connecteer met RPi Pico GPIO)
#define BUTTON_UP_PIN 11 // recht Pin voor knop omhoog
#define BUTTON_DOWN_PIN 12 // recht Pin voor knop omlaag
#define BUTTON_UP2_PIN 8 // linker paddle pin naar hoog 
#define BUTTON_DOWN2_PIN 9 // linker paddle oin naarlaag 

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

signed int paddel1X = 100;  // x-waarde van de rechte paddle 
signed int prev_paddel1X;
signed int new_paddel1X;

char paddel2X = 100; // x-waarde van de linker paddle
char prev_paddel2X;
char new_paddel2X;

int ballspeedX = 1;
int ballspeedY = 1;

int ballX = 120;
int new_ballX;
int prev_ballX;

int ballY = 160;
int new_ballY;
int prev_ballY;

int P1 = 0;
int P2 = 0;

void setup() {
  int w, h;

  Serial1.begin(115200);
  Serial1.println("Started...");

  tft.begin();

  w = tft.width();
  h = tft.height();
  Serial1.println(w);
  Serial1.println(h);

  pinMode(TFT_LED, OUTPUT);
  analogWrite(TFT_LED, 10);  // Pas de helderheid aan (0-255)

  pinMode(BUTTON_UP_PIN, INPUT_PULLDOWN);
  pinMode(BUTTON_DOWN_PIN, INPUT_PULLDOWN);

  pinMode(BUTTON_UP2_PIN, INPUT_PULLDOWN);
  pinMode(BUTTON_DOWN2_PIN, INPUT_PULLDOWN);

  tft.fillScreen(ILI9341_PINK); // achtergrondkleur  

  tft.fillRect(paddel1X, 40, 50, 6, ILI9341_WHITE);
  tft.fillRect(paddel2X, 280, 50, 6, ILI9341_WHITE);
  tft.drawRect(ballX, ballY, 10, 10, ILI9341_GREEN);
  tft.drawRect(120, 160, 10,10, ILI9341_PINK);
}

void loop() {
  char BUTTON_UP, BUTTON_DOWN;
  char BUTTON_UP2, BUTTON_DOWN2;

  BUTTON_UP = digitalRead(BUTTON_UP_PIN);
  BUTTON_DOWN = digitalRead(BUTTON_DOWN_PIN);

  BUTTON_UP2 = digitalRead(BUTTON_UP2_PIN);
  BUTTON_DOWN2 = digitalRead(BUTTON_DOWN2_PIN);
  
  ballX += ballspeedX;
  ballY += ballspeedY;

  reset_ball();
  set_ball();

  if (ballX >= 230 || ballX <= 25) {
    // Reverse the horizontal direction
    ballspeedX = -ballspeedX;
    ballspeedY = -ballspeedY;
  }

  // ball reseten na elke punt 
  if (ballY >= 315 || ballY <= 5) {
    
   tft.drawRect(ballX, ballY, 10, 10, ILI9341_GREEN);
   tft.drawRect(120, 160, 10,10, ILI9341_PINK);

   ballX += ballspeedX;
   ballY += ballspeedY;

   reset_ball();
   set_ball();
 }
  Serial1.print(ballspeedX);
  Serial1.print(':');
  Serial1.print(ballspeedY);
  Serial1.print(ballX);
  Serial1.print(':');
  Serial1.println(ballY);

  // als BUTTON_UP 1 is, gaat de paddle omhoog
  if (BUTTON_UP && paddel1X >= 25) {
    // Verplaats de rechte paddle omhoog
    prev_paddel1X = paddel1X;
    paddel1X = paddel1X - 7;
    reset_paddle(prev_paddel1X);
    set_paddle(paddel1X);
  }

  // als BUTTON_DOWN 1 is, gaat de paddle omlaag
  if (BUTTON_DOWN && paddel1X <= 185) {
    // Verplaats de rechte paddle omlaag
    prev_paddel1X = paddel1X;
    paddel1X = paddel1X + 7;
    reset_paddle(prev_paddel1X);
    set_paddle(paddel1X);
  }

  if (BUTTON_UP2 && paddel2X >= 25) {
    // Verplaats de linker paddle omhoog
    prev_paddel2X = paddel2X;
    paddel2X = paddel2X - 7;
    reset_paddle2(prev_paddel2X);
    set_paddle2(paddel2X);
  }

  if (BUTTON_DOWN2 && paddel2X <= 185) {
    // Verplaats de linker paddle omlaag
    prev_paddel2X = paddel2X;
    paddel2X = paddel2X + 7;
    reset_paddle2(prev_paddel2X);
    set_paddle2(paddel2X);
  }

  tft.setCursor(260,0);
  tft.setTextColor(ILI9341_WHITE,ILI9341_PINK);  tft.setTextSize(2);
  tft.setRotation(1);
  tft.print("P2=");
  tft.setRotation(0);
  if(ballY<=10) { 
   P2=P2+1;
   tft.setCursor(280, 0);
   tft.setTextColor(ILI9341_WHITE,ILI9341_PINK);  tft.setTextSize(2);
   tft.setRotation( 1);
   tft.print(P2);
   tft.setRotation( 0);
  }

  tft.setCursor(0, 0);
  tft.setTextColor(ILI9341_WHITE,ILI9341_PINK);  tft.setTextSize(2);
  tft.setRotation(1);
  tft.print("P1=");
  tft.setRotation(0);
  if(ballY>=310) { 
   P1=P1+1;
   tft.setCursor(40, 0);
   tft.setTextColor(ILI9341_WHITE,ILI9341_PINK);  tft.setTextSize(2);
   tft.setRotation(1);
   tft.print(P1);
   tft.setRotation(0);
  }
    
  

 // Check if P1 or P2 reaches 5 points
  if (P1 >= 5 || P2 >= 5) {
    // Game ends, display winner and reset the game
    displayWinner();
    delay(1000);
    resetGame();
  }

  delay(100);
}

// Display the winner
void displayWinner() {
  tft.fillScreen(ILI9341_PINK);
  tft.setCursor(30,100);
  tft.setRotation(1);
  tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(3);
  if (P1 >= 5) {
    tft.println("Player 1 WINS!");
  } 

  else if( P2 >= 5) {
    tft.println("Player 2 WINS!");
  }
  tft.setRotation(0);
}

// Reset the game
void resetGame() {
  P1 = 0;
  P2 = 0;
  paddel1X = 100;
  paddel2X = 100;
  ballX = 120;
  ballY = 160;
  ballspeedX = 1;
  ballspeedY = 1;
  tft.fillScreen(ILI9341_PINK);
  tft.fillRect(paddel1X, 40, 50, 6, ILI9341_WHITE);
  tft.fillRect(paddel2X, 280, 50, 6, ILI9341_WHITE);
  tft.drawRect(ballX, ballY, 10, 10, ILI9341_GREEN);
  tft.drawRect(120, 160, 10, 10, ILI9341_PINK);
}

// player 1 
void reset_paddle(char prev_xpos) {
  for (char w = 0; w <= 6; w++) {
    tft.drawLine(prev_xpos, 40 + w, prev_xpos + 50, 40 + w, ILI9341_PINK);
  }
}

// player 1 
void set_paddle(char new_xpos) {
  for (char w = 0; w <= 6; w++) {
    tft.drawLine(new_xpos, 40 + w, new_xpos + 50, 40 + w, ILI9341_WHITE);
  }
}

void reset_paddle2(char prev_xpos2) {
  for (char w = 0; w <= 6; w++) {
    tft.drawLine(prev_xpos2, 280 + w, prev_xpos2 + 50, 280 + w, ILI9341_PINK);
  }
}

void set_paddle2(char new_xpos2) {
  for (char w = 0; w <= 6; w++) {
    tft.drawLine(new_xpos2, 280 + w, new_xpos2 + 50, 280 + w, ILI9341_WHITE);
  }
}

void set_ball() {
  new_ballX = ballX + ballspeedX;
  new_ballY = ballY + ballspeedY;
  new_ballX <= 235;
  new_ballY <= 315;
  tft.drawRect(new_ballX, new_ballY, 10, 10, ILI9341_GREEN);
}

void reset_ball() {
  tft.drawRect(prev_ballX, prev_ballY, 20, 20, ILI9341_PINK);
  prev_ballX = ballX;
  prev_ballY = ballY;
}
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT