#include "FastLED.h"

// Pin configurations
#define DATA_PIN    4 // Connect the data pin of the APA102c LEDs to GPIO5 (D1) of the ESP8266
#define CLOCK_PIN   3 // Connect the clock pin of the APA102c LEDs to GPIO4 (D2) of the ESP8266
#define NUM_LEDS    256 // 60 // Number of LEDs in your strip
#define BRIGHTNESS  180 // Set the brightness of the LEDs (0-255)

// LED configurations
CRGB leds[NUM_LEDS];
#define LED_TYPE    APA102
#define COLOR_ORDER BGR

// Firework configurations
#define FIREWORK_NUM_SPARKS  8
#define FIREWORK_SPEED       15
#define FIREWORK_FADE        100

void setup() {
  FastLED.addLeds<LED_TYPE, DATA_PIN, CLOCK_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
}

void loop() {
  firework();
  FastLED.show();
  FastLED.delay(30);
}

void firework() {
  // Fade out the previous state
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i].fadeToBlackBy(FIREWORK_FADE);
  }

  // Randomly generate a firework origin and color
  static int origin = random(NUM_LEDS);
  static CRGB fireworkColor = CHSV(random8(), 255, 255);

  // Generate firework sparks
  static int sparkCounter = 0;
  if (sparkCounter < FIREWORK_NUM_SPARKS) {
    int position = origin - sparkCounter;
    if (position >= 0) {
      leds[position] += fireworkColor;
    }

    position = origin + sparkCounter;
    if (position < NUM_LEDS) {
      leds[position] += fireworkColor;
    }
    sparkCounter++;
  } else {
    // Reset the spark counter and generate a new firework
    sparkCounter = 0;
    origin = random(NUM_LEDS);
    fireworkColor = CHSV(random8(), 255, 255);
  }

  // Update the firework position
  sparkCounter += FIREWORK_SPEED;
}