// source: https://editor.soulmatelights.com/gallery/895-splendida-rgb-caleidoscope4

#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;

#define NUM_LEDS_FIB_STRIP 256

const uint16_t Fibon_Strip[] PROGMEM = {
0, 98, 195, 49, 146, 243, 74, 171, 24, 122,
219, 50, 147, 244, 97, 194, 25, 123, 220, 73,
170, 1, 99, 196, 48, 145, 242, 75, 172, 23,
121, 218, 51, 148, 245, 96, 193, 26, 124, 221,
72, 169, 2, 100, 197, 47, 144, 241, 76, 173,
22, 120, 217, 52, 149, 246, 95, 192, 27, 125,
222, 71, 168, 3, 101, 198, 46, 143, 240, 77,
174, 21, 119, 216, 53, 150, 247, 94, 191, 28,
126, 223, 70, 167, 4, 102, 199, 45, 142, 239,
78, 175, 20, 118, 215, 54, 151, 248, 93, 190,
29, 127, 224, 69, 166, 5, 103, 200, 44, 141,
238, 79, 176, 19, 117, 214, 55, 152, 249, 92,
189, 30, 128, 225, 68, 165, 6, 104, 201, 43,
140, 237, 80, 177, 18, 116, 213, 56, 153, 250,
91, 188, 31, 129, 226, 67, 164, 7, 105, 202,
42, 139, 236, 81, 178, 17, 115, 212, 57, 154,
251, 90, 187, 32, 130, 227, 66, 163, 8, 106,
203, 41, 138, 235, 82, 179, 16, 114, 211, 58,
155, 252, 89, 186, 33, 131, 228, 65, 162, 9,
107, 204, 40, 137, 234, 83, 180, 15, 113, 210,
59, 156, 253, 88, 185, 34, 132, 229, 64, 161,
10, 108, 205, 39, 136, 233, 84, 181, 14, 112,
209, 60, 157, 254, 87, 184, 35, 133, 230, 63,
160, 11, 109, 206, 38, 135, 232, 85, 182, 13,
111, 208, 61, 158, 255, 86, 183, 36, 134, 231,
62, 159, 12, 110, 207, 37
};

 const uint16_t physicalToFibonacciOrder [] PROGMEM = {
0, 21, 42, 63, 84, 105, 126, 147, 168, 189, 210, 231, 252,
1, 22, 43, 64, 85, 106, 127, 148, 169, 190, 211, 232, 253,
2, 23, 44, 65, 86, 107, 128, 149, 170, 191, 212, 233, 254,
3, 24, 45,66, 87, 108, 129, 150, 171, 192, 213, 234, 255,
4, 25, 46, 67, 88, 109, 130, 151, 172, 193, 214, 235,
5, 26, 47, 68, 89, 110, 131, 152, 173, 194, 215, 236,
6, 27, 48, 69, 90, 111, 132, 153, 174, 195, 216, 237,
7, 28, 49, 70, 91, 112, 133, 154, 175, 196, 217, 238,
8, 29, 50, 71, 92, 113, 134,155,176,197, 218, 239,
9, 30, 51, 72, 93, 114, 135, 156, 177, 198, 219, 240,
10, 31, 52, 73, 94, 115, 136, 157, 178, 199, 220, 241,
11, 32, 53, 74, 95, 116, 137, 158, 179, 200, 221, 242,
12, 33, 54, 75, 96, 117, 138, 159, 180, 201, 222, 243,
13, 34, 55, 76, 97, 118, 139, 160, 181, 202, 223, 244,
14,35, 56,77, 98, 119, 140, 161, 182, 203, 224, 245,
15, 36, 57, 78, 99, 120, 141, 162, 183,204, 225, 246,
16, 37, 58, 79, 100, 121, 142, 163, 184, 205, 226, 247,
17, 38, 59, 80, 101, 122, 143, 164, 185, 206, 227, 248,
18, 39, 60, 81, 102, 123, 144, 165, 186, 207, 228, 249,
19, 40, 61, 82, 103, 124, 145, 166, 187, 208, 229, 250,
20, 41, 62, 83, 104, 125, 146, 167, 188, 209, 230, 251
};


 const uint8_t exp_gamma[256] PROGMEM = {
0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   1,   1,
1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
1,   2,   2,   2,   2,   2,   2,   2,   2,   2,   3,   3,   3,   3,   3,
4,   4,   4,   4,   4,   5,   5,   5,   5,   5,   6,   6,   6,   7,   7,
7,   7,   8,   8,   8,   9,   9,   9,   10,  10,  10,  11,  11,  12,  12,
12,  13,  13,  14,  14,  14,  15,  15,  16,  16,  17,  17,  18,  18,  19,
19,  20,  20,  21,  21,  22,  23,  23,  24,  24,  25,  26,  26,  27,  28,
28,  29,  30,  30,  31,  32,  32,  33,  34,  35,  35,  36,  37,  38,  39,
39,  40,  41,  42,  43,  44,  44,  45,  46,  47,  48,  49,  50,  51,  52,
53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,
68,  70,  71,  72,  73,  74,  75,  77,  78,  79,  80,  82,  83,  84,  85,
87,  89,  91,  92,  93,  95,  96,  98,  99,  100, 101, 102, 105, 106, 108,
109, 111, 112, 114, 115, 117, 118, 120, 121, 123, 125, 126, 128, 130, 131,
133, 135, 136, 138, 140, 142, 143, 145, 147, 149, 151, 152, 154, 156, 158,
160, 162, 164, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187,
190, 192, 194, 196, 198, 200, 202, 204, 207, 209, 211, 213, 216, 218, 220,
222, 225, 227, 229, 232, 234, 236, 239, 241, 244, 246, 249, 251, 253, 254, 255};

void GammaCorrection(){   //gamma correction function 
byte r,g,b;
for (uint16_t i=0; i<256; i++){
r=leds[i].r;
g=leds[i].g;
b=leds[i].b;
leds[i].r = pgm_read_byte(exp_gamma + r);
leds[i].g = pgm_read_byte(exp_gamma + g);
leds[i].b = pgm_read_byte(exp_gamma + b);
}
}

void RGB_Caleidoscope3(){
uint16_t a= millis()/8;

for (uint16_t j = 0; j <NUM_LEDS_FIB_STRIP; j++) {
uint16_t r =      pgm_read_byte (physicalToFibonacciOrder+j);       //need change table
// uint16_t cindex = pgm_read_byte (Fibon_Strip+j);  //work fine
uint16_t index =  pgm_read_byte (Fibon_Strip+r);   //work not fine. need change physicalToFibonacciOrder (return original)

leds[index].r= sin8(r+j/8-a+index);
leds[index].g= sin8(r+j/2-a/2);
leds[index].b= sin8(r+a);
} 
}


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() 
{
    RGB_Caleidoscope3();
    GammaCorrection();
    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;
}