#include <SPI.h>
#include "Semafori.h"
#include "sr595.h"

const byte PIN_CS   =  4;   


// tempi specificati in millesimi di secondo
uint16_t lss0_2Times[] = { 5000,   750,    250 }; 
uint16_t lss1_3Times[] = { 3000,   750,    250 };
//                         Verde, Giallo, Rosso
// Nota sui tempi:
// il verde di durata meggiore viene solitamente assegnato 
// alla strada più trafficata

uint8_t lssR00 = Color::RED;   // registro per lss0 
uint8_t lssR02 = Color::RED;   // registro per lss2
uint8_t lssR1_3 = Color::RED;  // registro per lss1 e lss3 (Est e Ovest)
uint8_t lssR3_0 = Color::RED;  // registro per lss3 e lss0 (Ovest e Nord)
uint32_t greenStartTime;       // dove salvare millis()

char *forPhases[] = {
          "Grrrrrgr"  //fase 1
          "rGrGgrgr"  //fase 2
          "rrrrgGGG"  //fase 3
          "rrGrGrrr"  //fase 4

};


// sr16 è istanza di classe SR59516 per controllare due shift register 595
SR59532 sr32(PIN_CS);
// Istanze di Lanterne Semaforiche Stradali
LSS lss0(sr32, 0, 1, 2);      // Nord (ore 12)
LSS lss1(sr32, 3, 4, 5);      // Est (ore 3)
LSS lss2(sr32, 6, 7, 8);      // Sud (ore 6)     
LSS lss3(sr32, 9, 10, 11);    // Ovest (ore 9)
LSS lssp0(sr32, 12, 13, 14);  

void setup() {
 
    Serial.begin(115200);
    
    pinMode(PIN_CS, OUTPUT);

    digitalWrite(PIN_CS, HIGH);
    SPI.begin();
    // ad ogni lanterna è possibile assegnare un ID 0÷255 
    lss0.setId(0);
    lss1.setId(1);
    lss2.setId(2);
    lss3.setId(3);
    //lssp1.setId(4);
    // Connette le lanterne ai registri.
    lss0.connectToReg(lssR00);   
    lss2.connectToReg(lssR02);
    // le lanterne lss1 e 3 condividono lo stesso registro lssR1_3
    lss1.connectToReg(lssR1_3);
    lss3.connectToReg(lssR1_3);
    
}

bool f_allred = true;   
// Accende tutti rossi per 2 secondi poi lss1_3 su verde
void allRed() {
    
    static uint8_t startTime = millis();
    if (f_allred && millis() - startTime > 2000) {
        lssR1_3 = Color::GREEN;
        greenStartTime = millis();
        f_allred = false;
        Serial.println("allRed");
    }
}

Color matureToRed(uint8_t &reg, uint16_t *times) {
    Color color = Color::NOCOLOR;
    if (millis() - greenStartTime >= times[reg]) {
        greenStartTime = millis();
        reg++;
        reg = reg % 3;
        color = reg;
    }
    return color;
}

uint8_t phase = 1;  // seleziona la fase iniziale

void loop() { 
    // occorre chiamare il metodo show per ogni istanza di lanterna 
    lss0.show();
    lss1.show();
    lss2.show();
    lss3.show();
    // Mantiene accessi tutti rossi per 2 secondi, poi lss1_3 commuta sul verde 
    allRed();  
    if (f_allred) 
        return;

    switch (phase) {
        
      case 1:
          /*if (lss1.color() == Color::GREEN)
              lss3.setRegister(&lss1_3);*/
          lss3.connectOnGreen(lssR1_3, lss1);
          if (matureToRed(lssR1_3, lss1_3Times) == Color::RED) {
              phase = 2;
          } 

          break;

      case 2:
          if (matureToRed(lssR02, lss0_2Times) == Color::RED) {
              lss3.connectToReg(lssR3_0);
              lss0.connectToReg(lssR3_0);
              phase = 3;
          }
          
          break;

      case 3:
          if (lss3.color() == Color::GREEN)
              lss3.disconnect();
          if (matureToRed(lssR3_0, lss1_3Times) == Color::RED) {
              lss1.connectToReg(lssR1_3);
              phase = 1;
          } 
          
          break;
     
    }
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
74HC595
sr1:Q1
sr1:Q2
sr1:Q3
sr1:Q4
sr1:Q5
sr1:Q6
sr1:Q7
sr1:GND
sr1:Q7S
sr1:MR
sr1:SHCP
sr1:STCP
sr1:OE
sr1:DS
sr1:Q0
sr1:VCC
led3:A
led3:C
led4:A
led4:C
led5:A
led5:C
led6:A
led6:C
led7:A
led7:C
led8:A
led8:C
74HC595
sr2:Q1
sr2:Q2
sr2:Q3
sr2:Q4
sr2:Q5
sr2:Q6
sr2:Q7
sr2:GND
sr2:Q7S
sr2:MR
sr2:SHCP
sr2:STCP
sr2:OE
sr2:DS
sr2:Q0
sr2:VCC
led11:A
led11:C
led12:A
led12:C
led13:A
led13:C
led14:A
led14:C
led15:A
led15:C
led16:A
led16:C
lss0 id=0
lss1 id=1
lss3 id=3
lss2 id=2
3
4
5
8
7
6
9
10
11
0
1
2
sw1:1a
sw1:2a
sw1:3a
sw1:4a
sw1:5a
sw1:6a
sw1:7a
sw1:8a
sw1:8b
sw1:7b
sw1:6b
sw1:5b
sw1:4b
sw1:3b
sw1:2b
sw1:1b
sw2:1a
sw2:2a
sw2:3a
sw2:4a
sw2:5a
sw2:6a
sw2:7a
sw2:8a
sw2:8b
sw2:7b
sw2:6b
sw2:5b
sw2:4b
sw2:3b
sw2:2b
sw2:1b
sw3:1a
sw3:2a
sw3:3a
sw3:4a
sw3:5a
sw3:6a
sw3:7a
sw3:8a
sw3:8b
sw3:7b
sw3:6b
sw3:5b
sw3:4b
sw3:3b
sw3:2b
sw3:1b
74HC595
sr3:Q1
sr3:Q2
sr3:Q3
sr3:Q4
sr3:Q5
sr3:Q6
sr3:Q7
sr3:GND
sr3:Q7S
sr3:MR
sr3:SHCP
sr3:STCP
sr3:OE
sr3:DS
sr3:Q0
sr3:VCC
LS0
LS1
LS2
LS3
LS4
LS5
LS6
LS7
led1:A
led1:C
led2:A
led2:C
led9:A
led9:C
12
13
14
lssp0 pedonale su lss0