#include <Adafruit_NeoPixel.h>

// Define pin numbers for each NeoPixel strip
#define NUM_PINS 9
#define PIXELS_PER_STRIP 8 // Number of pixels per strip

uint8_t pins[NUM_PINS] = {2, 3, 4, 5, 6, 7, 8, 9, 10}; // Pins for each strip
Adafruit_NeoPixel strips[NUM_PINS] = {
  Adafruit_NeoPixel(PIXELS_PER_STRIP, pins[0], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(PIXELS_PER_STRIP, pins[1], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(PIXELS_PER_STRIP, pins[2], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(PIXELS_PER_STRIP, pins[3], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(PIXELS_PER_STRIP, pins[4], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(PIXELS_PER_STRIP, pins[5], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(PIXELS_PER_STRIP, pins[6], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(PIXELS_PER_STRIP, pins[7], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(PIXELS_PER_STRIP, pins[8], NEO_GRB + NEO_KHZ800)
};

// Button pin
#define BUTTON_PIN 11

// Global variables
uint8_t activePins = 1;      // Number of currently active strips
bool lastButtonState = LOW;  // Last button state
uint32_t fire_color = Adafruit_NeoPixel::Color(80, 35, 0);
uint32_t off_color = Adafruit_NeoPixel::Color(0, 0, 0);

///
/// Fire animation for one strip
///
void animateFire(Adafruit_NeoPixel &strip) {
  for (int i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, fire_color);

    // Add randomness to simulate flicker
    int r = random(80);
    uint32_t diff_color = strip.Color(r, r / 2, r / 2);
    uint32_t currentColor = strip.getPixelColor(i);

    // Blend and set the pixel color
    uint8_t r1 = (currentColor >> 16) & 0xFF;
    uint8_t g1 = (currentColor >> 8) & 0xFF;
    uint8_t b1 = currentColor & 0xFF;
    uint8_t r2 = (diff_color >> 16) & 0xFF;
    uint8_t g2 = (diff_color >> 8) & 0xFF;
    uint8_t b2 = diff_color & 0xFF;

    strip.setPixelColor(i, strip.Color(
      constrain(r1 - r2, 0, 255),
      constrain(g1 - g2, 0, 255),
      constrain(b1 - b2, 0, 255)
    ));
  }
  strip.show();
}

///
/// Setup
///
void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP); // Button with pull-up resistor

  // Initialize all strips
  for (int i = 0; i < NUM_PINS; i++) {
    strips[i].begin();
    strips[i].show(); // Set all pixels to off initially
  }
}

///
/// Main loop
///
void loop() {
  // Read button state
  bool buttonState = digitalRead(BUTTON_PIN);

  // Detect button press (falling edge)
  if (buttonState == LOW && lastButtonState == HIGH) {
    activePins++;
    if (activePins > NUM_PINS) {
      activePins = 1; // Wrap around to 1 active pin
    }
  }

  lastButtonState = buttonState;

  // Clear all strips
  for (int i = 0; i < NUM_PINS; i++) {
    strips[i].clear();
    strips[i].show();
  }

  // Animate the active strips
  for (int i = 0; i < activePins; i++) {
    animateFire(strips[i]);
  }

  delay(random(50, 150)); // Flickering animation timing
}