#include <MFRC522.h>
#include <MCUFRIEND_kbv.h>
#include <Adafruit_GFX.h>
#include <SPI.h>

// Pin definitions
#define SS_PIN   53  // MFRC522 SDA/SS pin
#define RST_PIN  49  // MFRC522 RST pin
#define GREEN_LED 24
#define RED_LED   26
#define BUZZER    28

// Color definitions
#define BLACK   0x0000
#define WHITE   0xFFFF
#define RED_C   0xF800
#define GREEN_C 0x07E0
#define BLUE    0x001F
#define YELLOW  0xFFE0
#define CYAN    0x07FF

// Create instances
MFRC522 mfrc522(SS_PIN, RST_PIN);
MCUFRIEND_kbv tft;

void setup() {
  Serial1.begin(9600); // For communication with Raspberry Pi (TX1/RX1 on Mega)
  SPI.begin();         // Init SPI bus for RFID
  mfrc522.PCD_Init();  // Init MFRC522 card

  // Setup TFT display
  uint16_t ID = tft.readID();
  if (ID == 0xD3D3) ID = 0x9486;
  tft.begin(ID);
  tft.setRotation(0);
  tft.fillScreen(BLACK);

  // Setup pins
  pinMode(GREEN_LED, OUTPUT);
  pinMode(RED_LED, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  digitalWrite(GREEN_LED, LOW);
  digitalWrite(RED_LED, LOW);
  digitalWrite(BUZZER, LOW);

  // Display ready screen
  tft.setTextSize(2);
  tft.setTextColor(WHITE);
  tft.setCursor(10, 20);
  tft.print("RFID & TFT Ready");
  delay(1000);
  tft.fillScreen(BLACK);
  tft.setCursor(10, 20);
  tft.print("Please scan card...");
}

void loop() {
  // === 1. Check for Pi message ===
  if (Serial1.available()) {
    String message = Serial1.readStringUntil('\n');
    message.trim();

    tft.fillScreen(BLACK);
    tft.setCursor(10, 40);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    tft.print("Status:");

    tft.setCursor(10, 70);
    tft.setTextSize(3);

    // Reset feedback
    digitalWrite(GREEN_LED, LOW);
    digitalWrite(RED_LED, LOW);
    digitalWrite(BUZZER, LOW);

    // === Interpret message ===
    if (message.indexOf("GRANTED") != -1) {
      tft.setTextColor(GREEN_C);
      digitalWrite(GREEN_LED, HIGH);
      tone(BUZZER, 1000, 200); // short beep
    } 
    else if (message.indexOf("DENIED") != -1 || message.indexOf("ERROR") != -1) {
      tft.setTextColor(RED_C);
      digitalWrite(RED_LED, HIGH);
      tone(BUZZER, 500, 800); // long beep
    } 
    else if (message.indexOf("VERIFYING") != -1) {
      tft.setTextColor(YELLOW);
      tone(BUZZER, 2000, 100); // soft short tone
    } 
    else {
      tft.setTextColor(CYAN);
    }

    tft.print(message);
    delay(1000); // show status for 1 sec
    digitalWrite(GREEN_LED, LOW);
    digitalWrite(RED_LED, LOW);
    noTone(BUZZER);
  }

  // === 2. Check for card ===
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    String uidString = "";
    for (byte i = 0; i < mfrc522.uid.size; i++) {
      uidString += (mfrc522.uid.uidByte[i] < 0x10 ? "0" : "");
      uidString += String(mfrc522.uid.uidByte[i], HEX);
    }
    uidString.toUpperCase();

    // Send UID to Pi
    Serial1.println(uidString);

    // Display UID
    tft.fillScreen(BLACK);
    tft.setCursor(10, 40);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    tft.print("Card UID:");
    tft.setCursor(10, 70);
    tft.setTextColor(YELLOW);
    tft.print(uidString);

    mfrc522.PICC_HaltA();
    mfrc522.PCD_StopCrypto1();
    delay(1000);
  }
}
  