//source: https://editor.soulmatelights.com/gallery/1726-nigger

#include "FastLED.h"
#define DATA_PIN 2
#define BRIGHTNESS 255
#define NUM_LEDS 256
#define NUM_COLS 16
#define NUM_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;

uint16_t COLS_HALF = NUM_COLS / 2;
uint16_t ROWS_HALF = NUM_ROWS / 2;
uint8_t radius = COLS_HALF * 3;
uint8_t offset = 0;

int16_t calcRadius(int16_t x, int16_t y) {
  x *= x;
  y *= y;
  int16_t radi = sqrt16(x + y);
  return radi;
}

int16_t calcDist(uint8_t x, uint8_t y, int8_t center_x, int8_t center_y) {
  int16_t a = center_y - y;
  int16_t b = center_x - x;
  int16_t dist = calcRadius(a, b);
  return dist;
}


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() 
{
  EVERY_N_MILLISECONDS(150) {
    offset += 10;
  }
  
  for (int x = 0; x < NUM_COLS; x++) {
    for (int y = 0; y < NUM_ROWS; y++) {
      int dist = calcDist(x, y, COLS_HALF, ROWS_HALF);
      
      uint8_t brightness = 0;
      brightness = map(dist, 0, radius, 255, 0);
      brightness += offset;
      brightness = sin8(brightness);
      int index = XY(x, y);
      leds[index] = CRGB(brightness, 75 * brightness, .5 * brightness);
    }
  }
      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;
}