// Board : RP2040
#include <Adafruit_NeoPixel.h>
// Which pin is connected to the NeoPixels?
#define LED_PIN 2
// How many NeoPixels are attached?
#define LED_COUNT 20
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
#define SW1 10
#define SW2 11
// Define your color palette (RGB format)
uint32_t colors[] = {
  strip.Color(255, 0, 0),      // 1 - Red
  strip.Color(0, 255, 0),      // 2 - Green
  strip.Color(0, 0, 255),      // 3 - Blue
  strip.Color(255, 255, 0),    // 4 - Yellow
  strip.Color(255, 0, 255),    // 5 - Magenta
  strip.Color(0, 255, 255),    // 6 - Cyan
  strip.Color(255, 255, 255),  // 7 - White
  strip.Color(128, 0, 128),    // 8 - Purple
  strip.Color(255, 165, 0),    // 9 - Orange
  strip.Color(0, 0, 0)         // 10 - Off/Black
};
// Function to get color by index (1-based)
uint32_t setcolor(uint8_t index) {
  index = constrain(index, 1, sizeof(colors) / sizeof(colors[0]));  // Clamp to valid range
  return colors[index-1];
}
int mode = 0;
int num = 1;
uint32_t colour;
void setup() {
  Serial.begin(115200);
  strip.begin();            // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();             // Turn OFF all pixels ASAP
  strip.setBrightness(255);  // Set BRIGHTNESS to about 1/5 (max = 255)
  pinMode(SW1, INPUT_PULLUP);
  pinMode(SW2, INPUT_PULLUP);
  colour = setcolor(num);  // default color
}
void loop() {
  // switch modes
  if (!digitalRead(SW2)) {
    mode++;
    if (mode > 3) mode = 0;
    Serial.print("Mode : ");
    Serial.println(mode);
    delay(250);
  }
  // switch colors
  if (!digitalRead(SW1)) {
    if (mode != 0 && mode != 1) {
      num++;
      if (num > 10) num = 0;
      colour = setcolor(num);
      Serial.print("Color : ");
      Serial.println(num);
      delay(250);
    }
  }
  // off
  if (mode == 0) {
    strip.clear();
    strip.show();
  }
  // rainbow mode
  if (mode == 1) {
    rainbow(10);
  }
  // flashing mode
  if (mode == 2) {
    theaterChase(colour, 50);
  }
  // solid mode
  if (mode == 3) {
    for (int i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, colour);
    }
    strip.show();
    delay(250);
  }
}
// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow(int wait) {
  for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; firstPixelHue += 256) {
    strip.rainbow(firstPixelHue);
    strip.show();  // Update strip with new contents
    delay(wait);   // Pause for a moment
    if (!digitalRead(SW1) || !digitalRead(SW2)) break;
  }
}
void theaterChase(uint32_t color, int wait) {
    for (int b = 0; b < 3; b++) {  //  'b' counts from 0 to 2...
      strip.clear();               //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for (int c = b; c < strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color);  // Set pixel 'c' to value 'color'
      }
      strip.show();  // Update strip with new contents
      delay(wait);   // Pause for a moment
      if (!digitalRead(SW1) || !digitalRead(SW2)) break;
    }
}