#include <TaskScheduler.h>

const int RED_TIME     = 5000;
const int YELLOW_TIME  = 3000;
const int YELLOW_TIME2 = 1000;
const int GREEN_TIME   = 3000;
const int GREEN_BLINK  = 5000;
const int GREEN_BLINK_INTERVAL = 500;
const int WHITE_TIME   = 3000;
const int WHITE_BLINK  = 5000;
const int WHITE_BLINK_INTERVAL = 500;

bool redOE();
void redOD();

bool yellowOE();
void yellowOD();
void yellowOD2();

bool greenOE();
void greenOD();

bool greenBlinkOE();
void greenBlinkCB();
void greenBlinkOD();

bool whiteOE();
void whiteOD();

bool whiteBlinkOE();
void whiteBlinkCB();
void whiteBlinkOD();

Scheduler ts;

Task red(                    RED_TIME,   TASK_ONCE,          NULL,      &ts, false,   redOE,    redOD);
Task yellow(              YELLOW_TIME,   TASK_ONCE,          NULL,      &ts, false,   yellowOE, yellowOD);
Task yellows(            YELLOW_TIME2,   TASK_ONCE,          NULL,      &ts, false,   yellowOE, yellowOD2);
Task green(                GREEN_TIME,   TASK_ONCE,          NULL,      &ts, false,   greenOE,  greenOD);
Task greenBlink( GREEN_BLINK_INTERVAL,           6,  greenBlinkCB,      &ts, false,   greenBlinkOE, greenBlinkOD);
Task white(                WHITE_TIME,   TASK_ONCE,          NULL,      &ts, false,   whiteOE,  whiteOD);
Task whiteBlink( WHITE_BLINK_INTERVAL,           6,  whiteBlinkCB,      &ts, false,   whiteBlinkOE, whiteBlinkOD);



void setup() {
  pinMode(8, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(13, OUTPUT);

  red.restartDelayed();
}

void loop() {
  ts.execute();
}

bool redOE() {
  digitalWrite(8, HIGH);
  return true;
}

void redOD() {
  digitalWrite(8, LOW);
  green.restartDelayed();
}

bool greenOE() {
  digitalWrite(9, HIGH);
  return true;
}

void greenOD() {
  digitalWrite(9, LOW);
  greenBlink.restartDelayed();
  yellow.restartDelayed();
  white.restartDelayed();
}

bool greenState;

bool greenBlinkOE() {
  digitalWrite(9, HIGH);
  greenState = true;
  return true;
}

void greenBlinkCB()  {
  greenState = greenState ^ 1;
  digitalWrite(9, greenState ? HIGH : LOW);
}

void greenBlinkOD() {
  digitalWrite(9, LOW);
}

bool yellowOE() {
  digitalWrite(11, HIGH);
  return true;
}

void yellowOD() {
  digitalWrite(11, LOW);
}

void yellowOD2() {
  digitalWrite(11, LOW);
  red.restartDelayed();
}

bool whiteOE(){
  digitalWrite(13,HIGH);
  return true;
}

void whiteOD(){
  digitalWrite(13,LOW);
  whiteBlink.restartDelayed();
}

bool whiteState;

bool whiteBlinkOE(){
  digitalWrite( 13, HIGH);
  whiteState = true;
  return true;
}

void whiteBlinkCB(){
  whiteState = whiteState ^ 1;
  digitalWrite( 13, whiteState ? HIGH : LOW);
}

void whiteBlinkOD(){
  digitalWrite(13, LOW);
  yellows.restartDelayed();
}