// C++ code
//

int Bp = 2;

int R1 = 1;
int R2 = 5;
int Rp = 8;
int G1 = 3;
int G2 = 6;
int Gp = 9;
int V1 = 4;
int V2 = 7;
int Vp = 10;

bool premuto = false;

int stato = 0;
unsigned long previousMillis = 0;

void setup()
{
  pinMode(R1, OUTPUT);
  pinMode(R2, OUTPUT);
  pinMode(Rp, OUTPUT);
  pinMode(G1, OUTPUT);
  pinMode(G2, OUTPUT);
  pinMode(Gp, OUTPUT);
  pinMode(V1, OUTPUT);
  pinMode(V2, OUTPUT);
  pinMode(Vp, OUTPUT);
  
  pinMode(Bp, INPUT);
  attachInterrupt(digitalPinToInterrupt(Bp), premiPedone, FALLING);

  previousMillis = millis();
}

void loop()
{
  
  
  if (premuto == true) {
    for (int i = 0; i < 5; i++) {
       gialloM();
       delay(250);
       digitalWrite(Gp, LOW);
       delay(250);
    }
    verdePedoni();
    delay(2000);
    for (int i = 0; i < 5; i++) {
      digitalWrite(Gp, LOW);
       delay(250);
       gialloM();
       delay(250);
    }
    premuto = false;
    stato = 0;
    previousMillis = millis();
  }
  
  unsigned long currentMillis = millis();

  int intervalloAttuale;
  
  switch (stato)
  {
   case 0: intervalloAttuale = 2000; // V1 R2
    break;
    case 1: intervalloAttuale = 1000; // Giallo
    break;
    case 2: intervalloAttuale = 2000; // V2 R1
    break;
    case 3: intervalloAttuale = 1000; // giallo
    break;
  }
  
  if (currentMillis - previousMillis >= intervalloAttuale) {
    digitalWrite(Rp, HIGH);
    switch (stato)
    {
     case 0: verde1();// V1 R2
      break;
      case 1: giallo(); // Giallo
      break;
      case 2: verde2(); // V2 R1
      break;
      case 3: giallo(); // giallo
      break;
    }
    
    stato++;
    if (stato >= 4)
      stato = 0;
    
    previousMillis = currentMillis;
  }
}

void gialloM() {
  digitalWrite(R1, LOW);
  digitalWrite(R2, LOW);
  digitalWrite(Rp, LOW);
  digitalWrite(V1, LOW);
  digitalWrite(V2, LOW);
  digitalWrite(Vp, LOW);
  digitalWrite(G1, HIGH);
  digitalWrite(G2, HIGH);
  digitalWrite(Gp, HIGH);
}


void giallo() {
  digitalWrite(R1, LOW);
  digitalWrite(R2, LOW);
  digitalWrite(Rp, LOW);
  digitalWrite(V1, LOW);
  digitalWrite(V2, LOW);
  digitalWrite(Vp, LOW);
  digitalWrite(G1, HIGH);
  digitalWrite(G2, HIGH);
  digitalWrite(Gp, LOW);
}

void verdePedoni() {
  digitalWrite(R1, HIGH);
  digitalWrite(R2, HIGH);
  digitalWrite(Rp, LOW);
  digitalWrite(V1, LOW);
  digitalWrite(V2, LOW);
  digitalWrite(Vp, HIGH);
  digitalWrite(G1, LOW);
  digitalWrite(G2, LOW);
  digitalWrite(Gp, LOW);
}

void verde1() {
  digitalWrite(R1, LOW);
  digitalWrite(R2, HIGH);
  digitalWrite(Rp, LOW);
  digitalWrite(V1, HIGH);
  digitalWrite(V2, LOW);
  digitalWrite(Vp, LOW);
  digitalWrite(G1, LOW);
  digitalWrite(G2, LOW);
  digitalWrite(Gp, LOW);
}

void verde2() {
  digitalWrite(R1, HIGH);
  digitalWrite(R2, LOW);
  digitalWrite(Rp, LOW);
  digitalWrite(V1, LOW);
  digitalWrite(V2, HIGH);
  digitalWrite(Vp, LOW);
  digitalWrite(G1, LOW);
  digitalWrite(G2, LOW);
  digitalWrite(Gp, LOW);
}

void premiPedone() {
  if (premuto == false)
 	premuto = true; 
}