#include <FastLED.h>

#define LED_PIN     3
#define NUM_LEDS    24
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB

CRGB leds[NUM_LEDS];
const uint8_t led_count[] = {24, 0, 0};
// const uint8_t led_count[] = {24, 0, 0, 0, 0, 0};
// const uint8_t led_count[] = {24, 0, 0, 0, 0, 0, 0};

#define NUM_RINGS (sizeof(led_count) / sizeof(led_count[0]))
#define FIRE_WIDTH 24
#define FIRE_HEIGHT NUM_RINGS
static uint8_t heat[FIRE_WIDTH][FIRE_HEIGHT];

void setup() {
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
}


void loop() {
  static uint8_t flash = 0;
  if (random(750) == 0)
    flash = 120;
  Fire2012(qadd8(random8() / 2 + 90, flash));
  flash = qsub8(flash, 1);


  CRGB *led = leds;
  uint8_t ring = NUM_RINGS - 1;
  // map the modified Fire2012() onto the ring
  for (uint8_t i = 0; i < 24 ; i++) {
    uint8_t h = heat[i][ring];
    *led++ = HeatColor(qadd8(h, flash));
  }

  FastLED.show();
}

void Fire2012(uint8_t activity) {
  for (uint8_t h = 0; h < FIRE_WIDTH; h++) {
    // Step 1.  Cool down every cell a little
    for( uint8_t i = 0; i < FIRE_HEIGHT; i++) {
      heat[h][i] = qsub8( heat[h][i],  random8(27));
    }

    // Step 2.  Heat from each cell drifts 'up' and diffuses a little
    for( uint8_t k = FIRE_HEIGHT - 1; k >= 1; k--) {
      uint8_t hleft = (h + FIRE_WIDTH - 1) % FIRE_WIDTH;
      uint8_t hright = (h+1) % FIRE_WIDTH;
      heat[h][k] = (heat[h][k]
                  + heat[hleft][k - 1]
                  + heat[h][k - 1]
                  + heat[hright][k - 1] ) / 4;
    }

    if( random8() < activity ) {
      heat[h][0] = qadd8( heat[h][0], random8(42));
    }

  }
}