#include <Adafruit_NeoPixel.h>

#define LED_PIN 2 // PIN du signal vers le LEDs
#define LED_COUNT 4 // nombre de LEDs dans le circuit

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

int i_func = 0; // ID de l'effet à jouer
const int buttonPin = 3; // PIN du bouton
int buttonState = 0;
int buttonPressed = false;

// liste des effets
typedef void (*FuncPtr)(void);
FuncPtr myFunctions[] = { &effect_rainbow, &effect_cyan, &effect_purple, &effect_blue, &effect_red, &effect_green, &effect_orange, &effect_off };

void setup() {

  Serial.begin(57600);

  pinMode(buttonPin, INPUT);

  // reset des LEDs
  strip.begin();
  strip.setPixelColor(0, 0, 0, 0);
  strip.show();

}

int m;

void loop() {
  
  buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH) {
    if (buttonPressed) {
      if (millis() >= m + 180) {
        i_func = 7;
      }
    }
    else {
      m = millis();
      buttonPressed = true; 
    }
  }
  else {
    if (buttonPressed) {
      buttonPressed = false;
      i_func++;
      
      if (i_func == 8) {
        i_func = 0;
      }
    }
  }

  // lancement de l'effet
  myFunctions[i_func]();
  
}

// OFF
void effect_off() {
  strip.setPixelColor(0, 0, 0, 0);
  strip.setPixelColor(1, 0, 0, 0);
  strip.setPixelColor(2, 0, 0, 0);
  strip.setPixelColor(3, 0, 0, 0);
  strip.show();
}

// EFFET CYAN
void effect_cyan() {
  strip.setPixelColor(0, 37, 186, 191);
  strip.setPixelColor(1, 37, 186, 191);
  strip.setPixelColor(2, 37, 186, 191);
  strip.setPixelColor(3, 37, 186, 191);
  strip.show();
}

// EFFET VIOLET
void effect_purple() {
  strip.setPixelColor(0, 209, 12, 244);
  strip.setPixelColor(1, 209, 12, 244);
  strip.setPixelColor(2, 209, 12, 244);
  strip.setPixelColor(3, 209, 12, 244);
  strip.show();
}

// EFFET BLEU
void effect_blue() {
  strip.setPixelColor(0, 0, 0, 255);
  strip.setPixelColor(1, 0, 0, 255);
  strip.setPixelColor(2, 0, 0, 255);
  strip.setPixelColor(3, 0, 0, 255);
  strip.show();
}

// EFFET ROUGE
void effect_red() {
  strip.setPixelColor(0, 255, 0, 0);
  strip.setPixelColor(1, 255, 0, 0);
  strip.setPixelColor(2, 255, 0, 0);
  strip.setPixelColor(3, 255, 0, 0);
  strip.show();
}

// EFFET VERT
void effect_green() {
  strip.setPixelColor(0, 0, 255, 0);
  strip.setPixelColor(1, 0, 255, 0);
  strip.setPixelColor(2, 0, 255, 0);
  strip.setPixelColor(3, 0, 255, 0);
  strip.show();
}

// EFFET ORANGE
void effect_orange() {
  strip.setPixelColor(0, 238, 164, 47);
  strip.setPixelColor(1, 238, 164, 47);
  strip.setPixelColor(2, 238, 164, 47);
  strip.setPixelColor(3, 238, 164, 47);
  strip.show();
}

// EFFET RAINBOW
void effect_rainbow() {
  rainbow(30);
  delay(10);
}

// UTILES POUR L'EFFET RAINBOW
void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i*1+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } 
  else if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } 
  else {
    WheelPos -= 170;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}
