#include "Relays.h"

static unsigned long last_relay_off_ts=0, last_relay_hold_ts=0;
enum RelayState { RELAY_STATE_OFF=0, RELAY_STATE_ON_EVEN_MINUTE, RELAY_STATE_ON_ODD_MINUTE };
static RelayState relaysState = RELAY_STATE_OFF;
static RelayState lastRelayOnState = RELAY_STATE_ON_EVEN_MINUTE;
static bool relayCanSwitch=true;

void Relays::begin(int _relay1Pin, int _relay2Pin) {
  relay1Pin = _relay1Pin;
  relay2Pin = _relay2Pin;
  pinMode(relay1Pin, OUTPUT);
  pinMode(relay2Pin, OUTPUT);
  digitalWrite(relay1Pin, LOW);
  digitalWrite(relay2Pin, LOW);
}

void Relays::toggle() {
  if (relayCanSwitch) {
    if (lastRelayOnState == RELAY_STATE_ON_EVEN_MINUTE) {
      digitalWrite(relay1Pin, HIGH);
      digitalWrite(relay2Pin, LOW);
      relaysState = RELAY_STATE_ON_ODD_MINUTE;
      // P.print("R-OEv");
    } else {
      digitalWrite(relay1Pin, LOW);
      digitalWrite(relay2Pin, HIGH);
      relaysState = RELAY_STATE_ON_EVEN_MINUTE;
      // P.print("R-OOd");
    }
    lastRelayOnState = relaysState;
  } // else P.print("R-OErr");
  relayCanSwitch = false;
  last_relay_hold_ts = millis();
  // increment displayed time
  displayedTime_minutes++;
  if (displayedTime_minutes >= 60) {
    displayedTime_hours++;
    displayedTime_minutes -= 60;
    if (displayedTime_hours >= 24) {
      displayedTime_hours = 0;
    }
  }
  if (fastforwardMode) {
    if (displayedTime_hours == targetHours && displayedTime_minutes == targetMinutes) {
      // wanted time reached!
      fastforwardMode = false;
    }
  }
  Serial.println(F("Toggle Relays"));
}

void Relays::off(void) {
  digitalWrite(relay1Pin, LOW);
  digitalWrite(relay2Pin, LOW);
  last_relay_off_ts = millis();
  relaysState = RELAY_STATE_OFF;
  // P.print("R-Off");
}

void Relays::loop(void) {
  if (relaysState == RELAY_STATE_OFF) {
    if (millis() - last_relay_off_ts > minOffTime_ms) {
      relayCanSwitch = true;
      if (fastforwardMode) toggle();
    }
  } else {
    if (millis() - last_relay_hold_ts > holdTime_ms) {
      off();
    }
  }
}

void Relays::fwdToTime(unsigned int hours, unsigned int minutes) {
  // @TODO
  // as we have a 12h clock, we adjust displayedTime to be before the wanted time
  if (hours < displayedTime_hours ||
      (hours == displayedTime_hours && minutes < displayedTime_minutes)) {
          displayedTime_hours -= 12;
          if (displayedTime_hours < 0) displayedTime_hours += 24;
  }
  targetHours = hours;
  targetMinutes = minutes;
  fastforwardMode = true;
}
