//source: https://editor.soulmatelights.com/gallery/308-writing
// Simple text scrolling 

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

int hueOffset = 0;
int offset = 0;
//int numberOfLetters = 4;
int letterHeight = 4;
int rowHeight = 5; //5
int letterWidth = 5;

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() 
{
  byte cool2[][21] = {
    {1,1,1,1, 0, 1,1,1,1, 0, 1,1,1,1, 0, 1,0,0,0, 0, 0},
    {1,0,0,0, 0, 1,0,0,1, 0, 1,0,0,1, 0, 1,0,0,0, 0, 0},
    {1,0,0,0, 0, 1,0,0,1, 0, 1,0,0,1, 0, 1,0,0,0, 0, 0},
    {1,1,1,1, 0, 1,1,1,1, 0, 1,1,1,1, 0, 1,1,1,1, 0, 0}
  };
/*
    byte trance[][25] = {
    {1,1,1,1,1, 0, 1,1,1,0,0, 0, 1,1,1,1,0, 0, 1,0,0,1,0, 0, 0},
    {0,0,1,0,0, 0, 1,0,0,1,0, 0, 1,0,0,1,0, 0, 1,1,0,1,0, 0, 0},
    {0,0,1,0,0, 0, 1,1,1,0,0, 0, 1,1,1,1,0, 0, 1,0,1,1,0, 0, 0},
    {0,0,1,0,0, 0, 1,0,1,0,0, 0, 1,0,0,1,0, 0, 1,0,0,1,0, 0, 0},
    {0,0,1,0,0, 0, 1,0,0,1,0, 0, 1,0,0,1,0, 0, 1,0,0,1,0, 0, 0}
  }; */

  // int offset = beatsin16(5, 0, 30);
  EVERY_N_MILLISECONDS(200) {
    offset++;
  }
  int yoffset = 0; // beatsin16(6, 10, 20);

  hueOffset += 1;

  for (uint16_t x = 0; x < COLS; x++) {
    for (uint16_t y = 0; y < ROWS; y++) {
      uint16_t i = XY(x, y);
      int letterX = x + offset;
      int letterY = y + yoffset;
      byte pixel = cool2[3 - letterY % rowHeight][letterX % 21];
      //byte pixel = trance[3 - letterY % rowHeight][letterX % 25];
      int brightness = pixel ? 255 : 0;

      if (letterY % rowHeight == letterHeight) brightness = 0;
      
      int hue = (x + offset) * letterWidth + (y + offset) * letterHeight;
      leds[i] = CHSV(hue + hueOffset, 255, 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;
}