void glow (byte mins, byte maxs, byte dsat) {
  if (dir_sat == 1) {
    sat += dsat;
    if (sat + dsat >= maxs) {
      dir_sat = -1;
      return;
    }
  }
  if (dir_sat == -1) {
    sat -= dsat;
    if (sat - dsat < mins) {
      dir_sat = 1;
    }
  }
}

void fill_rainbow_unsat( struct CRGB * pFirstLED, int numToFill,
                         uint8_t initialhue,
                         uint8_t deltahue )
{
  CHSV hsv;
  hsv.hue = initialhue;
  hsv.val = 255;
  hsv.sat = 190;
  for ( int i = 0; i < numToFill; i++) {
    pFirstLED[i] = hsv;
    hsv.hue += deltahue;
  }
}

void fill_fond ()
{
  if (millis() - TlastFond >= 50) {
    TlastFond = millis();
    fondHue += 2;
    if (DEBUG) Serial << "Hue = " << fondHue << endl ;
    fill_solid(leds, NUM_LEDS, CHSV(fondHue, 120, 255));
  }
}

void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
  uint8_t brightness = 100;
  for ( int i = 0; i < NUM_LEDS; i++) {
    leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness);
    colorIndex += 3;
  }
}

void PaletteSelect ()
{
  // Choix de la palette pour animation RANDOM_PAL
  switch (numero_pal) {
    case 1 :
      currentPalette = RainbowColors_p;
      currentBlending = LINEARBLEND;
      break;
    case 2 :
      currentPalette = Pal2_p;
      currentBlending = LINEARBLEND;
      break;
    case 3 :
      currentPalette = Pal3_p;
      currentBlending = LINEARBLEND;
      break;
    case 4 :
      currentPalette = Pal4_p;
      currentBlending = LINEARBLEND;
      break;
    default :
      break;
  }
}

void GestionAnimations ()
{
  TlastAnim += periode_anim;
  //if (DEBUG) Serial << "Numéro anim " << anim << endl ;
  switch (anim) {
    case NO_ANIM :
      if (fond) fill_fond();
      break;

    case COLOR_PULSE : // pulse couleurs
      glow(30, 150, 10);
      periode_anim = 50;
      FastLED.clear ();
      if (numero_hue == 0) {
        fill_solid( leds, NUM_LEDS, CHSV(255, 0, sat));
      }
      else
      {
        fill_solid( leds, NUM_LEDS, CHSV(numero_hue, 255, sat));
      }
      break;

    case MOVING_RAINBOW : // Arc en ciel mobile
      FastLED.clear ();
      periode_anim = 30; //50;
      initialHue += 2;
      fill_rainbow_unsat (leds, NUM_LEDS, initialHue, changeInHue);
      break;

    case COLOR_BAND :  // Bande blanche mobile (1 tour par seconde)
      if (fond)  {
        fill_fond();
      }
      else {
        FastLED.clear ();
      }
      periode_anim = int(1000 / NUM_LEDS);
      if (numero_hue == 0) {
        couleur = CRGB::White;
        couleur1 = CRGB::LightGrey;
      }
      else {
        couleur = CHSV(numero_hue, 255, 255);
        couleur1 = CHSV(numero_hue, 255, 150);
      }
      leds[(pos_bande - 1) % NUM_LEDS] = couleur1;
      leds[(pos_bande + 1) % NUM_LEDS] = couleur1;
      leds[pos_bande] = couleur;
      pos_bande = (pos_bande + 1) % NUM_LEDS;
      break;

    case COLOR_BAND_AR : // Bande blanche A/R
      if (fond)  {
        fill_fond();
      }
      else {
        FastLED.clear ();
      }
      periode_anim = int(1000 / NUM_LEDS);
      if (numero_hue == 0) {
        couleur = CRGB::White;
        couleur1 = CRGB::LightGrey;
      }
      else {
        couleur = CHSV(numero_hue, 255, 255);
        couleur1 = CHSV(numero_hue, 255, 150);
      }
      leds[(pos_bande - 1) % NUM_LEDS] = couleur1;
      leds[(pos_bande + 1) % NUM_LEDS] = couleur1;
      leds[pos_bande] = couleur;
      if (pos_bande + dir_bande == num_secondes) {
        dir_bande = - dir_bande;
      }
      pos_bande = (pos_bande + dir_bande) % NUM_LEDS;
      if (pos_bande == -1) {
        pos_bande = NUM_LEDS - 1;
      }
      break;

    case RANDOM_PAL :  // Couleurs palette saturation aléatoire
      periode_anim = 200;
      FillLEDsFromPaletteColors(0);
      for (int i = 0; i < NUM_LEDS; i++) {
        byte n = random(30, 180);
        leds[i] %= n;
      }
      break;

    case GLOWING_SEC :  // secondes qui grossissent et diminuent
      if (fond)  {
        fill_fond();
      }
      else {
        FastLED.clear ();
      }
      periode_anim = 53;
      glow(30, 255, 23);
      break;

    case BBR : // Balayage drapeau, choisi avec palette
      if (fond)  {
        fill_fond();
      }
      else {
        FastLED.clear ();
      }
      periode_anim = 100;
      if (numero_pal == 0) {
        // Drapeau Français
        couleurA = CRGB::RoyalBlue ;
        couleurB = CRGB::White ;
        couleurC = CRGB::Red ;
      } else if (numero_pal == 1) {
        // Drapeau Italien
        couleurA = CRGB::Green ;
        couleurB = CRGB::White ;
        couleurC = CRGB::Red ;
      } else if (numero_pal == 2) {
        // Drapeau Bulgare
        couleurA = CRGB::White ;
        couleurB = CRGB::Green ;
        couleurC = CRGB::Red ;
      } else if (numero_pal == 3) {
        // Drapeau Irlandais
        couleurA = CRGB::Green ;
        couleurB = CRGB::White ;
        couleurC = CRGB::Orange ;
      } else if (numero_pal == 4) {
        // Drapeau Roumain
        couleurA = CRGB::RoyalBlue ;
        couleurB = CRGB::Yellow ;
        couleurC = CRGB::OrangeRed ;
      }
      if (sens_horaire) {
        leds[(pos_bande) % NUM_LEDS] = couleurA ;
        leds[(pos_bande + 1) % NUM_LEDS] = couleurA ;
        leds[(pos_bande + 2) % NUM_LEDS] = couleurB ;
        leds[(pos_bande + 3) % NUM_LEDS] = couleurB ;
        leds[(pos_bande + 4) % NUM_LEDS] = couleurC ;
        leds[(pos_bande + 5) % NUM_LEDS] = couleurC ;
      } else {
        leds[(pos_bande) % NUM_LEDS] = couleurC ;
        leds[(pos_bande + 1) % NUM_LEDS] = couleurC ;
        leds[(pos_bande + 2) % NUM_LEDS] = couleurB ;
        leds[(pos_bande + 3) % NUM_LEDS] = couleurB ;
        leds[(pos_bande + 4) % NUM_LEDS] = couleurA ;
        leds[(pos_bande + 5) % NUM_LEDS] = couleurA ;
      }
      pos_bande = (pos_bande + 1) % NUM_LEDS;
      break;

    default :
      if (DEBUG) Serial << "Problème animation " << endl ;
      break;
  }
  change = true;
}

