// https://lodev.org/cgtutor/plasma.html

#include <Arduino.h>
#include <FastLED.h>
#include "constants.h"
#include "enums.h"
#include "plasma.h"

#define dist(a, b, c, d) sqrt(double((a - c) * (a - c) + (b - d) * (b - d)))

CRGB palette[256];
int plasma[PANEL_HEIGHT][PANEL_WIDTH];
bool plasma_ready = false;

int palette_shift = 0;

void setup_plasma() {
  for(int i = 0; i < 256; i++) {

    CHSV hsv_color(i, 255, 255);
    hsv2rgb_rainbow(hsv_color, palette[i]);
  }
  // initial plasma
  for(int y = 0; y < PANEL_HEIGHT; y++) {
    for(int x = 0; x < PANEL_WIDTH; x++) {
      //the plasma buffer is a sum of sines
      int color = int
      (
          128.0 + (128.0 * sin(float(x) / 4.0))
        + 128.0 + (128.0 * sin(float(y) / 2.0))
        + 128.0 + (128.0 * sin(float(x + y) / 4.0))
        + 128.0 + (128.0 * sin(sqrt(x * x + y * y) / 4.0))
      ) / 4;
      plasma[y][x] = color;
    }
  }
  plasma_ready = true;
}
int timer = 0;
void draw_plasma(MatrixPanel_I2S_DMA *matrix, Mode mode) {
  //if (!plasma_ready)
  //  setup_plasma();
  //int timer = int(millis() / 25.0);
  for (int y = 0; y < PANEL_HEIGHT; y++) {
    for (int x = 0; x < PANEL_WIDTH; x++) {
      //CRGB color = palette[(plasma[y][x] + palette_shift) % 256];
      //double value = sin(dist(x + timer, y, 128.0, 128.0) / 8.0)
      //       + sin(dist(x, y, 64.0, 64.0) / 8.0)
      //       + sin(dist(x, y + timer / 7.0, 192.0, 64.0) / 7.0)
      //       + sin(dist(x, y, 192.0, 100.0) / 8.0);
      double value = (
               sin(dist(x + timer, y, 128.0, 128.0) * 0.5)
             + sin(dist(x, y, 64.0, 64.0) * 0.5)
             + sin(dist(x, y + timer / 7.0, 192.0, 64.0)  * 0.5)
             + sin(dist(x, y, 192.0, 100.0) * 0.5 )
            ) * 0.25;
      CRGB color;
      CHSV hsv_color(int(128.0 + (value * 127.0)), 255, 255);
      hsv2rgb_rainbow(hsv_color, color);
      matrix->drawPixel(x, y, matrix->color565(color.r, color.g, color.b));
      //if(Serial)
      //  Serial.println(value);
      //matrix->drawPixel(x, y, matrix->color565(color.r, color.g, color.b));
    }
  }
  timer++;
  //palette_shift++;
}
