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

// Define ILI9341 display pins
#define TFT_CLK 13
#define TFT_MISO 12
#define TFT_MOSI 11
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8

// Define display dimensions
#define TFT_WIDTH 320
#define TFT_HEIGHT 240

// Initialize ILI9341 display
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CLK, TFT_RST, TFT_DC, TFT_CS, TFT_MISO, TFT_MOSI);

// Define HC-SR04 sensor pins
#define NUM_SENSORS 3
const int triggerPins[NUM_SENSORS] = {2, 3, 4};
const int echoPins[NUM_SENSORS] = {5, 6, 7};

// Define parking slot availability
bool slotsAvailable[NUM_SENSORS] = {true, true, true};

void setup() {
  // Initialize the ILI9341 display
  tft.begin();
  tft.setRotation(3); // Adjust screen orientation if needed

  // Clear the screen
  tft.fillScreen(ILI9341_BLACK);

  // Set the font size and color
  tft.setTextSize(2);
  tft.setTextColor(ILI9341_WHITE);
}

void loop() {
  // Check the availability of parking slots
  for (int i = 0; i < NUM_SENSORS; i++) {
    slotsAvailable[i] = isSlotAvailable(i);
  }

  // Clear the screen
  tft.fillScreen(ILI9341_BLACK);

  // Display parking slot availability
  for (int i = 0; i < NUM_SENSORS; i++) {
    displaySlotStatus(i, slotsAvailable[i]);
  }

  // Update the display
  tft.setCursor(0, 0);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(2);
  if (allSlotsFull()) {
    tft.println("No Slots Available");
  } else {
    tft.println("Slots Available");
  }

  delay(2000); // Delay for visibility
}

// Function to check if a parking slot is available
bool isSlotAvailable(int slotIndex) {
  long duration;
  int distance;

  // Send ultrasonic pulse
  pinMode(triggerPins[slotIndex], OUTPUT);
  digitalWrite(triggerPins[slotIndex], LOW);
  delayMicroseconds(2);
  digitalWrite(triggerPins[slotIndex], HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPins[slotIndex], LOW);

  // Measure echo time
  pinMode(echoPins[slotIndex], INPUT);
  duration = pulseIn(echoPins[slotIndex], HIGH);

  // Calculate distance based on speed of sound
  distance = duration * 0.034 / 2;

  // Adjust distance threshold as needed
  return (distance > 10); // Set a suitable threshold value
}

// Function to display the status of a parking slot
void displaySlotStatus(int slotIndex, bool isAvailable) {
  int xPos = 20;
  int yPos = 40 + slotIndex * 40;

  // Set text color based on availability
  if (isAvailable) {
    tft.setTextColor(ILI9341_GREEN);
  } else {
    tft.setTextColor(ILI9341_RED);
  }

  // Display slot index and availability
  tft.setCursor(xPos, yPos);
  tft.print("Slot ");
  tft.print(slotIndex + 1);
  tft.print(": ");
  if (isAvailable) {
    tft.println("Available");
  } else {
    tft.println("Occupied");
  }
}

// Function to check if all slots are full
bool allSlotsFull() {
  for (int i = 0; i < NUM_SENSORS; i++) {
    if (slotsAvailable[i]) {
      return false;
    }
  }
  return true;
}