/*
this version has a picker sparkle button 
and a zap button that does a colorful sparkle at the end
NO SOLENOID!
*/

#include <Adafruit_NeoPixel.h>

// --------- Pin Definitions ---------
#define SELECT_BUTTON_PIN 2  // Button to select a color & sparkle
#define EFFECT_BUTTON_PIN 3  // Button to run the pulse effect & trigger sparkles
#define NEOPIXEL_PIN      11 // Data pin for the NeoPixel strip

// --------- NeoPixel Settings ---------
#define NUM_PIXELS   180    // Full 3 m strip at 60 LEDs/m
#define TAIL_LENGTH   8     // Number of LEDs lit in the moving pulse
#define SPARK_TIME   2000   // Sparkling effect duration in ms
#define PULSE_SPEED  20     // Pulse speed

// --------- Color Options ---------
uint32_t colorOptions[] = {
  Adafruit_NeoPixel::Color(255, 0, 0),    // Red
  Adafruit_NeoPixel::Color(255, 64, 0),   // Orange
  Adafruit_NeoPixel::Color(170, 160, 0),  // Yellow
  Adafruit_NeoPixel::Color(0, 90, 0),     // Green
  Adafruit_NeoPixel::Color(0, 0, 255),    // Blue
  Adafruit_NeoPixel::Color(255, 16, 65)   // Pink
};
const int numColors = sizeof(colorOptions) / sizeof(colorOptions[0]);

Adafruit_NeoPixel strip(NUM_PIXELS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
uint32_t selectedColor;
void setup() {
  pinMode(SELECT_BUTTON_PIN, INPUT_PULLUP);
  pinMode(EFFECT_BUTTON_PIN, INPUT_PULLUP);

  strip.begin();
  strip.show(); // Turn all pixels off

  randomSeed(analogRead(A0));
  int index = random(0, numColors);
 selectedColor = colorOptions[index];
}

void loop() {
  // ----- Color Select & Sparkle Effect -----
  if (digitalRead(SELECT_BUTTON_PIN) == LOW) {
    delay(50); // debounce
    if (digitalRead(SELECT_BUTTON_PIN) == LOW) {
      int index = random(0, numColors);
      selectedColor = colorOptions[index];
      sparklingEffect(selectedColor, SPARK_TIME);

      while (digitalRead(SELECT_BUTTON_PIN) == LOW) delay(10);
      delay(100);
    }
  }

  // ----- Pulse Effect & Random Sparkles -----
  if (digitalRead(EFFECT_BUTTON_PIN) == LOW) {
    delay(50); // debounce
    if (digitalRead(EFFECT_BUTTON_PIN) == LOW) {
      pulseEffect(selectedColor);
      randomSparkEffect(SPARK_TIME);  // Sparkle effect with random colors

      while (digitalRead(EFFECT_BUTTON_PIN) == LOW) delay(10);
      delay(100);
    }
  }
}

// -----------------
// sparklingEffect()
// -----------------
// Flashes 10 random pixels in the same chosen color.
void sparklingEffect(uint32_t color, unsigned long durationMillis) {
  unsigned long startTime = millis();
  while (millis() - startTime < durationMillis) {
    strip.clear();
    for (int i = 0; i < 10; i++) {
      int pix = random(NUM_PIXELS);
      strip.setPixelColor(pix, color);
    }
    strip.show();
    delay(100);
  }
  strip.clear();
  strip.show();
}

// -----------------
// randomSparkEffect()
// -----------------
// Similar to sparklingEffect, but each spark is a random color.
void randomSparkEffect(unsigned long durationMillis) {
  unsigned long startTime = millis();
  while (millis() - startTime < durationMillis) {
    strip.clear();
    for (int i = 0; i < 10; i++) {
      int pix = random(NUM_PIXELS);
      uint32_t randColor = colorOptions[random(0, numColors)]; // Pick a random color
      strip.setPixelColor(pix, randColor);
    }
    strip.show();
    delay(100);
  }
  strip.clear();
  strip.show();
}

// -----------------
// pulseEffect()
// -----------------
// Creates a moving “pulse” with a fading tail.
void pulseEffect(uint32_t color) {
  for (int i = NUM_PIXELS + TAIL_LENGTH - 1; i >= 0; i--) {
    strip.clear();
    for (int j = 0; j < TAIL_LENGTH; j++) {
      int pixelIndex = i + j;
      if (pixelIndex >= 0 && pixelIndex < NUM_PIXELS) {
        uint8_t brightness = 255 - (j * (255 / TAIL_LENGTH));
        uint8_t r = (color >> 16) & 0xFF;
        uint8_t g = (color >> 8) & 0xFF;
        uint8_t b = color & 0xFF;
        r = (uint8_t)(((uint16_t)r * brightness) / 255);
        g = (uint8_t)(((uint16_t)g * brightness) / 255);
        b = (uint8_t)(((uint16_t)b * brightness) / 255);
        uint32_t fadeColor = strip.Color(r, g, b);
        strip.setPixelColor(pixelIndex, fadeColor);
      }
    }
    strip.show();
    delay(PULSE_SPEED);
  }
  strip.clear();
  strip.show();
  int index = random(0, numColors);
  selectedColor = colorOptions[index];

}
NOCOMNCVCCGNDINLED1PWRRelay Module