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

#define OLED_RESET 4
#define POTENTIOMETER_PIN A0
#define TEMP_SENSOR_PIN A1
#define BUTTON_PIN 2

Adafruit_SSD1306 display(OLED_RESET);

int mode = 0; // 0 for soil moisture, 1 for pH, 2 for temperature
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
int lastButtonState = HIGH;

void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP); // Set the button pin as input with internal pull-up resistor
  Serial.begin(9600); // Initialize serial communication
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Initialize the OLED display
  display.clearDisplay(); // Clear the display buffer
  display.display(); // Update the display with the cleared buffer
}

void loop() {
  int buttonState = digitalRead(BUTTON_PIN);

  // If the button state has changed
  if (buttonState != lastButtonState) {
    lastDebounceTime = millis();
  }

  // If the button is stable for debounceDelay
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (buttonState == LOW && lastButtonState == HIGH) {
      mode = (mode + 1) % 3; // Cycle the mode between 0, 1, and 2
      Serial.println("Button pressed, toggling mode.");
    }
  }

  lastButtonState = buttonState;

  // Read the analog value from the potentiometer
  int sensorValue = analogRead(POTENTIOMETER_PIN);

  // Read the analog value from the temperature sensor
  int tempValue = analogRead(TEMP_SENSOR_PIN);
  float temperature = tempValue * (5.0 / 1024.0) * 100.0; // Convert the analog reading to temperature

  // Map the analog value to either soil moisture levels, pH levels, or temperature based on the current mode
  float measurement;
  if (mode == 0) {
    measurement = map(sensorValue, 0, 1023, 0, 100); // Map to soil moisture levels (0-100%)
    displayMeasurement("Soil Moisture", measurement, "%");
  } else if (mode == 1) {
    measurement = map(sensorValue, 0, 1023, 0, 14); // Map to pH levels (0-14)
    displayMeasurement("pH Level", measurement, "");
  } else {
    displayMeasurement("Temperature", temperature, "C");
  }

  // Print the measurement value to the Serial Monitor
  Serial.print("Mode: ");
  Serial.println(mode == 0 ? "Soil Moisture" : (mode == 1 ? "pH Level" : "Temperature"));
  Serial.print("Measurement: ");
  Serial.println(measurement);

  delay(1000); // Add a delay between readings
}

void displayMeasurement(String label, float value, String unit) {
  display.clearDisplay(); // Clear the display buffer
  display.setTextSize(1); // Set text size to 1 (small)
  display.setTextColor(WHITE); // Set text color to white
  display.setCursor(0, 0); // Set cursor to (0,0)
  display.println(label); // Print the label (e.g., "Soil Moisture", "pH Level", or "Temperature")
  display.setTextSize(2); // Set text size to 2 (medium)
  display.setCursor(0, 20); // Set cursor to (0,20)
  display.print(value); // Print the measurement value
  display.print(" "); // Add a space
  display.print(unit); // Print the unit (e.g., "%", "C")
  display.display(); // Display the content on the OLED display
}