#include <SPI.h>

#define TIMER4_DEBUG
#include "Semafori.h"
#include "sr595.h"
#include <JC_Button.h>

const byte PIN_CS   =  4;   

const byte PIN_START   =  7;

SR59516 sr16(PIN_CS);
Button btnStart(PIN_START);
// tempi in secondi diviso 4  60     3    1
uint16_t StradaleTempi[] = { 15000, 750, 250 };
uint8_t idxST;
uint16_t PedonaleTempi[] = { 3750, 750, 250 };
uint8_t idxPT = 2;
// creare istanza di LSS richiede come argomenti:
// * Una istanza di classe SR59516 (vedi sr16)
// * 3 argomenti bit-verde, bit-giallo e bit-rosso
// Esempio: LSS   lss2(
//               sr16,  // istanza di classe SR59516
//                 10,  // bit 10, pin sr2:Q2
//                 11,  // bit 11, pin sr2:Q3
//                 12   // bit 12, pin sr2:Q4 
//                   );

LSS lss5(sr16, 2, 3, 4);
//LSS lss35(sr16, 5, 6, 7);
LSS lsp5(sr16, 10, 11, 12);
//LSS lss24(sr16, 13, 14, 15);
//LSS ls0(sr16, 0, 1, 2);
//LSS ls1(sr16, 3, 4, 5);
//LSS ls2(sr16, 6, 7, 8);
//LSS ls3(sr16, 9, 10, 11);
//LSS ls4(sr16, 12, 13, 14);





void test0() {
  Timer4 timer4(StradaleTempi);
    // prima di potere usare una istanza di classe LSS
    // è necessario assegnargli un registro.
    // Un registro è sostanzialmente una variabile uint8_t
    // che assume un valore da 0÷2:
    // 0 verde, 1 giallo, 2 rosso.
    lss5.setRegister(timer4.getRegG());
    lsp5.setRegister(timer4.getRegR());
    lsp5.show();
    lss5.show();
    //lss24.setRegister(timer4.getRegR());
    //lss35.setRegister(timer4.getRegG());
    timer4.start();
    while(true) {
      btnStart.read();
      if (btnStart.wasPressed() && bitRead(*lss5.getRegister(), 3) ) {
          Serial.println("prenota");
      }
      // timer4.run() // restituisce true allo scadere dei 
      // seguenti tempi: uint16_t interval[] = { 3000, 1000, 800 };

      bool event = timer4.run();
      if (event) {
          // aggiorna lo stato di tutte le lanterne
          lsp5.show();
          lss5.show();
          //lss24.show();
          //lss35.show();
      }
    }
}

uint8_t regPedonale = Color::RED;
uint8_t regStradale = Color::RED;

//const char *strColor[] = { "Verde", "Giallo", "Rosso" };
void setup() {
 
    Serial.begin(115200);
    btnStart.begin();
    pinMode(PIN_START, INPUT_PULLUP);
    pinMode(PIN_CS, OUTPUT);

    digitalWrite(PIN_CS, HIGH);
    SPI.begin();
    // ad ogni lanterna è possibile assegnare un ID 0÷255 
    lsp5.setId(42);
    lss5.setId(53);
    
    lss5.setRegister(&regStradale);
    lsp5.setRegister(&regPedonale);
    //lss5.show();
    //lsp5.show();
    
    //test0();

}



void incIndex(uint8_t &idx) {
    idx++;
    idx = idx % 3;
}
uint16_t greenStartTime;
uint32_t saveMillis;
//uint16_t startTime;
bool s_allred = true;
// tutti rossi per 2 secondi poi verde per lo stradale
void allRed() {
    
    static uint8_t startTime = millis();
    if (s_allred && millis() - startTime > 2000) {
        regStradale = Color::GREEN;
        greenStartTime = millis();
        saveMillis = greenStartTime;
        s_allred = false;
    }
}
/*
// tempi in secondi diviso 4  60     3    1
uint16_t StradaleTempi[] = { 15000, 750, 250 };
uint8_t idxST;
uint16_t PedonaleTempi[] = { 3750, 750, 250 };
uint8_t idxPT = 2;
*/

// Leggi readme.md per sapere su questa versione
bool pedonalePrenotato;
uint8_t alterna = 0;
uint32_t saveMls0;
uint32_t saveMlsPed;
uint8_t idxSTP;
uint32_t salvaTempoVerdeStradale;
void loop() { 
    btnStart.read();
    
    lss5.show();
    lsp5.show();
    allRed();  // tutti rossi per 2 secondi poi verde per lo stradale
    if (s_allred == false) {
        if (alterna == 0) {
            
            if (millis() - saveMillis >= StradaleTempi[idxST]) {
                saveMillis = millis();
                incIndex(idxST);
                incIndex(regStradale);
                if (idxST == 2) {
                    if (salvaTempoVerdeStradale) {
                        StradaleTempi[0] = salvaTempoVerdeStradale;
                        salvaTempoVerdeStradale = 0;
                        Serial.println(StradaleTempi[0]);
                    }
                    alterna = 1;
                    saveMlsPed = saveMillis;
                }
            }
            if (!pedonalePrenotato && btnStart.wasPressed()) {
                  pedonalePrenotato = true;
                  sr16.set(0, true);
                  sr16.update();
                 
            }
            if (pedonalePrenotato && millis() - saveMillis >= 2500
                    && !(millis() - saveMillis >= 7750)) {
                idxSTP = 1;
                regStradale = 1;
                Serial.println(regStradale);  
                saveMls0 = millis();
                alterna = 2;
            }

        } else if (alterna == 1) {
            if (salvaTempoVerdeStradale == 0) {
                pedonalePrenotato = false;
                sr16.set(0, false);
                sr16.update();
            }
            if (millis() - saveMlsPed >= PedonaleTempi[idxPT]) {
                saveMlsPed = millis();
                incIndex(idxPT);
                incIndex(regPedonale);
                if (idxPT == 2) {
                    alterna = 0;
                    //regStradale = idxST;
                    saveMillis = millis();
                    idxST = 2;
                }
            }
        } else if (alterna == 2) {
              //Serial.println(alterna);
              
              if (millis() - saveMls0 >= StradaleTempi[idxSTP]) {
                  saveMls0 = millis();
                  regStradale = idxSTP = 2;
                  alterna = 1;
                  saveMlsPed = millis();
                  pedonalePrenotato = false;
                  salvaTempoVerdeStradale = StradaleTempi[0];
                  StradaleTempi[0] = StradaleTempi[0] - 
                          (2500+PedonaleTempi[0]+PedonaleTempi[1]+PedonaleTempi[2]);
                  Serial.println(StradaleTempi[0]);
                  sr16.set(0, false);
                  sr16.update();
              }

        }
    }
    
    
}
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
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
gnd1:GND
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
lss35 id=35
lss2 id=42
lss24 id=24
lss5 id=53
10
11
12
2
3
4
13
14
15
5
6
7
pedonale
led1:A
led1:C