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

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define Plus 2
#define Minus 3
#define Save 5
#define ON_BUTTON 6
#define OFF_BUTTON 7
#define Mode 8
#define PUMP_PIN 9

#define EEPROM_ADDRESS 0 // Address to store X value in EEPROM

int X = 50; // Default value for X (you can change this based on your needs)
int Y = 50;
int Z=0;

bool autoMode = true; // Initial mode set to Auto

unsigned long old = 0;
unsigned long old2 = 0; 
bool motorOn = false; // Keeps track of the motor state
String Motor_Stat="OFF";
void setup() 
{
  Serial.begin(9600);
  pinMode(Plus, INPUT_PULLUP);
  pinMode(Minus, INPUT_PULLUP);
  pinMode(Save, INPUT_PULLUP);
  pinMode(ON_BUTTON, INPUT_PULLUP);
  pinMode(OFF_BUTTON, INPUT_PULLUP);
  pinMode(Mode, INPUT_PULLUP);
  pinMode(PUMP_PIN, OUTPUT);
  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3D); // Initialize with the I2C address 0x3C
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  X = EEPROM.read(EEPROM_ADDRESS);
  if(X<0)  X=0;
   if(X>99)  X=19;
  Serial.println(X);
  Y=X;
  if (digitalRead(Mode) == LOW) 
  autoMode = 1; 
  else
  autoMode=0;
  if (digitalRead(Mode) == LOW) 
  autoMode = 1; 
  else
  autoMode=0;
  
}

void loop() 
{
  
  display_print();
  if (autoMode)
  autoMotorControl();
  else 
  manualMotorControl();
  if (motorOn==false)
  {
  checkTimerButtons();
  checkSaveButton();
  }
  
  checkModeButton();
  Serial.println("Loop");

}
void display_print()
{
    display.setCursor(0, 0);
    display.print("Auto Timer: "+String(X));
    display.setCursor(0, 14);
    if(autoMode==true)
    display.print("Mode: Auto");
    else
    display.print("Mode: Manual");
    
   
    display.setCursor(0, 42);
    display.print("Motor On: "+String(Z)+" Min");
    display.setCursor(0, 56);
    display.print("New Timer: "+String(Y));
     if(motorOn==true)
    {
      display.setCursor(0, 28);
      display.print("Motor Status: ON");
      Z=(millis()-old2)/1000;
      delay(100);
      display.display();
      display.clearDisplay();
    }
    else
    {
      display.setCursor(0, 28);
      display.print("Motor Status: OFF");
      Z=0;
      display.display();
    }
    

}
void checkTimerButtons() 
{
  // Check Timer Plus Button
  if (digitalRead(Plus) == LOW) {
    
    Y=Y-1;
   if(Y<0)  Y=0;
   if(Y>99)  Y=99;
   Serial.println(Y);
   display.clearDisplay();
   delay(200); // Button debouncing delay
  }

  // Check Timer Minus Button
  if (digitalRead(Minus) == LOW) {
    Y=Y+1;
    if(Y>99)  Y=99;
    if(Y<0)  Y=0;
    Serial.println(Y);
    display.clearDisplay();
  
    delay(200); // Button debouncing delay
  }
}

void checkSaveButton() {
  // Check Save Value Button
  if (digitalRead(Save) == LOW) 
  {
    Serial.println("Stored");
    EEPROM.write(EEPROM_ADDRESS, Y); // Save X value to EEPROM
    X=Y;
    
    display.clearDisplay();
    delay(200);
    display.display();
  }
}

void checkModeButton() {
  if (digitalRead(Mode) == LOW && autoMode==0) 
  {
  autoMode = 1; 
  display.clearDisplay();
  Z=0;
  motorOn=false;
  digitalWrite(PUMP_PIN, LOW);
  }
  
  else if(digitalRead(Mode) == HIGH && autoMode==1) 
  {
    autoMode=0;
    display.clearDisplay();
    Z=0;
    motorOn=false;
    digitalWrite(PUMP_PIN, LOW);
  }
  
  
}



void autoMotorControl() {
  if (motorOn) {
    unsigned long currentMillis = millis();
    if ((currentMillis - old)/1000 >= X) {
      // Time is up, turn off the motor
      digitalWrite(PUMP_PIN, LOW);
      Z=0;
      display.clearDisplay();
      motorOn = false;
      
    }
  } else {
    // Check Motor ON Button in Auto Mode
    if (digitalRead(ON_BUTTON) == LOW) {
      digitalWrite(PUMP_PIN, HIGH);
      old2=millis();
      motorOn = true;
      old = millis(); // Reset the timer
      
      delay(200); // Button debouncing delay
    }
  }

  // Check Motor OFF Button in Auto Mode
  if (digitalRead(OFF_BUTTON) == LOW) {
    digitalWrite(PUMP_PIN, LOW);
    motorOn = false;
    Z=0;
    display.clearDisplay();
    delay(200); // Button debouncing delay
  }
}

void manualMotorControl() {
  // Check Motor ON Button in Manual Mode
  if (digitalRead(ON_BUTTON) == LOW) {
    digitalWrite(PUMP_PIN, HIGH);
    motorOn = true;
    Z=0;
    old2=millis();
    display.clearDisplay();
    delay(200); // Button debouncing delay
  }

  // Check Motor OFF Button in Manual Mode
  if (digitalRead(OFF_BUTTON) == LOW) {
    digitalWrite(PUMP_PIN, LOW);
    motorOn = false;
    display.clearDisplay();
    Z=0;
    delay(200); // Button debouncing delay
  }
}