#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h> //Libraries to include so the code works

#define PIR_PIN 2
#define TRIG_PIN 9
#define ECHO_PIN 8
#define BUTTON_PIN 10
//Setting up pins so the arduino understand what variable is on which pin
Adafruit_SSD1306 display;

enum SystemState {
  MOTION_DETECTION,
  DISTANCE_MEASUREMENT
};
//Motion Sensor triggers Distance Sensor
SystemState currentState = MOTION_DETECTION;

void setup() {
  Serial.begin(9600);
  pinMode(PIR_PIN, INPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);

  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
//Setting everything up as an output or as an input
  // No need to specify a reset pin when initializing the display
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // Init with I2C addr 0x3C (128x64)
  display.clearDisplay();
  display.display();
}
//Refreshes Display
void loop() {
  if (currentState == MOTION_DETECTION) { //if the state says that there is motion then then there has been motion detected
    motionDetection();
  } else if (currentState == DISTANCE_MEASUREMENT) { //if its on distance, check the distance
    distanceMeasurement();1
  }
}

void motionDetection() {
  static unsigned long lastMotionDetected = 0;
  const unsigned long debounceTime = 1000; // Debounce time in milliseconds

  display.clearDisplay();

  // Read PIR Sensor state
  int pirState = digitalRead(PIR_PIN);

  // Display PIR status on OLED
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(10, 10);
  display.print("PIR Sensor: ");

  if (pirState == HIGH) {
    unsigned long currentMillis = millis();
    if (currentMillis - lastMotionDetected > debounceTime) {
      lastMotionDetected = currentMillis;  // Update the last motion detected time
      // Display motion detected message
      display.setCursor(90, 10);
      display.print("Motion Detected");
      display.display();
      delay(500);  // Short delay before switching state
      currentState = DISTANCE_MEASUREMENT;
    }
  } else {
    display.setCursor(90, 10);
    display.print("No Motion");
    display.display();
  }

  delay(1000);  // Adjust the delay as needed
}

void distanceMeasurement() {
  float duration;
  float distance_cm;
  float distance_in;

  digitalWrite(TRIG_PIN, LOW); // PULSE ___|---|___
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  duration = pulseIn(ECHO_PIN, HIGH);

  distance_cm = (duration / 2) / 29.1;
  distance_in = (duration / 2) / 73.914;

  display.clearDisplay();

  // Centered text
  display.setTextSize(1);
  display.setTextColor(WHITE);

  int textWidth = 6 * 10; // 6 pixels per character, assuming 10 characters
  int x = (display.width() - textWidth) / 2; // Centered

  display.setCursor(x, 0);
  display.println("Dist Meter");

  display.setCursor(x + 10, 15);
  display.print(distance_cm);
  display.setCursor(x + 55, 15);  //  "cm" to the right
  display.print("cm");

  display.setCursor(x + 10, 25);  // "in" up
  display.print(distance_in);
  display.setCursor(x + 55, 25);  //  "in" to the right
  display.print("in");

  display.display();

  delay(500);
  display.clearDisplay();

  Serial.println(distance_cm);
  Serial.println(distance_in);

  if (digitalRead(BUTTON_PIN) == LOW) {
    while (digitalRead(BUTTON_PIN) == LOW) {}  // Wait for button release
    currentState = MOTION_DETECTION;  // Reset the device on button press
  }
}
