// Pin Definitions
const int inOff = 3;
const int inPulse = 5;
const int inLow = 7;
const int inHigh = 9;
const int inPump = 11;
const int inPot = 12;
const int oMotor = 39;
const int oMag = 37;
const int oPump = 18;
const int oWash = 16;
const int oLED = 15;

// Global Variables
int waitingTime = 5000; // Default waiting time in milliseconds (5 seconds)
bool isWipIntmRunning = false; // Flag to track if WipIntm function is running
unsigned long previousTime = 0; // Variable to store the previous time for checking elapsed time

// Default state: WipOffPark
int currentState = 0;

void setup() {
  // Initialize input pins
  
  pinMode(inOff, INPUT_PULLUP);
  pinMode(inPulse, INPUT_PULLUP);
  pinMode(inLow, INPUT_PULLUP);
  pinMode(inHigh, INPUT_PULLUP);
  pinMode(inPump, INPUT_PULLUP);
  pinMode(inPot, INPUT);

  // Initialize output pins
  pinMode(oMotor, OUTPUT);
  pinMode(oMag, OUTPUT);
  pinMode(oPump, OUTPUT);
  pinMode(oWash, OUTPUT);
  pinMode(oLED, OUTPUT);

  // Default state: all Outputs are off (WipOffPark)
  digitalWrite(oMotor, LOW);
  digitalWrite(oMag, LOW);
  digitalWrite(oPump, LOW);
  digitalWrite(oWash, LOW);
}

void loop() {
  // Blink LED
  digitalWrite(oLED, HIGH);
  delay(100);
  digitalWrite(oLED, LOW);
  delay(100);

  // Read input states
  int offParkState = digitalRead(inOff);
  int intmState = digitalRead(inPulse);
  int loState = digitalRead(inLow);
  int hiState = digitalRead(inHigh);

  // Check input states and execute corresponding functions
  if (offParkState == HIGH) {
    WipOffPark();
    currentState = 0; // Set current state to WipOffPark
  } else if (intmState == HIGH) {
    if (!isWipIntmRunning) {
      WipIntm();
      currentState = 1; // Set current state to WipIntm
    }
  } else if (loState == HIGH) {
    WipLo();
    currentState = 2; // Set current state to WipLo
  } else if (hiState == HIGH) {
    WipHi();
    currentState = 3; // Set current state to WipHi
  } else {
    // Stop WipIntm function if no input is detected
    if (currentState == 1 && isWipIntmRunning) {
      isWipIntmRunning = false;
      digitalWrite(oPump, HIGH);
    }
  }

  // Update waiting time based on potentiometer value
  int potValue = analogRead(inPot);
  waitingTime = map(potValue, 0, 1023, 5000, 30000); // 5 seconds to 30 seconds

  // Check if the waiting time has elapsed for WipIntm function
  if (currentState == 1 && isWipIntmRunning && millis() - previousTime >= waitingTime) {
    previousTime = millis(); // Update the previous time for the next waiting period
    digitalWrite(oPump, LOW);
    delay(1000);
    digitalWrite(oPump, HIGH);
  }
}

void WipOffPark() {
  digitalWrite(oMotor, LOW);
  digitalWrite(oMag, LOW);
  digitalWrite(oPump, HIGH);
  digitalWrite(oWash, HIGH);
}

void WipIntm() {
  isWipIntmRunning = true; // Set the flag to indicate that WipIntm function is running
  digitalWrite(oMotor, LOW);
  digitalWrite(oMag, LOW);
  digitalWrite(oPump, HIGH);
  digitalWrite(oWash, HIGH);

  while (digitalRead(inPulse) == HIGH && isWipIntmRunning) {
    // WipIntm function code
    int potValue = analogRead(inPot);
    waitingTime = map(potValue, 0, 1023, 5000, 30000); // Update waiting time based on potentiometer value

    unsigned long currentTime = millis();
    if (currentTime - previousTime >= waitingTime) {
      previousTime = currentTime;
      digitalWrite(oPump, LOW);
      delay(1000);
      digitalWrite(oPump, HIGH);
    }
  }

  isWipIntmRunning = false; // Reset the flag after the loop ends
  digitalWrite(oPump, HIGH);
}

void WipLo() {
  digitalWrite(oMotor, LOW);
  digitalWrite(oMag, LOW);
  digitalWrite(oPump, LOW);
  digitalWrite(oWash, HIGH);
}

void WipHi() {
  digitalWrite(oMotor, HIGH);
  digitalWrite(oMag, LOW);
  digitalWrite(oPump, LOW);
  digitalWrite(oWash, HIGH);
}
