//Stepko
#include "FastLED.h"

// Matrix size
#define LED_COLS 16
#define LED_ROWS 16
#define NUM_LEDS LED_ROWS * LED_COLS
// LEDs pin
#define DATA_PIN 3
// LED brightness
#define BRIGHTNESS 255
// Define the array of leds
CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
}
byte dir = 3;
void drawPixel(byte x, byte y, CRGB color) {
  leds[XY(x, y)] += color;
  if (LED_COLS > 24 || LED_ROWS > 24) {
    leds[XY(x + 1, y)] += color;
    leds[XY(x - 1, y)] += color;
    leds[XY(x, y + 1)] += color;
    leds[XY(x, y - 1)] += color;
  }
}

void MoveX(int8_t delta) {
  if (delta) {
    if (delta > 0) {
      for (uint8_t y = 0; y < LED_ROWS; y++) {
        for (uint8_t x = 0; x < LED_COLS; x++) {
          leds[XY(x, y)] = leds[XY(x + delta, y)];
        }
      }
    } else {
      for (uint8_t y = 0; y < LED_ROWS; y++) {
        for (uint8_t x = LED_COLS - 1; x > 0; x--) {
          leds[XY(x, y)] = leds[XY(x + delta, y)];
        }
      }
    }
  }
}

void MoveY(int8_t delta) {
  if (delta) {
    if (delta > 0) {
      for (uint8_t x = 0; x < LED_COLS; x++) {
        for (uint8_t y = 0; y < LED_ROWS; y++) {
          leds[XY(x, y)] = leds[XY(x, y + delta)];
        }
      }
    } else {
      for (uint8_t x = 0; x < LED_COLS; x++) {
        for (uint8_t y = LED_ROWS - 1; y > 0; y--) {
          leds[XY(x, y)] = leds[XY(x, y + delta)];
        }
      }
    }
  }
}


void loop() {
  fadeToBlackBy(leds, NUM_LEDS, 16);
  switch (dir) {
    case 0:
      MoveX(1);
      break;
    case 1:
      MoveX(1);
      MoveY(-1);
      break;
    case 2:
      MoveY(-1);
      break;
    case 3:
      MoveX(-1);
      MoveY(-1);
      break;
    case 4:
      MoveX(-1);
      break;
    case 5:
      MoveX(-1);
      MoveY(1);
      break;
    case 6:
      MoveY(1);
      break;
    case 7:
      MoveX(1);
      MoveY(1);
      break;
  }
    for (byte i = 0; i < 8; i++) {
    byte x = beatsin8(12 + i, 2, LED_COLS - 3);
    byte y = beatsin8(15 + i, 2, LED_ROWS - 3);
    drawPixel(x, y, ColorFromPalette(RainbowColors_p, beatsin8(12 + i, 0, 255), 255));
  }
  blur2d(leds, LED_COLS, LED_ROWS, 32);
  FastLED.show();
  EVERY_N_SECONDS(5) {
    if (dir == 7) dir = 0;
    else dir++;
  }
}


uint16_t XY (uint8_t x, uint8_t y) {
  return (y * LED_COLS + x);
}