//XYMatrix v18 – ok, med punkter
#include <FastLED.h>
#include <TimeLib.h>

#define LED_PIN  3

#define COLOR_ORDER GRB
#define CHIPSET     WS2811

#define BRIGHTNESS 64

//------------ Definiera matrisen

// Params for width and height
const uint8_t kMatrixWidth = 10;
const uint8_t kMatrixHeight = 9;

// Param for different pixel layouts
const bool    kMatrixSerpentineLayout = true;

#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
CRGB leds_plus_safety_pixel[ NUM_LEDS + 1];
CRGB* const leds( leds_plus_safety_pixel + 1);

//Använd ett begränsat antal led
const int myNumLeds = kMatrixWidth * kMatrixHeight;

//--------- Arrayer med leds som ska tändas

const int klockanAr[9] = {80,81,82,83,84,85,86,   88,89};

const int femMinOver[7]= {79,78,77,58,57,56,55};
const int femMinI[4]= {79,78,77,  75};
const int femMinOverHalv[11] = {79,78,77,  58,57,56,55,   53,52,51,50};
const int femMinIHalv[8] = {79,78,77,  75,   53,52,51,50};

const int tioMinOver[7] = {65,66,67,  58,57,56,55};
const int tioMinI[4] = {65,66,67, 69};
const int femtonMinOver[9] = {74,73,72,71,70,   58,57,56,55};
const int femtonMinI[6]= {74,73,72,71,70,  66};
const int tjugoMinOver[9] = {60,61,62,63,64,   58,57,56,55};
const int tjugoMinI[6] = {60,61,62,63,64,  66};
const int trettioMinI[4] = {53,52,51,50};

const int ettTim[3] = {27,28,29};
const int tvaTim[3] = {3,4,5};
const int treTim[3] = {0,1,2};
const int fyraTim[4] = {14,13,12,11};
const int femTim[3] = {20,21,22};
const int sexTim[3] = {47,48,49};
const int sjuTim[3] = {40,41,42};
const int attaTim[4] = {18,17,16,15};
const int nioTim[3] = {33,32,31};
const int tioTim[3] = {43,44,45};
const int elvaTim[4]= {23,24,25,26};
const int tolvTim[4] = {38,37,36,35};

const int minutPunkter[4] = {6,7,8,9};

//Längd på arrayer
int sizeOfCurrentArray;

const int klockanArLength = 9;

const int femMinOverLength = 7;
const int femMinILength  = 4;
const int femMinOverHalvLength = 11;
const int femMinIHalvLength =8;
const int tioMinOverLength = 7;
const int tioMinILength = 4;
const int femtonMinOverLength = 9;
const int femtonMinILength = 6;
const int tjugoMinOverLength = 9;
const int tjugoMinILength = 6;
const int trettioMinILength = 4;

const int timLengthTre = 3;
const int timLengthFyra = 4;

const int punktLengthEtt = 1;

//---------- Parametrar för beräkning av klockslag

int now_tt = 99;
int now_mm = 99;
int calc_tt = 99;
int calc_mm = 99;
int display_tt = 99;
int display_mm = 99;

int calc_minutpunkt = 99;
int display_minutpunkt = 99;
int antal_minutpunkter = 9;

void setup() 
{
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
  FastLED.setBrightness( BRIGHTNESS );
  Serial.begin(9600);

  //Bestämm starttid
  setTime(7,0,0,19,4,2022); // Starttid. (hh, mm, ss,day, mo, yr)
}

void loop()
{
  //aktullt klockslag, t, så att det inte ändras innan loopen är slut
  time_t t = now();

  //Tilldela aktuell timme och minut
  now_tt = hourFormat12(t);
  now_mm = minute(t);
  Serial.print("now_tt ");
  Serial.println(now_tt);
  Serial.print("now_mm ");
  Serial.println(now_mm);

  //Är aktuell minut delbar med 5, dvs ett fem-minutersintervall
  if ( now_mm % 5 == 0 )
  {
    calc_mm = now_mm;
    Serial.print("calc_mm ");  
    Serial.println(calc_mm);  
    
    } 
    //Om det ett nytt fem-minutersintervall, släck tavla, tänd ny tid
    if (calc_mm != display_mm)
    {

      //---------- SLÄCK ALLA LED / HELA URTAVALAN ------------
      for (int i = 0;  i < myNumLeds; i++)
      { leds[i] =  CRGB::Black; }
      FastLED.show();
      delay(500);

      display_mm = calc_mm;
      Serial.print("display_mm ");  
      Serial.println(display_mm);

      //Ange vilka leds som ska visa minuter över/i/halv
      switch (display_mm)
      {
        case 0:
          //heltimme
          break;

        case 5:
          sizeOfCurrentArray = femMinOverLength;
          lightUpLed(femMinOver,sizeOfCurrentArray,CRGB::Orange);
          break;

        case 10:
          sizeOfCurrentArray = tioMinOverLength;
          lightUpLed(tioMinOver, sizeOfCurrentArray, CRGB::Purple); 
          break;

        case 15:
          sizeOfCurrentArray = femtonMinOverLength;
          lightUpLed(femtonMinOver, sizeOfCurrentArray, CRGB::Red);
          break;
          
        case 20:
          sizeOfCurrentArray = tjugoMinOverLength;
          lightUpLed(tjugoMinOver, sizeOfCurrentArray, CRGB::Blue);
          break;

        case 25:
          sizeOfCurrentArray = femMinIHalvLength;
          lightUpLed(femMinIHalv, sizeOfCurrentArray, CRGB::Green);
          break;
          
        case 30:
          sizeOfCurrentArray = trettioMinILength;
          lightUpLed(trettioMinI, sizeOfCurrentArray, CRGB::Pink);
          break;
          
        case 35:
          sizeOfCurrentArray = femMinOverHalvLength;
          lightUpLed(femMinOverHalv, sizeOfCurrentArray, CRGB::Cyan);
          break;

        case 40:
          sizeOfCurrentArray = tjugoMinILength;
          lightUpLed(tjugoMinI, sizeOfCurrentArray, CRGB::Orange);
          break;
          
        case 45:
          sizeOfCurrentArray = femtonMinILength;
          lightUpLed(femtonMinI, sizeOfCurrentArray, CRGB::Yellow);
          break;

        case 50:
          sizeOfCurrentArray = tioMinILength;
          lightUpLed(tioMinI, sizeOfCurrentArray, CRGB::Magenta);
          break;

        case 55:
          sizeOfCurrentArray = femMinILength;
          lightUpLed(femMinI, sizeOfCurrentArray, CRGB::LightPink);
          break;
      }

      //---------- ANGE TIME ------------
      calc_tt = now_tt;

      //Justera heltimmen beroenden på aktuellt 5-minutersintervallet
      //Notera: 8:00 till 8:20 tänder ÅTTA, medan 8:25 till 8:55 tänder NIO!
      if (display_mm >= 25 && calc_tt < 12 )
      { display_tt = calc_tt+1;}
        else if (display_mm >= 25 && calc_tt == 12)
        { display_tt = 1;}
          else 
          display_tt = calc_tt;
      
      Serial.print("calc_tt ");  
      Serial.println(calc_tt);
      Serial.print("display_tt ");  
      Serial.println(display_tt);   

      //Ange vilka leds som anger heltimme
      switch (display_tt)
      {
        case 1:
          sizeOfCurrentArray = timLengthTre;
          lightUpLed(ettTim, sizeOfCurrentArray, CRGB::Blue);
          break;

        case 2:
          sizeOfCurrentArray = timLengthTre;
          lightUpLed(tvaTim, sizeOfCurrentArray, CRGB::Red);
          break;

        case 3:
          sizeOfCurrentArray = timLengthTre;
          lightUpLed(treTim, sizeOfCurrentArray, CRGB::Yellow);
          break;

        case 4:
          sizeOfCurrentArray = timLengthFyra;
          lightUpLed(fyraTim, sizeOfCurrentArray, CRGB::Green);
          break;

        case 5:
          sizeOfCurrentArray = timLengthTre;
          lightUpLed(femTim, sizeOfCurrentArray, CRGB::Blue);
          break;

        case 6:
          sizeOfCurrentArray = timLengthTre;
          lightUpLed(sexTim, sizeOfCurrentArray, CRGB::Red);
          break;

        case 7:
          sizeOfCurrentArray = timLengthTre;
          lightUpLed(sjuTim, sizeOfCurrentArray, CRGB::Yellow);
          break;

        case 8:
          sizeOfCurrentArray = timLengthFyra;
          lightUpLed(attaTim, sizeOfCurrentArray, CRGB::Green);
          break;

        case 9:
          sizeOfCurrentArray = timLengthTre;
          lightUpLed(nioTim, sizeOfCurrentArray, CRGB::Blue);
          break;

        case 10:
          sizeOfCurrentArray = timLengthTre;
          lightUpLed(tioTim, sizeOfCurrentArray, CRGB::Red);
          break;

        case 11:
          sizeOfCurrentArray = timLengthFyra;
          lightUpLed(elvaTim, sizeOfCurrentArray, CRGB::Yellow);
          break;

        case 12:
          sizeOfCurrentArray = timLengthFyra;
          lightUpLed(tolvTim, sizeOfCurrentArray, CRGB::Green);
          break;

      }
      //---------- NOLLSTÄLL MINUTPUNKTER ---------
      display_minutpunkt = now_mm;
      antal_minutpunkter = 0;


      //---------- ANGE KLOCKA ÄR  ------------
      sizeOfCurrentArray = klockanArLength;
      lightUpLed(klockanAr, sizeOfCurrentArray, CRGB::Cyan);

      //============= YES! Tänd urtavlan!! ================
      FastLED.show();
      
    // End of nytt fem-minutersintervall
    }

  //Om ny minut, tänd minutpunkt
  if (display_minutpunkt != now_mm) // ny minut
  {
    display_minutpunkt = now_mm;
    antal_minutpunkter = antal_minutpunkter +1; 
    Serial.print("display_minutpunkt ");  
    Serial.println(display_minutpunkt);    
    Serial.print("antal_minutpunkter ");  
    Serial.println(antal_minutpunkter);

    sizeOfCurrentArray = antal_minutpunkter;
    lightUpLed(minutPunkter, sizeOfCurrentArray, CRGB::Blue);

    //----------- Tänd en minutpunkt (och allandra led som redan är tända) ----------
    FastLED.show();

  // End of ny minutpunkt
  }

delay(3000);
    
//End of loop
}

/* Spara för framtida bruk. ================================

Hur var/deklarera COLOR (om inte hårdkoda färgen till vit)?

int COLOR = CRGB::Red;

lightUpLed(FEM_MINUTER, sizeof(FEM_MINUTER)/sizeof(FEM_MINUTER[0]),CRGB::Orange);
delay(5000);

*/

int lightUpLed(int* ledArray,int ledArraySize, CRGB colorOfLed)
{
 Serial.print("ledArraySize ");  
 Serial.println(ledArraySize); 
for (byte i = 0; i < ledArraySize; i++) 
{leds[ledArray[i]] = colorOfLed;}
}