#include <Adafruit_NeoPixel.h>
#define PIX_PIN 2
#define PIX_MAX 50
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIX_MAX, PIX_PIN, NEO_GRB + NEO_KHZ800);

bool j; // for 1 / 0 loops
byte cases = 4;
byte buttonPin = 3, buttonCount;
bool currentButtonState, lastButtonRead;
unsigned long timer, timeout = 50;
uint8_t delayTime = 100; // 100 for hardware 20 for Wokwi

void setup() {
  Serial.begin(9600);
  strip.begin();
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  // rgb();
  readButton();
  switch (buttonCount) {
    case (0): bounce(); break;
    case (1): red_wht_blu(); break;
    case (2): red_pnk_gry(); break;
    case (3): cyn_org(); break;
  }
}

void bounce() {
  j = !j;
  for (int i = 0; i < PIX_MAX; i++) {
    if (i == 0 || i == PIX_MAX) {
      strip.setPixelColor(i, strip.Color(255, 255, 255));
      strip.show();
      delay(10);
      strip.setPixelColor(i, strip.Color(0, 0, 0));
      strip.show();
    }
    if (j)
      strip.setPixelColor(i, strip.Color(0, 0, 255));
    else
      strip.setPixelColor(PIX_MAX - i, strip.Color(0, 0, 255));
    strip.show();
    delay(25);
    if (j)
      strip.setPixelColor(i, strip.Color(0, 0, 0));
    else
      strip.setPixelColor(PIX_MAX - i, strip.Color(0, 0, 0));
    strip.show();
  }
}

void red_wht_blu() {
  theaterChase(strip.Color(255, 255, 255), delayTime);  // WHT
  theaterChase(strip.Color(000, 000, 255), delayTime);  // BLU
  theaterChase(strip.Color(255, 000, 000), delayTime);  // RED
}

void red_pnk_gry() {
  theaterChase(strip.Color(127, 127, 127), delayTime);  // WHT (dim)
  theaterChase(strip.Color(255, 031, 127), delayTime);  // PNK
  theaterChase(strip.Color(255, 000, 000), delayTime);  // RED
}

void cyn_org() {
  theaterChase(strip.Color(0, 127, 127), delayTime);  // CYN
  theaterChase(strip.Color(255, 0, 63), delayTime);   // ORG
}

void theaterChase(uint32_t color, uint8_t wait) { // crawling lights with spacing
  for (int q = 0; q < 10; q++) {  // first pixel to first pixel
    for (int i = 0; i < strip.numPixels(); i = i + 10) {
      for (int j = 0; j < 6; j++) { // number or lit pixels
        strip.setPixelColor(q + i + j, color);
        if (q > 5)
          strip.setPixelColor(q - 6, color); // fill in first pixels
      }
    }
    strip.show();
    delay(delayTime);

    // set  all leds off to clear the strip, do not show() or delay()
    for (int i = 0; i < strip.numPixels(); i = i + 1) {
      strip.setPixelColor(q + i, 0);
    }
  }
}

void readButton() {
  bool currentButtonRead = digitalRead(buttonPin);             // read button pin

  if (currentButtonRead != lastButtonRead) {                    // if button pin changes...
    timer = millis();                                           // ...start a timer
    lastButtonRead = currentButtonRead;                         // ... and store current state
  }

  if ((millis() - timer) > timeout) {                           // if button change was longer than debounce timeout
    if (currentButtonState == HIGH && lastButtonRead == LOW) {  // ... and State is "NOT pressed" while Button "IS PRESSED"
      //==================================================
      digitalWrite(LED_BUILTIN, HIGH);                          // The button was pressed...
      if (++buttonCount > cases)
        buttonCount = 0;
      Serial.print(buttonCount);
      digitalWrite(LED_BUILTIN, LOW);
      //==================================================
    }
    currentButtonState = currentButtonRead;                     // update button state
  }
}

void rgb() {
  strip.setPixelColor(0, strip.Color(255, 0, 0));
  strip.setPixelColor(1, strip.Color(0, 255, 0));
  strip.setPixelColor(2, strip.Color(0, 0, 255));
  strip.setPixelColor(PIX_MAX - 1, strip.Color(255, 0, 0));
  strip.setPixelColor(PIX_MAX - 2, strip.Color(0, 255, 0));
  strip.setPixelColor(PIX_MAX - 3, strip.Color(0, 0, 255));
  strip.show();
}
1000uF elec cap