#include <Arduino.h>
#include <FastLED.h>
#include "constants.h"
#include "enums.h"
#include "supercomputer.h"
#include "overlay.h"

struct Cell {
  float state;
  float factor;
};

float cell_value(Cell c) {
  return (1.0 + sin(c.state * c.factor)) * 0.5;
}

Cell cells[PANEL_WIDTH * PANEL_HEIGHT];
bool cells_setup = false;
uint8_t rainbow_offset = 0;

void setup_cells() {
  for(int i = 0; i < PANEL_WIDTH * PANEL_HEIGHT; i++) {
    cells[i].state = random(100, 1000) / 100.0;
    cells[i].factor = random(90, 110) / 100.0;
  }
}

void draw_supercomputer(MatrixPanel_I2S_DMA *matrix, Mode mode) {
  if (!cells_setup) {
    setup_cells();
    cells_setup = true;
  }
  for(int i = 0; i < PANEL_WIDTH * PANEL_HEIGHT; i++) {
    int x = i % PANEL_WIDTH;
    int y = i / PANEL_WIDTH;
    cells[i].state += 0.3;
    if (mode == Stealth) {
      // red only
      matrix->drawPixel(x, y, matrix->color565((int)round(255.0 * cell_value(cells[i])), 0, 0));
    } else {
      // rainbow
      float progress = (255.0 / PANEL_WIDTH) * x;
      uint8_t hue = ((int)round(progress) + rainbow_offset);
      if (overlay[i / 8] & (1 << (7 - (i % 8)))) {
        hue -= 128;
      } else if (mode == HighVis) {
        continue;
      }
      CHSV hsv_color(hue, 255, 255 * cell_value(cells[i]));
      CRGB rgb;
      hsv2rgb_rainbow(hsv_color, rgb);
      matrix->drawPixel(x, y, matrix->color565(rgb.r, rgb.g, rgb.b));
    }
  }
  rainbow_offset++;
  delay(25);
}
