//source: https://editor.soulmatelights.com/gallery/1435-lumanjer-test

#include "FastLED.h"
#define DATA_PIN 2
#define BRIGHTNESS 255
#define NUM_LEDS 256
#define LED_COLS 16
#define LED_ROWS 16
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
//#define FRAMES_PER_SECOND 60
const uint8_t kMatrixWidth = 16;
const uint8_t kMatrixHeight = 16;

const bool    kMatrixSerpentineLayout = false;

const byte updateFromRGBWeight = 64;
const byte scaleToNumLeds = ceil((float)NUM_LEDS /128);

uint16_t RGBweight(uint16_t idx) {
  return (leds[idx].r + leds[idx].g + leds[idx].b);
}
uint8_t x, y, hue, sat, step;
int8_t dx = -1, dy = -1;

void setup() {
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS); //setCorrection(TypicalLEDStrip);
  //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);
 //Serial.begin(115200);
}

void loop() 
{
  if (step%2 == 0) {
    //blur2d(leds, LED_COLS, LED_ROWS, 8);
    fadeToBlackBy(leds, NUM_LEDS, 16);
  for (uint8_t i = 0; i< scaleToNumLeds; i++) {
    uint8_t retry = 0;
    do {
      dx = random(2) ? -1: 1;
      dy = random(2) ? -1: 1;
      retry++;
      if (retry == 20) {
        x =  random(0, LED_COLS);
        //y = random(0, LED_ROWS);
        sat = random(256);
        break;
      }
    } while (RGBweight(XY((LED_COLS + x + dx) % LED_COLS,(LED_ROWS + y + dy) % LED_ROWS)) > updateFromRGBWeight);
    x = (LED_COLS + x + dx) % LED_COLS;
    y = (LED_ROWS + y + dy) % LED_ROWS;
    leds[XY(x, y)] = CHSV(hue, sat, BRIGHTNESS);
  }
  hue +=8;
  }
  step++;
  delay(16);
      FastLED.show();

}
 
uint16_t XY( uint8_t x, uint8_t y)
{
  uint16_t i;
  if( kMatrixSerpentineLayout == false) {
    i = (y * kMatrixWidth) + x;
  }
  if( kMatrixSerpentineLayout == true) {
    if( y & 0x01) {
      // Odd rows run backwards
      uint8_t reverseX = (kMatrixWidth - 1) - x;
      i = (y * kMatrixWidth) + reverseX;
    } else {
      // Even rows run forwards
      i = (y * kMatrixWidth) + x;
    }
  }
  return i;
}