#include <EncButton.h>
const byte REMOTE_A_BTN_PIN = 2;
const byte REMOTE_B_BTN_PIN = 3;
const byte REMOTE_D_BTN_PIN = 4;
const byte MANUALLY_STOP_BTN_PIN = 7;

const byte CLOSE_END_SWITCH_PIN = 8;
const byte OPEN_END_SWITCH_PIN = 9;
const byte MAIN_VALVE_PIN = 10;

// Inputs like a buttons
Button remoteA_Btn(REMOTE_A_BTN_PIN);
Button remoteB_Btn(REMOTE_B_BTN_PIN);
Button remoteD_Btn(REMOTE_D_BTN_PIN);
Button manuallyStop_Btn(MANUALLY_STOP_BTN_PIN);
Button openEndSwitcher_Btn(OPEN_END_SWITCH_PIN);
Button closeEndSwitcher_Btn(CLOSE_END_SWITCH_PIN);

// Outputs
const byte RELAY_1_OUTPUT_PIN = 5;
const byte RELAY_2_OUTPUT_PIN = 6;

// Gate status
const byte GATE_STATUS_STOP = 5;
const byte GATE_STATUS_OPENED = 10;
const byte GATE_STATUS_IS_OPENING = 11;
const byte GATE_STATUS_CLOSED = 20;
const byte GATE_STATUS_IS_CLOSING = 21;
byte GATE_STATUS = 0;

// Timers
unsigned long last_time;
const byte MAIN_GATE_VALVE_DELAY = 3; // seconds
const byte GATE_STOP_DEALY = 2; // seconds


void setup() {
  pinMode(RELAY_1_OUTPUT_PIN, OUTPUT);
  pinMode(RELAY_2_OUTPUT_PIN, OUTPUT);
  pinMode(MAIN_VALVE_PIN, OUTPUT);
}

void loop() {
  remoteA_Btn.tick();
  remoteB_Btn.tick();
  remoteD_Btn.tick();

  manuallyStop_Btn.tick();
  openEndSwitcher_Btn.tick();
  closeEndSwitcher_Btn.tick();

  if (remoteA_Btn.click()) {  // click OPEN btn
    if (GATE_STATUS == GATE_STATUS_IS_OPENING) {
      stopMotor();
    } else {
      opening();
    }
  };

  if (remoteB_Btn.click()) {  // click CLOSE btn
    if (GATE_STATUS == GATE_STATUS_IS_CLOSING) {
      stopMotor();
    } else {
      closing();
    }
  };

  if (remoteD_Btn.click() || manuallyStop_Btn.click()) {
    stopMotor();
    GATE_STATUS = GATE_STATUS_STOP;
  };

  // extra cases when something extra happened end we need reverse direction after emergency stop
  if (GATE_STATUS == GATE_STATUS_IS_OPENING) {

    if (millis() - last_time > (unsigned long) MAIN_GATE_VALVE_DELAY * 1000) {
      digitalWrite(MAIN_VALVE_PIN, LOW);
    } else {
      digitalWrite(MAIN_VALVE_PIN, HIGH);
    }
  }

  if (GATE_STATUS == GATE_STATUS_IS_CLOSING) {
    digitalWrite(MAIN_VALVE_PIN, LOW);
    if(closeEndSwitcher_Btn.click()) {
      stopMotor();
    }
    GATE_STATUS = GATE_STATUS_CLOSED;
  }

  // buttonState = digitalRead(buttonPin);
  // Serial.println(buttonState);
}

void stopMotor() {
  digitalWrite(RELAY_1_OUTPUT_PIN, LOW);
  digitalWrite(RELAY_2_OUTPUT_PIN, LOW);
  digitalWrite(MAIN_VALVE_PIN, LOW);
  GATE_STATUS = GATE_STATUS_STOP;
}

void opening() {
  if (openEndSwitcher_Btn.read() == HIGH) { // контакт уже замкнут
    stopMotor();
    GATE_STATUS = GATE_STATUS_OPENED;
  } else {
    digitalWrite(RELAY_1_OUTPUT_PIN, HIGH);
    digitalWrite(RELAY_2_OUTPUT_PIN, LOW);
    GATE_STATUS = GATE_STATUS_IS_OPENING;
    last_time = millis();
  }
}

void closing() {  
  if (closeEndSwitcher_Btn.read() == HIGH) { // контакт уже замкнут
    // stopMotor();
    // GATE_STATUS = GATE_STATUS_CLOSED;
  } else {
    digitalWrite(RELAY_2_OUTPUT_PIN, HIGH);
    digitalWrite(RELAY_1_OUTPUT_PIN, LOW);
    GATE_STATUS = GATE_STATUS_IS_CLOSING;
  }
}