enum States {WG, WY, NG, NY, WS, NS, AS } state;

struct MyState {
  int state;
  char *name;
  byte pin;
  int delay1;
  int delay2;
  int nextState;
} myStates[] {
  {WG, "WestGreen", 2, 10000, 8000, WY },
  {WY, "WestYellow", 3, 2000, 1000, WS},
  {NG, "NorthGreen", 8, 10000, 8000, NY},
  {NY, "NorthYellow", 9, 2000, 1000, NS},
  {WS, "WestStop", 4, 0, 0, NG},
  {NS, "NorthStop", 10, 0, 0, WG},
  {AS, "AllStop", 10, 5000, 5000, NS},
};

uint32_t lastSwitchMs = 0;
const byte PedButton = 12;


void setup() {
  Serial.begin(115200);
  pinMode(PedButton, INPUT_PULLUP);
  int ii = 0;
  for ( auto & myState : myStates) {
    pinMode(myState.pin, OUTPUT);
    digitalWrite(myState.pin, HIGH);
    Serial.print(myState.name);
    if (myState.state != ii++)Serial.print("State/myState mismatch\n");
  }
  state = AS;
  digitalWrite(myStates[WS].pin, LOW);
  digitalWrite(myStates[NS].pin, LOW);
  lastSwitchMs = millis();
}

void loop() {
  uint32_t now = millis();
  if (now - lastSwitchMs >= myStates[state].delay1) {
    lastSwitchMs = now;
    // Outgoing transitions
    switch (state) {
      case NS:
        digitalWrite(myStates[WS].pin, HIGH); // turn off opposing light
        break;
      case WS:
        digitalWrite(myStates[NS].pin, HIGH); // turn off opposing light
        break;
      default:
        digitalWrite(myStates[state].pin, HIGH); // turn off light
    }
    // change state
    state = myStates[state].nextState;
    digitalWrite(myStates[state].pin, LOW); // turn on new light
    Serial.print(myStates[state].name); Serial.print(" ");
  }
  if (digitalRead(PedButton) == LOW) {
    state = AS;
    for (auto & myState : myStates) {
      digitalWrite(myState.pin, HIGH);
    }
    digitalWrite(myStates[WS].pin, LOW);
    digitalWrite(myStates[NS].pin, LOW);
    lastSwitchMs = millis();
  }
}


void LightState() {}