/*
  KLOKKEPROSJEKT 2025
  ====================
  En smart skole-timeplan klokke med NeoPixel LED-ring
  
  Hver elev/gruppe skal implementere sin egen funksjon.
  Alle funksjoner må følge spesifikasjonene nøyaktig!
*/
#include <WiFi.h>
#include <time.h>
#include <Adafruit_NeoPixel.h>
// ========== HARDWARE KONFIGURASJON ==========
#define LED_PIN 25        // Pin for NeoPixel ring
#define NUM_LEDS 77       // Antall LEDs på ringen (60 = en hel sirkel)
#define soundpin 26       // Linus sin buzzerpin
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
// ========== WIFI KONFIGURASJON ==========
const char* ssid = "Wokwi-GUEST";      // WiFi navn
const char* password = "";               // WiFi passord
// ========== ENUMS OG DATASTRUKTURER ==========
enum Fag {
  INGENTING, FRIMINUTT, ELKRETSER, ELENERGI, STYRESYS, NORSK, ENGELSK, MATTE, NATURFAG, GYM
};
enum Ukedag {
  SONDAG = 0, MANDAG, TIRSDAG, ONSDAG, TORSDAG, FREDAG, LORDAG
};
struct timePlan {
  Ukedag dag;       // Se enum Ukedag
  byte startTime;   // 0-23
  byte startMinutt; // 0-59
  byte varighet;    // Minutter
  Fag fag;          // Enum for fag
};
// ========== GLOBALE VARIABLER ==========
timePlan plan[50];     // Array for hele ukens timeplan
int antallTimer = 48;  // HØYESTE INDEX + 1 (ikke antall elementer!)
Fag gjeldendeFag = INGENTING; // Hvilket fag vi har nå (bruker enum)
Fag forrigeFag = INGENTING;   // Hvilket fag vi hadde før
int sekunderIgjen = 0;        // Sekunder igjen av gjeldende aktivitet
// Status-flagg for animasjoner
bool nyTime = false;
bool nyttFriminutt = false; 
bool ferdigForDagen = false;
bool erHelg = false;
// ========== FUNKSJONSERKLÆRINGER ==========
// Disse funksjonene må elevene implementere:
// ENKLE FUNKSJONER:
bool sjekkHelg(int ukedag);
uint32_t fagFarge(Fag fag);
void blinkLED(uint32_t farge, int antallBlink);
void timeStartAnimasjon();
void friminuttAnimasjon();
void visMeny(); // Meny hvor brukeren kan aktivere alle funksjonene
// MIDDELS FUNKSJONER:
void visKlokkevisere(int time, int minutt, int sec);
//void nedtellingBar(timeinfo.tm_min, sekunderIgjen, fagFarge(gjeldendeFag), timeinfo.tm_hour, timeinfo.tm_wday);
void spillMelodi(int melodi);
void ferdigForDagenAnimasjon();
void helgeSluttAnimasjon();
// AVANSERTE FUNKSJONER:
void fyllPlan();
int beregnTidIgjen(int time, int minutt, int sekund, int ukedag);
Fag hentGjeldendeFag(int time, int minutt, int ukedag);
bool hentInternetTid();
void helgAnimasjon();
int planIndex();
// ========== HJELPEFUNKSJONER (ferdig implementert) ==========
void debugInfo() {
  time_t now;
  struct tm timeinfo;
  time(&now);
  localtime_r(&now, &timeinfo);
  
  Serial.print("Tid: ");
  Serial.printf("%02d:%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
  Serial.print(" | Ukedag: ");
  Serial.print(timeinfo.tm_wday);
  Serial.print(" | Fag: ");
  Serial.print(gjeldendeFag);
  Serial.print(" | Sekunder igjen: ");
  Serial.println(sekunderIgjen);
}
void startupAnimasjon() {
  // Enkel oppstart-animasjon
  for(int i = 0; i < NUM_LEDS; i++) {
    strip.setPixelColor(i, strip.Color(0, 50, 100));
    strip.show();
    delay(10);
  }
  strip.clear();
  strip.show();
}
// ========== SETUP ==========
void setup() {
  Serial.begin(115200);
  Serial.println("🕐 KLOKKEPROSJEKT STARTER...");
  
  // Initialiser LED-strip
  strip.begin();
  strip.show();
  startupAnimasjon();
  
  // Koble til WiFi og hent tid
  WiFi.begin(ssid, password); // Start forbindelsen til internett
  if(hentInternetTid()) {
    Serial.println("✅ WiFi og tid OK!");
    blinkLED(strip.Color(0, 255, 0), 2); // Grønn = success
  } else {
    Serial.println("❌ WiFi eller tid feilet!");
    blinkLED(strip.Color(255, 0, 0), 2); // Rød = feil
  }
  
  // Lag timeplan
  fyllPlan();
  Serial.println("📅 Timeplan lastet!");
  
  Serial.println("🚀 Klokke klar!");
}
// ========== HOVEDLOOP ==========
void loop() {
  // Hent gjeldende tid
  time_t now;
  struct tm timeinfo;
  time(&now);
  localtime_r(&now, &timeinfo);
  if (Serial.available()) {
    String input = Serial.readStringUntil('\n'); // Leser til linjeskift
    input.trim(); // Fjerner mellomrom og linjeskift
    if (input == "meny") {
      visMeny();
    }
  }
  
  // Sjekk om det er helg
  if(sjekkHelg(timeinfo.tm_wday)) {
    if(!erHelg) {
      erHelg = true;
      Serial.println("🎉 DET ER HELG!");
    }
    helgAnimasjon();
    delay(1000);
  } 
  else {
    erHelg = false;
  }
  
  // Beregn gjeldende fag og tid igjen
  Fag nyttFag = hentGjeldendeFag(timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_wday);
  sekunderIgjen = beregnTidIgjen(timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, timeinfo.tm_wday);
  
  // Sjekk om vi har byttet aktivitet
  if(nyttFag != forrigeFag) {
    Serial.println("🔄 NY AKTIVITET!");
    
    if(nyttFag == INGENTING) {
      ferdigForDagen = true;
      Serial.println("🏠 Ferdig for dagen!");
      
      // Sjekk om det er siste time på fredag (helgesluttanimasjon)
      if(timeinfo.tm_wday == FREDAG && forrigeFag != INGENTING) {
        helgeSluttAnimasjon();
      }
    } else if(nyttFag == FRIMINUTT) {
      nyttFriminutt = true;
      spillMelodi(1); // Friminutt-melodi
      Serial.println("☕ FRIMINUTT!");
    } else {
      nyTime = true;
      spillMelodi(2); // Time-melodi
      Serial.println("📚 NY TIME!");
    }
    
    forrigeFag = nyttFag;
  }
  
  gjeldendeFag = nyttFag;
  
  // Vis status på LED-ring
  strip.clear();
  
  if(ferdigForDagen) {
    // Vis "ferdig for dagen" animasjon
    ferdigForDagenAnimasjon();
    ferdigForDagen = false;
  } else if(nyttFriminutt) {
    // Vis friminutt-animasjon
    friminuttAnimasjon();
    nyttFriminutt = false;
  } else if(nyTime) {
    // Vis time-start animasjon
    timeStartAnimasjon();
    nyTime = false;
  } else {
    // Normal visning: nedtelling-bue + klokkevisere
    nedtellingBar(timeinfo.tm_min, sekunderIgjen, fagFarge(gjeldendeFag), timeinfo.tm_hour, timeinfo.tm_wday); // Vis gjenværende tid som bue
    visKlokkevisere(timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
  }
  
  strip.show();
  
  // Debug info hver 5. sekund
  static unsigned long lastDebug = 0;
  if(millis() - lastDebug > 5000) {
    debugInfo();
    lastDebug = millis();
  }
  
  delay(1000); // Oppdater hvert sekund
}
// ========== FUNKSJONSIMPLEMENTASJONER ==========
// ELEVENE MÅ IMPLEMENTERE DISSE FUNKSJONENE:
/* ERSTATTET AV NY OG KORTERE VERSJON
bool sjekkHelg(int ukedag) { 
//Laget av Filip Utsola & Erik Øverland
  if (ukedag == 0 || ukedag == 6){ 
    //Serial.println("Det er helg"); // Kommentert ut av Ingve
    return(true); 
  } 
  else{ 
    //Serial.print("DEt er ikke helg"); // Kommentert ut av Ingve
    return(false); 
  } 
} 
*/
bool sjekkHelg(int ukedag) {
  // laget av Brage/Copilot
  return (ukedag == 0 || ukedag == 6);
}
void visMeny() {
  // Viser menyen
  Serial.println("=== Dagens meny ===");
  Serial.println("1: Menyalternativ1");
  Serial.println("2: Menyalternativ2");
  Serial.println("3: Menyalternativ3");
  Serial.println("4: Menyalternativ4");
  Serial.println("5: Menyalternativ5");
  Serial.println("Velg et alternativ (1-5):");
  // Venter på brukerinput
  while (!Serial.available()) {
    delay(200); // Kort forsinkelse for å unngå å overbelaste CPU
  }
  // Leser og trimmer inndata
  String input = Serial.readStringUntil('\n');
  input.trim(); // Fjerner mellomrom og linjeskift
  // Viser mottatt input for debugging
  Serial.print("Valgt alternativ: ");
  Serial.println(input);
  // Konverterer input til et tall for switch-case
  int valg = input.toInt(); // Konverterer streng til heltall
  // Håndterer menyvalg med switch-case
  switch (valg) {
    case 1:
      Serial.println("Kjører alternativ1");
      ferdigForDagenAnimasjon();
      break;
    case 2:
      Serial.println("Kjører alternativ2");
      break;
    case 3:
      Serial.println("Kjører blinkLED()...");
      break;
    case 4:
      Serial.println("Viser menyen igjen...");
      break;
    case 5:
      Serial.println("Utfører plassholderhandling...");
      // Eksempel på plassholderhandling
      Serial.println("Dette er en test av alternativ 5!");
      break;
    default:
      Serial.println("Ugyldig valg! Vennligst velg et tall mellom 1 og 5.");
      visMeny(); // Viser menyen igjen ved ugyldig valg
      break;
  }
}
uint32_t fagFarge(Fag fag) {
//Laget av Gabriela
  switch (fag){
    case (0):  //ingenting
      return(strip.Color(0,0,0));
      break;
    case(1): //Friminutt
      return(strip.Color(250,0,250));
      break;
    case(2): //Elkretser
      return(strip.Color(0,0,205));
      break;
    case(3): //ElEnergi
      return(strip.Color(0,77,204));
      break;
    case(4): //Styresys
      return(strip.Color(102,205,170));
      break;    
    case(5):
      return(strip.Color(188,143,143));
      break;
    case(6):
      return(strip.Color(60,179,113));
      break;
    case(7):
      return(strip.Color(100,0,0));
      break;
    case(8):
      return(strip.Color(0,100,0));
      break;
    case(9):
      return(strip.Color(255,165,0));
      break;
    default:
      return(strip.Color(0,0,0));
      break;
  }
}
/* //Alternativ fagFarge() (Mulig den skulle hatt en default?)
uint32_t fagFarge(Fag fag) {
//Laget av Brage
  switch (fag) {
    case INGENTING:   return strip.Color(0, 0, 0);          // Svart (av)
    case FRIMINUTT:   return strip.Color(18, 219, 2);        // Grønn
    case ELKRETSER:   return strip.Color(255, 195, 51);    // Gul
    case ELENERGI:    return strip.Color(140, 237, 80);      // Lys grønn
    case STYRESYS:    return strip.Color(138, 43, 226);     // Lilla
    case NORSK:       return strip.Color(62, 146, 255);        // lys blå
    case ENGELSK:     return strip.Color(0, 0, 255);     // blå
    case MATTE:       return strip.Color(232, 0, 0);        // rød
    case NATURFAG:    return strip.Color(216, 23, 255);    // Lilla
    case GYM:         return strip.Color(255, 165, 0);      // Oransje
  }
}
*/
void blinkLED(uint32_t farge, int antallBlink) {
//Laget av Stefan
  for (int i = 0; i < antallBlink; i++) {
    strip.fill(farge);
    strip.show();
    delay(200);
    strip.clear();
    strip.show();
    delay(200);
  }
}
void buzzerBlinkLED(uint32_t farge , int antallBlink,int time_to_turn_on_ms,int time_to_turn_off_ms,int amounton,int amountoff,int hertzon,int hertzoff) {
  //LAGET AV LINUS
  strip.clear();
  strip.show();
  int availableLEDS[NUM_LEDS];
  for(int i = 0; i < NUM_LEDS; i++){
    availableLEDS[i] = i;
  }
  int x = 0;
  for(int b = 0; b < antallBlink ; b++)
  {
    for(int i = 0; i < NUM_LEDS; i++){availableLEDS[i] = i;}
    for(int i = 0; i < NUM_LEDS;i++){
      x = random(0,NUM_LEDS -i);
      strip.setPixelColor(availableLEDS[x],farge);
      if((i+1)%amounton == 0 ){strip.show();tone(soundpin,hertzon,40);delay(time_to_turn_on_ms);}
      Serial.print("Turning on led: ");
      Serial.println(availableLEDS[x]);
      for(int r = x; r < NUM_LEDS -i-1; r++){availableLEDS[r] = availableLEDS[r+1];}// tar den brukte LED i slutten av listen
      Serial.print("last list element: ");
      Serial.println(availableLEDS[NUM_LEDS-i-1]);
    }
    strip.show();
    for(int i = 0; i < NUM_LEDS; i++){availableLEDS[i] = i;}// nullstiller listen
    for(int i = 0; i < NUM_LEDS;i++){
        x = random(0,NUM_LEDS-i);
        strip.setPixelColor(availableLEDS[x],strip.Color(0,0,0));
        if((i+1)%amountoff == 0 ){strip.show();tone(soundpin,hertzoff,20);delay(time_to_turn_off_ms);}
        Serial.print("Turning off led: ");
        Serial.println(availableLEDS[x]);
        for(int r = x; r < NUM_LEDS -i-1 ; r++){availableLEDS[r] = availableLEDS[r+1];}
        Serial.print("last list element: ");
        Serial.println(availableLEDS[NUM_LEDS -i-1]);
      }
      strip.show();
  }  
}
void timeStartAnimasjon() {
  // TODO: Implementer denne funksjonen
  // Vis en kort animasjon når en ny time starter (Maks 5 sekunder)
  
  // TIPS til implementering:
  // - Enkel og kort animasjon som signaliserer ny time
  // - Bruk fagFarge(gjeldendeFag) for å vise riktig farge
  // - Eksempel: Puls-effekt, spiraleffekt, eller "countdown" fra sentrum
  // - Kan kombinere med spillMelodi() for ekstra effekt
  // - Hold deg under 5 sekunder total tid!
  
  // Placeholder - implementer en kul time-start animasjon!
}
void friminuttAnimasjon() {
  // TODO: Implementer denne funksjonen
  // Vis en kort animasjon når friminutt starter (Maks 5 sekunder)
  
  // TIPS til implementering:
  // - Glad og energisk animasjon som signaliserer pause
  // - Bruk gjerne grønne farger (friminutt = grønn)
  // - Eksempel: Sprettende "ball", regnbue-flash, eller tilfeldige blitz
  // - Kan kombinere med spillMelodi() for ekstra effekt
  // - Hold deg under 5 sekunder total tid!
  
  // Placeholder - implementer en glad friminutt-animasjon!
}
void visKlokkevisere(int time, int minutt, int sec) {
    // Laget av Robert og Linus
  int t_min = time%12 * 60;
  int sec_pix = ((sec*(NUM_LEDS-1))/59);
  int min_pix = ((minutt*(NUM_LEDS-1))/59);
  int time_pix = ((t_min + minutt) * NUM_LEDS)/720;
  //strip.setPixelColor(0, strip.Color(0,255,0));
  strip.setPixelColor(sec_pix, strip.Color(0 ,0 ,255));
  strip.setPixelColor(min_pix, strip.Color(255, 0 ,0));
  strip.setPixelColor(time_pix, strip.Color(0, 255, 0));
  strip.show();
}
void nedtellingBar(int minutt, int sekunderIgjen, uint32_t fagfarge, int time, int day) {
  strip.clear();
  int index = planIndex(time, minutt, day);
  if(index == -1){return;}
  int grimsarbo = plan[index].startMinutt;
  int klippoxel = plan[index].varighet;
  int slutt_time = map((grimsarbo+klippoxel)*60, 0, 3600, 0, NUM_LEDS);
  int start_pix = map((grimsarbo+klippoxel)*60 - sekunderIgjen, 0, 3600, 0, NUM_LEDS);
  for(int inxex_pix=0 ;inxex_pix + start_pix < slutt_time && inxex_pix < 60; inxex_pix ++){
    strip.setPixelColor((start_pix + inxex_pix) % NUM_LEDS, fagfarge);
  }
}
void spillMelodi(int melodi) {
  // TODO: Implementer denne funksjonen
  // Input: melodi-nummer (1=friminutt, 2=time, etc.)
  // Spill en melodi (kan være tom implementasjon hvis ingen buzzer)
  
  // TIPS til implementering - ALTERNATIV 1 (med buzzer):
  // - Definer BUZZER_PIN og bruk tone(pin, frekvens, varighet)
  // - Friminutt: Glad melodi (høye toner)
  // - Time: Nøytral tone (middels toner)
  //
  // TIPS til implementering - ALTERNATIV 2 (uten buzzer):
  // - Bruk LED-signaler i stedet for lyd
  // - Friminutt: blinkLED(strip.Color(0, 255, 0), 3) // Grønn
  // - Time: blinkLED(strip.Color(255, 0, 0), 2) // Rød
  // - Lag forskjellige blinkmønstre for hver melodi
  
  // Placeholder - velg alternativ og implementer!
}
void ferdigForDagenAnimasjon() {
  // Laget av Heine
  // Bruker variabelen “fade” for å få lysstrken fra 0 til 255
  for (int fade = 0; fade < 256; fade += 5) {
    // Brukte litt AI for å finne komboen til å lage oransje
    uint32_t farge = strip.Color(fade, fade / 2, 0);
    // fyller hele sirkelen med den utvalgte fargen
    strip.fill(farge); 
    // Oppdater stripen for å vise fargen
    strip.show();
    // venter 50 ms får å gi det en mer “smooth” (kommer ikke på en norsk ord) overgang
    delay(50);
  }
  // Venter ett sekund med fullt lys på
  delay(1000);
  // Fader lysstyrken ned fra255 til 0 gjennom å gå ned 5 per steg :)
  for (int fade = 255; fade >= 0; fade -= 5) {
    uint32_t farge = strip.Color(fade, fade / 2, 0);
    strip.fill(farge);
    strip.show();
    delay(50);
  }
  // Slår alstå av alle LED-lysene på stripen
  strip.clear();
  strip.show();
}
void helgeSluttAnimasjon() {
  // TODO: Implementer denne funksjonen
  // Vis en spektakulær animasjon når siste time på fredag er ferdig (Maks 30 sekunder)
  
  // TIPS til implementering:
  // - Dette er den store celebrasjonen - vær kreativ og spektakulær!
  // - Kombiner flere effekter: fyrverkeri, regnbuer, puls, rotasjoner
  // - Bruk alle 30 sekunder for en episk opplevelse
  // - Start rolig og bygg opp til klimaks
  // - Eksempel: Fyrverkeri → regnbue → feiring → rolig slutt
  // - Bruk math-funksjoner for smooth overganger
  // - Dette er eleven sin sjanse til å virkelig skinne!
  
  // Placeholder - implementer en episk helgesluttanimasjon!
}
void fyllPlan() {
  // MERK: Det er OK å ha hull i listen! Vi bruker forskjellige indekser for hver dag.
  
  // Mandag (0-9)
  plan[0] = {MANDAG, 10, 0, 90, STYRESYS};
  plan[1] = {MANDAG, 11, 30, 30, FRIMINUTT};
  plan[2] = {MANDAG, 12, 0, 45, STYRESYS};
  plan[3] = {MANDAG, 12, 45, 45, ENGELSK};
  plan[4] = {MANDAG, 13, 30, 10, FRIMINUTT};
  plan[5] = {MANDAG, 13, 40, 90, ENGELSK};
  // Tirsdag (10-19)
  plan[10] = {TIRSDAG, 8, 10, 90, ENGELSK};
  plan[11] = {TIRSDAG, 9, 40, 20, FRIMINUTT};
  plan[12] = {TIRSDAG, 10, 0, 90, MATTE};
  plan[13] = {TIRSDAG, 11, 30, 30, FRIMINUTT};
  plan[14] = {TIRSDAG, 12, 0, 90, NORSK};
  plan[15] = {TIRSDAG, 13, 30, 10, FRIMINUTT};
  plan[16] = {TIRSDAG, 13, 40, 90, STYRESYS};
  // Onsdag (20-29) - MERK: Fikset feil dag fra FREDAG til ONSDAG
  plan[20] = {ONSDAG, 8, 10, 90, STYRESYS};
  plan[21] = {ONSDAG, 9, 40, 20, FRIMINUTT};
  plan[22] = {ONSDAG, 10, 0, 90, STYRESYS};
  plan[23] = {ONSDAG, 11, 30, 30, FRIMINUTT};
  plan[24] = {ONSDAG, 12, 0, 45, STYRESYS};
  // Torsdag (30-39)
  plan[30] = {TORSDAG, 8, 10, 90, NORSK};
  plan[31] = {TORSDAG, 9, 40, 20, FRIMINUTT};
  plan[32] = {TORSDAG, 10, 00, 90, ELKRETSER};
  plan[33] = {TORSDAG, 11, 30, 30, FRIMINUTT};
  plan[34] = {TORSDAG, 12, 0, 90, GYM};
  plan[35] = {TORSDAG, 13, 30, 10, FRIMINUTT};
  plan[36] = {TORSDAG, 13, 40, 90, STYRESYS};
  // Fredag (40-49)
  plan[40] = {FREDAG, 8, 10, 90, NATURFAG};
  plan[41] = {FREDAG, 9, 40, 20, FRIMINUTT};
  plan[42] = {FREDAG, 10, 0, 90, MATTE};
  plan[43] = {FREDAG, 11, 30, 30, FRIMINUTT};
  plan[44] = {FREDAG, 12, 0, 45, MATTE};
  plan[45] = {FREDAG, 12, 45, 90, STYRESYS};
  plan[46] = {FREDAG, 13, 30, 10, FRIMINUTT};
  plan[47] = {FREDAG, 13, 40, 90, STYRESYS};
  
  // antallTimer er nå 48 (høyeste index + 1)
}
Fag hentGjeldendeFag(int time, int minutt, int ukedag) {
  // Laget av Robert
  int index = planIndex(time, minutt, ukedag);
  if(index == -1){
    return INGENTING;
  }
  return plan[index].fag;
}
int beregnTidIgjen(int time, int minutt, int sekund, int ukedag) {
  //Laget av Robert
  int index = planIndex(time, minutt, ukedag);
  if(index == -1){return 0;}
  
  int time_S = time * 3600;
  int minutt_S = minutt * 60;
  int plan_time_s = plan[index].startTime * 3600;
  int plan_minutt_s = plan[index].startMinutt * 60;
  int plan_varighet_s = plan[index].varighet * 60;
  int planTOT_s = plan_time_s + plan_minutt_s + plan_varighet_s;
  int nåTOT_s = time_S + minutt_S + sekund;
  return planTOT_s - nåTOT_s;
}
int planIndex(int time, int minutt, int ukedag){
  //Laget av Robert
  int minutter = time*60 + minutt;
  int index = 0;
  // Finner ut hvilken dag det er
  while (ukedag != plan[index].dag){
    if (index >= 50){
      return -1;
    }
    index = index + 10;
  }
  
  // Sjekker om hvis det før skole start
  if (minutter < plan[index].startTime*60 + plan[index].startMinutt){
    return -1;
  }
  
  //Sjekker om hvis Det er etter skole tid
  else if(ukedag == 3){
    if(minutter > 765){return -1;}
  }else if(minutter > 910){return -1;}
  // Sjekker om det er innefor timens tids parameter av timen
  // Vis ikke så kjekker den neste time
  while(!(plan[index].startTime*60 + plan[index].startMinutt <= minutter && plan[index].startTime*60 + plan[index].startMinutt + plan[index].varighet > minutter)){
    index ++;
  }
  // Returne Indexen til timeen vi har akkurat nå
  return index;
}
bool hentInternetTid() {
//Laget av Robert
    // Koble til WiFi
    int attempts = 0;
    while (WiFi.status() != WL_CONNECTED && attempts < 20) {
        delay(400);
        attempts++;
    }
    if (WiFi.status() != WL_CONNECTED) {
        Serial.print("Wifi status: ");
        Serial.println(WiFi.status());
        return false;
    }
    // Sett tidssone og hent tid
    configTime(3600, 3600, "pool.ntp.org");
    delay(2000);
    time_t now;
    time(&now);
    return (now > 1000000); // Sjekk at vi fikk gyldig tid
}
void helgAnimasjon() {
  // TODO: Implementer denne funksjonen
  // Lag en kul animasjon som vises i helgene
  
  // TIPS til implementering - Vær kreativ! Dette er din sjanse til å skinne:
  // - Regnbue-effekter: Bruk forskjellige farger som roterer
  // - Bouncing balls: Simuler en ball som spretter
  // - Fade-effekter: Fade inn/ut med forskjellige farger
  // - Roterende mønstre: Roter et mønster rundt ringen
  // - Stjernehimmel: Tilfeldige LEDs som blinker som stjerner
  // - Fyrverk-effekt: Eksplosjoner av farger
  // - Bruk math-funksjoner som sin(), cos() for smooth animasjoner
  // - Kombiner forskjellige effekter!
  // - Husk: ikke bruk for lange delays (animasjonen kalles hver loop)
  
  // Placeholder - vær kreativ og implementer din egen kule animasjon!
}