#include <Arduino.h>
#include "gameoflife.h"
#include "display.h"

#define COLOR_DEPTH 24                                        // known working: 24, 48 - If the sketch uses type `rgb24` directly, COLOR_DEPTH must be 24
const uint8_t kMatrixWidth = 64;                              // known working: 32, 64, 96, 128
const uint8_t kMatrixHeight = 64;                             // known working: 16, 32, 48, 64
const uint8_t kRefreshDepth = 24;                             // known working: 24, 36, 48
const uint8_t kDmaBufferRows = 2;                             // known working: 2-4, use 2 to save memory, more to keep from dropping frames and automatically lowering refresh rate
const uint8_t kPanelType = SMARTMATRIX_HUB75_64ROW_MOD32SCAN; // use SMARTMATRIX_HUB75_16ROW_MOD8SCAN for common 16x32 panels
const uint8_t kMatrixOptions = (SMARTMATRIX_OPTIONS_NONE);    // see http://docs.pixelmatix.com/SmartMatrix for options
const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE);
const uint8_t kIndexedLayerOptions = (SM_INDEXED_OPTIONS_NONE);

const int defaultBrightness = (brightnessPercent * 255) / 100;

rgb24 colorWhite = {0xff, 0xff, 0xff};
rgb24 colorBlack = {0x00, 0x00, 0x00};

SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);
SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions);
SMARTMATRIX_ALLOCATE_INDEXED_LAYER(indexedLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kIndexedLayerOptions);

void setupDisplay()
{
  matrix.addLayer(&backgroundLayer);
  matrix.addLayer(&indexedLayer);
  matrix.begin();
  matrix.setBrightness(defaultBrightness);
  backgroundLayer.setBrightness(255);
  backgroundLayer.enableColorCorrection(true);
}

void displayLoop()
{
  if (runGame)
  {
    for (int i = 0; i < SCREEN_HEIGHT; i++)
    {
      for (int j = 0; j < SCREEN_WIDTH; j++)
      {
        backgroundLayer.drawPixel(j, i, g[i][j] ? colorWhite : colorBlack);
      }
    }
    backgroundLayer.swapBuffers();
  }
}

void showEndScreen(int ticks) {
  showEvolutions(ticks);
}

void fadeOutGame(int brightness) {
  brightness = lightPowerMap8bit[brightness];
  backgroundLayer.setBrightness(brightness);
  backgroundLayer.swapBuffers();
}

void showEvolutions(int ticks)
{
  char msg[15] = "Life has ended";
  char evolutions[17];
  sprintf(evolutions, "Evolutions: %d", ticks);
  indexedLayer.setFont(font3x5);
  indexedLayer.drawString((matrix.getScreenWidth() / 2) - (strlen(msg) * 4) / 2, (matrix.getScreenHeight() / 2) - 2 - 5 , 1, msg);
  indexedLayer.drawString((matrix.getScreenWidth() / 2) - (strlen(evolutions) * 4) / 2, (matrix.getScreenHeight() / 2) + 2, 1, evolutions);
  indexedLayer.swapBuffers();
  indexedLayer.fillScreen(0);
}

void clearDisplay()
{
  indexedLayer.swapBuffers();
  backgroundLayer.fillScreen({0, 0, 0});
  backgroundLayer.setBrightness(255);
  backgroundLayer.swapBuffers();
}