#include <Adafruit_ILI9341.h>
#include <Adafruit_GFX.h>
#include <SD.h>

#define SD_MISO   15
#define SD_MOSI   17
#define SD_SCK    16
#define SD_CS     4

#define TFT_RST   23
#define TFT_DC    22
#define TFT_CS    5

#define BITMAP_FILE "/esplogo.bmp"

Adafruit_ILI9341 tft = Adafruit_ILI9341(&SPI, TFT_DC, TFT_CS);

uint8_t* logobmp;
size_t logo_w = 0;
size_t logo_h = 0;

void setup() {
  Serial.begin(115200);
  Serial.println("Starting program");
  SPI.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS);
  tft.begin();
  SD.begin(SD_CS, SPI);
  File logoFile = SD.open(BITMAP_FILE, "r");
  if (!logoFile) {
    Serial.println("Unable to open bitmap file");
    delay(10000);
    abort();
  }
  size_t logo_size = logoFile.size();
  logobmp = (uint8_t*)malloc(logo_size);
  size_t chunk_num = 0;
  while (logoFile.available()) {
    logoFile.read(logobmp + (chunk_num++ * 4096), 4096);
  }
  logoFile.close();
  logo_w = logobmp[18] + (logobmp[19] << 8);
  logo_h = logobmp[22] + (logobmp[23] << 8);
  tft.fillScreen(ILI9341_BLACK);
  tft.setRotation(1);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(2);
  char info[256];
  snprintf(info, 255,
           "Bitmap read from\n%s\nsize: %lu\nwidth: %lu height: %lu\n",
            BITMAP_FILE, logo_size, logo_w, logo_h);
  tft.print(info);
  if ((logo_w * logo_h * 2) + 170 != logo_size) {
    tft.print("Bitmap header does\nnot match file size");
    delay(60000);
    abort();
  }
  delay(2000);

}

void loop() {
  for(uint8_t r=0; r<4; r++) {
    tft.setRotation(r);
    tft.fillScreen(ILI9341_BLACK);
    for(uint8_t j=0; j<20; j++) {
      tft.drawRGBBitmap(
        random(-logo_w , tft.width()),
        random(-logo_h, tft.height()),
        (uint16_t *)logobmp,
        logo_w, logo_h);
      delay(1);
    }
    delay(3000);
  }
}