#include <FastLED.h>

CRGB s0[29];
CRGB s1[29];
CRGB s2[29];
CRGB s3[28];
CRGB s4[29];

CRGB* leds[] = {s0, s1, s2, s3, s4,};
constexpr byte nbStrips = sizeof leds / sizeof * leds;
constexpr byte pins[nbStrips] = {2, 4, 6, 8, 10};

struct Animation {
  CRGB couleur;
  unsigned long periode;
  const byte nbLeds;
  unsigned long chrono;
  byte position;
};

Animation animation[] = {
  {CRGB::Blue,  50, sizeof s0 / sizeof * s0},
  {CRGB::Blue, 100, sizeof s1 / sizeof * s1},
  {CRGB::White, 80, sizeof s2 / sizeof * s2},
  {CRGB::Red,   60, sizeof s3 / sizeof * s3},
  {CRGB::Red,   30, sizeof s4 / sizeof * s4},
};

void france() {
  fill_solid(s0, animation[0].nbLeds, CRGB::Blue);
  fill_solid(s1, animation[1].nbLeds, CRGB::Blue);
  fill_solid(s2, animation[2].nbLeds, CRGB::White);
  fill_solid(s3, animation[3].nbLeds, CRGB::Red);
  fill_solid(s4, animation[4].nbLeds, CRGB::Red);
  FastLED.show();
}

void eteindre() {
  for (byte i = 0; i < nbStrips; i++)
    fill_solid(leds[i], animation[i].nbLeds, CRGB::Black);
  FastLED.show();
}

void preparerUnPas(const byte index) {
  fill_solid(leds[index], animation[index].nbLeds, CRGB::Black);
  for (byte i = 0; i < 4; i++)
    if (animation[index].position + i < animation[index].nbLeds)
      leds[index][animation[index].position + i] = animation[index].couleur;
  animation[index].position++;
  if (animation[index].position >= animation[index].nbLeds) animation[index].position = 0;
}

void setup() {

  // on ne fait pas de boucle for car le template attend des expressions constantes
  FastLED.addLeds<WS2812B, pins[0], GRB>(s0, sizeof s0 / sizeof * s0);
  FastLED.addLeds<WS2812B, pins[1], GRB>(s1, sizeof s1 / sizeof * s1);
  FastLED.addLeds<WS2812B, pins[2], GRB>(s2, sizeof s2 / sizeof * s2);
  FastLED.addLeds<WS2812B, pins[3], GRB>(s3, sizeof s3 / sizeof * s3);
  FastLED.addLeds<WS2812B, pins[4], GRB>(s4, sizeof s4 / sizeof * s4);

  france();
  delay(1000);
  eteindre();
  for (byte i = 0; i < nbStrips; i++) animation[i].chrono = millis();
}

void loop() {
  bool affichageRequis = false;
  for (byte i = 0; i < nbStrips; i++) {
    if (millis() - animation[i].chrono >= animation[i].periode) {
      affichageRequis = true;
      preparerUnPas(i);
      animation[i].chrono = millis();
    }
  }
  if (affichageRequis) FastLED.show();
}