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

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define MANUAL_MODE_PIN 2
#define GREEN_BUTTON_PIN 3
#define RED_BUTTON_PIN 4
#define Sensor_25_percentage 5
#define Sensor_50_percentage 6
#define Sensor_75_percentage 7
#define Sensor_100_percentage 8
#define MOTOR_STATUS_LED_PIN 9
#define RELAY_Green 10
#define RELAY_Red 11
#define Water_Flow 12
#define BUZZER 13

#define LED1 A0
#define LED2 A1
#define LED3 A2
#define LED4 A3

bool manualMode = true;
bool motorRunning = false;
unsigned long current = 0, old = 0;
long interval = 0;
String Motor_percentage = "", Motor_Mode = "", Motor_Status = "";
void setup() {
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;
  }

  display.display();
  delay(100);


  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.clearDisplay();

  pinMode(MANUAL_MODE_PIN, INPUT);
  pinMode(GREEN_BUTTON_PIN, INPUT);
  pinMode(RED_BUTTON_PIN, INPUT);
  pinMode(Sensor_25_percentage, INPUT);
  pinMode(Sensor_50_percentage, INPUT);
  pinMode(Sensor_75_percentage, INPUT);
  pinMode(Sensor_100_percentage, INPUT);
  pinMode(MOTOR_STATUS_LED_PIN, OUTPUT);
  pinMode(RELAY_Green, OUTPUT);
  pinMode(RELAY_Red, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  digitalWrite(Sensor_25_percentage, LOW);
  digitalWrite(Sensor_50_percentage, LOW);
  digitalWrite(Sensor_75_percentage, LOW);
  digitalWrite(Sensor_100_percentage, LOW);
  pinMode(Water_Flow, INPUT);
  setManualMode();
}

void loop() {

  Update_OLED();
   current = millis();
  interval = (current - old) / 1000;

  if (motorRunning==true && interval > 10) {
    tone(BUZZER,1000,3000);
    stopMotor();
    Motor_Status = "Motor OFF"; 
    Motor_percentage = "FLOW ISSUE";
    current=millis();
    old=current;
     interval = (current - old) / 1000;
    while (interval < 20 && manualMode == false) {
    Update_OLED(); 
    if(interval < 5)
    {
       tone(BUZZER,1000);
       delay(500);
       noTone(BUZZER);
       delay(500);
    }
      current = millis();
      interval = (current - old) / 1000;
      delay(10);
      if (digitalRead(MANUAL_MODE_PIN) == HIGH) {
        setManualMode();
      } else {
        setAutoMode();
      }
    }
    return;
  }
  noTone(BUZZER);

    if (motorRunning == true)
    Motor_Status = "Motor ON";
  else
    Motor_Status = "Motor OFF";
  
  if (digitalRead(Sensor_100_percentage) == 1 && digitalRead(Sensor_75_percentage) == 1 && digitalRead(Sensor_50_percentage) == 1 && digitalRead(Sensor_25_percentage) == 1) {
    Motor_percentage = "Water 100%";
  } else if (digitalRead(Sensor_100_percentage) == 0 && digitalRead(Sensor_75_percentage) == 1 && digitalRead(Sensor_50_percentage) == 1 && digitalRead(Sensor_25_percentage) == 1) {
    Motor_percentage = "Water 75%";
  } else if (digitalRead(Sensor_100_percentage) == 0 && digitalRead(Sensor_75_percentage) == 0 && digitalRead(Sensor_50_percentage) == 1 && digitalRead(Sensor_25_percentage) == 1) {
    Motor_percentage = "Water 50%";
  } else if (digitalRead(Sensor_100_percentage) == 0 && digitalRead(Sensor_75_percentage) == 0 && digitalRead(Sensor_50_percentage) == 0 && digitalRead(Sensor_25_percentage) == 1) {
    Motor_percentage = "Water 25%";
  } else if (digitalRead(Sensor_100_percentage) == 0 && digitalRead(Sensor_75_percentage) == 0 && digitalRead(Sensor_50_percentage) == 0 && digitalRead(Sensor_25_percentage) == 0) {
    Motor_percentage = "Water 0%";
  } else {
    Motor_percentage = "ERROR !!!";
    if (motorRunning == true)
      stopMotor();
    digitalWrite(BUZZER, HIGH);
    delay(100);
    digitalWrite(BUZZER, LOW);
    delay(100);
    return;
  }

  if (digitalRead(MANUAL_MODE_PIN) == HIGH) {

    setManualMode();
    Motor_Mode = "Manual";
  } else {
    setAutoMode();
    Motor_Mode = "Auto Mode";
  }


 
  if (digitalRead(Water_Flow) == HIGH) {
    current = millis();
    old = current;
  }


  if (manualMode == true) {
    if (digitalRead(GREEN_BUTTON_PIN) == HIGH && motorRunning == false) {
      startMotor();
    }

    else if (digitalRead(RED_BUTTON_PIN) == HIGH && motorRunning == true) {
      stopMotor();
    } else if (digitalRead(Sensor_100_percentage) == HIGH && motorRunning == true) {
      stopMotor();
    }
  }

  if (manualMode == false) {
    if (digitalRead(Sensor_100_percentage) == HIGH && digitalRead(Sensor_75_percentage) == HIGH && digitalRead(Sensor_50_percentage) == HIGH && digitalRead(Sensor_25_percentage) == HIGH && motorRunning == true) {
      stopMotor();

    } else if (digitalRead(Sensor_50_percentage) == LOW && motorRunning == false) {
      startMotor();
    }
  }

  if (motorRunning == true) {
    if ((millis() / 500) % 5 == 1) {
      digitalWrite(LED1, HIGH);
      digitalWrite(LED2, LOW);
      digitalWrite(LED3, LOW);
      digitalWrite(LED4, LOW);
    }
    if ((millis() / 500) % 5 == 2) {
      digitalWrite(LED1, LOW);
      digitalWrite(LED2, HIGH);
      digitalWrite(LED3, LOW);
      digitalWrite(LED4, LOW);
    }
    if ((millis() / 500) % 5 == 3) {
      digitalWrite(LED1, LOW);
      digitalWrite(LED2, LOW);
      digitalWrite(LED3, HIGH);
      digitalWrite(LED4, LOW);
    }
    if ((millis() / 500) % 5 == 4) {
      digitalWrite(LED1, LOW);
      digitalWrite(LED2, LOW);
      digitalWrite(LED3, LOW);
      digitalWrite(LED4, HIGH);
    }
    if ((millis() / 500) % 5 == 0) {
      digitalWrite(LED1, LOW);
      digitalWrite(LED2, LOW);
      digitalWrite(LED3, LOW);
      digitalWrite(LED4, LOW);
    }
  }
}

void setManualMode() {
  if (manualMode == false) {
    stopMotor();
    manualMode = true;
  }
}

void setAutoMode() {
  if (manualMode == true) {
    startMotor();
    manualMode = false;
  }
}

void startMotor() {
  if (digitalRead(Sensor_100_percentage) == LOW) {
    digitalWrite(RELAY_Green, HIGH);
    digitalWrite(MOTOR_STATUS_LED_PIN, HIGH);
    delay(1000);
    digitalWrite(RELAY_Green, LOW);
    motorRunning = true;  // Set the flag to indicate that the motor is running
    current = millis();
    old = current;
  }
}

void stopMotor() {
  digitalWrite(RELAY_Red, HIGH);
  digitalWrite(MOTOR_STATUS_LED_PIN, LOW);
  delay(500);
  digitalWrite(RELAY_Red, LOW);
  motorRunning = false;  // Reset the flag to indicate that the motor is stopped
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);
  digitalWrite(LED4, LOW);
}


void Update_OLED()
{
  display.clearDisplay();
  display.setCursor(0, 2);
  display.print(Motor_percentage);
  display.setCursor(0, 22);
  display.print(Motor_Mode);
   display.setCursor(0, 42);
  display.print(Motor_Status);
  display.display();
}