#include <EEPROM.h>
//#include "EasyNextionLibrary.h"  // Include EasyNextionLibrary


//---------------- OUTPUT PINS -------------
#define pulsePin 4
#define Buzzer 5
#define FlushingPump 6
#define BallValve 7
#define RWP 8
#define HPP 9
#define DosingPump2 10
#define led_Pin 11

//const int Flush_Solenoid = 7;
//const int Input_Solenoid = 9;
//const int DosingPump1 = 11;
//const int WaterPump = 13;



//===========================================INPUT PINS======================
#define Low_Pressure A0
#define High_Pressure A1
#define FlowSensor1 A2
#define FlowSensor2 A3

#define interrupt_Pin 2
#define estopPin 3
#define TWT_Float 18
#define RWT_Float 19
#define FlushTank_Float 20
#define Dosing2_Float 21
#define Dosing1_Float A6
#define TDS_Sensor A7


int state, laststate;
unsigned long delay_millis;

int Flush_time;
int Recycling_time;
int Debounce_time;
int FT;
int RT;
int DT;

float Flow1Calib;
float Flow2Calib;

float LowPressure;
float HighPressure;
float SLP;
float SHP;

boolean flagLP = true;
boolean flagHP = true;
boolean TWT_LOW = true;
boolean RWT;
boolean FTF;
boolean DTF;
boolean BypassTWT = false;
boolean BypassRWT = false;
boolean BypassFTF = false;
boolean BypassDTF = false;
boolean Flow1B = false;
boolean Flow2B = false;
boolean LPSBypass = false;
boolean HPSBypass = false;

boolean HASRUN = false;
boolean STOPALL = false;
boolean ESTOP = false;
boolean Maintenance = false;


void setup() {
  Serial.begin(9600);
  Flush_time = 5;
  Recycling_time = 10;
  Debounce_time = 10;
  FT = Flush_time * 1000;
  RT = Recycling_time * 1000;
  DT = Debounce_time * 1000;
  SLP = 2;
  SHP = 10;
  pinMode(Low_Pressure, INPUT);
  pinMode(High_Pressure, INPUT);
  pinMode(TWT_Float, INPUT_PULLUP);
  pinMode(RWT_Float, INPUT_PULLUP);
  pinMode(FlushTank_Float, INPUT_PULLUP);
  pinMode(Dosing1_Float, INPUT_PULLUP);
  pinMode(Dosing2_Float, INPUT_PULLUP);

  pinMode(Buzzer, OUTPUT);
  pinMode(RWP, OUTPUT);
  //  pinMode(Input_Solenoid, OUTPUT);
  pinMode(FlushingPump, OUTPUT);
  //  pinMode(Flush_Solenoid, OUTPUT);
  pinMode(HPP, OUTPUT);
  //  pinMode(DosingPump1, OUTPUT);
  pinMode(DosingPump2, OUTPUT);
  //  pinMode(WaterPump, OUTPUT);
  state = 0;
  laststate = 1;
}

void loop() {
  CHECKPINS();
  handleD1Tank();
  if ( DTF && FTF && RWT && !TWT_LOW) {
    STOPALL = false;
    HASRUN = false;
    Case();
  }
  else {
    STOPALL = true;
    state = 0;
  }
  if (STOPALL == true && HASRUN == false)
  {
    StopAll();
    HASRUN = true;
  }
}

void CHECKPINS() {
  if (BypassTWT == false) {
    if (digitalRead(TWT_Float) == LOW) {
      TWT_LOW = false;
    }
    else {
      TWT_LOW = true;
    }
  }
  else {
    TWT_LOW = true;
  }


  if (BypassRWT == false) {
    if (digitalRead(RWT_Float) == LOW) {
      Serial.println( "RAW WATER TANK LEVEL LOW");
      digitalWrite( Buzzer, HIGH);
      RWT = false;
    }
    else {
      digitalWrite( Buzzer, LOW);
      RWT = true;
    }
  }
  else {
    RWT = true;
    digitalWrite( Buzzer, LOW);
  }


  if (BypassFTF == false) {
    if (digitalRead(FlushTank_Float) == LOW) {
      Serial.println( "FLUSHING WATER TANK LEVEL LOW");
      digitalWrite( Buzzer, HIGH);
      FTF = false;
    }
    else {
      digitalWrite( Buzzer, LOW);
      FTF = true;
    }
  }
  else {
    digitalWrite( Buzzer, LOW);
    FTF = true;
  }


  if (BypassDTF == false) {
    if (digitalRead(Dosing2_Float) == LOW) {
      Serial.println( "FLUSHING WATER TANK LEVEL LOW");
      digitalWrite( Buzzer, HIGH);
      DTF = false;
    }
    else {
      digitalWrite( Buzzer, LOW);
      DTF = true;
    }
  }
  else {
    digitalWrite( Buzzer, LOW);
    DTF = true;
  }
}


void Case() {
  switch (state) {
    case 0:
    if (state != laststate) {
      Serial.print("Case :");
      Serial.println(state);
      laststate = state;
    }
      delay_millis = millis();

      digitalWrite(FlushingPump, HIGH);
      //      digitalWrite(Flush_Solenoid, HIGH);
      state++;
      break;

    case 1:
    if (state != laststate) {
      Serial.print("Case :");
      Serial.println(state);
      laststate = state;
    }
      if (millis() - delay_millis > FT)
      {
        delay_millis = millis();
        state++;
      }
      break;

    case 2:
    if (state != laststate) {
      Serial.print("Case :");
      Serial.println(state);
      laststate = state;
    }
      digitalWrite(FlushingPump, LOW);
      //      digitalWrite(Flush_Solenoid, LOW);

      digitalWrite(RWP, HIGH);
      //      digitalWrite(Input_Solenoid, HIGH);
      state++;
      break;

    case 3:
    if (state != laststate) {
      Serial.print("Case :");
      Serial.println(state);
      laststate = state;
    }
      handle_Low_Pressure();
      if (digitalRead(HPP) == LOW) {
        if (flagLP == true) {
          digitalWrite(HPP, HIGH);
          //          digitalWrite(DosingPump1, HIGH);
          
          state++;
          delay_millis = millis();
        }
      }
      else state++;
      break;

    case 4:
    if (state != laststate) {
      Serial.print("Case :");
      Serial.println(state);
      laststate = state;
    }
      handle_Low_Pressure();
//      if (flagLP == false) {
        if (millis() - delay_millis > DT) {   
          state++;
        }
        break;
    case 5:
    if (state != laststate) {
      Serial.print("Case :");
      Serial.println(state);
      laststate = state;
    }        
        if (flagLP == false) {
          digitalWrite(HPP, LOW);
          state = 9;
        }
        else {
          handle_HIGH_Pressure();
          delay_millis = millis();
          state++;
        }
      break;

    case 6:
      handle_Low_Pressure();
      handle_HIGH_Pressure();
    if (state != laststate) {
      Serial.print("Case :");
      Serial.println(state);
      laststate = state;
    }
      if (flagLP && flagHP) {
        if ((millis() - delay_millis > RT) || digitalRead(TWT_Float) == HIGH || !flagHP) {
          //      if (millis() - delay_millis > FT) {
          delay_millis = millis();
          state++;
        }
      }
      if (!flagLP) state = 5;
      if (!flagHP) {
        digitalWrite(Buzzer, HIGH);
        state = 9;
      }
      break;

    case 7:
    if (state != laststate) {
      Serial.print("Case :");
      Serial.println(state);
      laststate = state;
    }

      digitalWrite(RWP, LOW);
      //      digitalWrite(Input_Solenoid, LOW);
      digitalWrite(FlushingPump, HIGH);
      //      digitalWrite(Flush_Solenoid, HIGH);
      delay_millis = millis();
      state++;
      break;

    case 8:
    if (state != laststate) {
      Serial.print("Case :");
      Serial.println(state);
      laststate = state;
    }
      if (millis() - delay_millis > FT)
      {
        delay_millis = millis();
        if (digitalRead(TWT_Float) == HIGH) {
          state++;
        }
        else if (digitalRead(TWT_Float) == LOW) state = 2;
      }
      break;

    case 9:
    if (state != laststate) {
      Serial.print("Case :");
      Serial.println(state);
      laststate = state;
    }
      digitalWrite( HPP, LOW);
      //      digitalWrite( DosingPump1, LOW);
      digitalWrite( FlushingPump, LOW);
      //      digitalWrite( Flush_Solenoid, LOW);
      digitalWrite(RWP, LOW);
      //      digitalWrite(Input_Solenoid, LOW);

      TWT_LOW = true;
      break;
  }
}


void handle_Low_Pressure() {
  //  LowPressure = analogRead(Low_Pressure);
  if (LowPressure > SLP) {
    flagLP = true;
  }
  else {
    flagLP = false;
    //    StopAll();
//    Serial.println(" LOW PRESSURE LOW");
  }
  const float  OffSet = 0.473 ;
  float V, P;
  V = analogRead(Low_Pressure) * 5.00 / 1024;     //Sensor output voltage
  P = (V - OffSet) * 400;             //Calculate water pressure
  LowPressure = P / 100;
  //pressure_psi = pressure_bar * 14.5038;
}


void handle_HIGH_Pressure() {
  //  HighPressure = analogRead(High_Pressure);
  if (HighPressure > SHP) {
    flagHP = true;
  }
  else {
    flagHP = false;
    //    StopAll();
//    Serial.println(" HIGH PRESSURE HIGH");
  }
  const float  OffSet = 0.473 ;
  float V, P;
  V = analogRead(High_Pressure) * 5.00 / 1024;     //Sensor output voltage
  P = (V - OffSet) * 400;             //Calculate water pressure
  HighPressure = P / 100;
  //pressure_psi = pressure_bar * 14.5038;
}


void handleD1Tank() {
  if (digitalRead(Dosing1_Float) == LOW) {
    Serial.println("DOSING 2 PUMP ON");
    Serial.println("DOSING WATER PUMP ON");
    digitalWrite(DosingPump2, HIGH);
    //    digitalWrite(WaterPump, HIGH);
  }
  else {
    digitalWrite(DosingPump2, LOW);
    //    digitalWrite(WaterPump, LOW);
  }
}



void StopAll() {
  digitalWrite(Buzzer, LOW);
  digitalWrite(RWP, LOW);
  //  digitalWrite(Input_Solenoid, LOW);
  digitalWrite(FlushingPump, LOW);
  //  digitalWrite(Flush_Solenoid, LOW);
  digitalWrite(HPP, LOW);
  //  digitalWrite(DosingPump1, LOW);
  digitalWrite(DosingPump2, LOW);
}