#include <ArduinoJson.h>
#include <SD.h>
#include "SPI.h"
#include "LumiPalette.h"

// #define CS_PIN 5
#define SCK  18
#define MISO  19
#define MOSI  23
#define CS  5

#define NUM_PALETTES 10
#define MAX_TAGS 4

File root;
LumiPalette pal[NUM_PALETTES] = {0};
int pIndex[NUM_PALETTES] = {0};

DynamicJsonDocument doc(18000);


void setup() {
  Serial.begin(115200);

  SPIClass spi = SPIClass(VSPI);
  spi.begin(SCK, MISO, MOSI, CS);

  Serial.print("Initializing SD card... ");

  if (!SD.begin(CS,spi,80000000)) {
    Serial.println("Card initialization failed!");
    while (true);
  }

  Serial.println("initialization done.");

  Serial.println("Files in the card:");
  root = SD.open("/");
  printDirectory(root, 0);
  Serial.println("");
  root.close();

  File file = SD.open("/palettes.json");
  DeserializationError err = deserializeJson(doc,file);
  file.close();  // We don't need the file anymore

  if (err) {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(err.c_str());
  }

  // JsonObject obj = doc.as<JsonObject>();

  // serializeJsonPretty(doc, Serial);

  for( int i = 0; i < NUM_PALETTES; i++ ) {
    pal[i].index = doc["palettes"][i]["index"];
    pal[i].label = doc["palettes"][i]["label"].as<String>();

    if (doc["palettes"][i]["enabled"].as<String>() == "yes") {
      pal[i].enabled = true;
    } else {
      pal[i].enabled = false;
    }

    for( int j = 0; j < MAX_TAGS; j++ ) {
      if( doc["palettes"][i]["tags"][j] != 0) { // should skip the nulls
        String tag = doc["palettes"][i]["tags"][j].as<String>();
        pal[i].tags[j] = str2enum(tag.c_str());
      }
    }
  }

  // Serial.println(pal[0].toJson().c_str());

  int numPalettesFound = getPalettesByTag(pIndex,PASTEL);
  Serial.print(numPalettesFound);
  Serial.print(" palettes match ");
  Serial.println(PASTEL);

  for( int i = 0; i <= numPalettesFound; i++ ) {
    Serial.println(pIndex[i]);
  }

  Serial.print(F("Done"));
}

void loop() {
  delay(100);
  // nothing happens after setup finishes.
}

void printDirectory(File dir, int numTabs) {
  while (true) {

    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numTabs + 1);
    } else {
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}

// Returns int, number of palettes matching tag
int getPalettesByTag( int * pIndexes, PaletteTag tag) {
    int indexIndex = 0;
      Serial.print("Searching for tag: ");
      Serial.println(tag);
    for( int i = 0; i < NUM_PALETTES; i++ ) {
      for( int j = 0; j < MAX_TAGS; j++) {
          Serial.print(i);
          Serial.print(" tag: ");
          Serial.println(pal[i].tags[j]);
        if( pal[i].tags[j] == tag) {
          pIndexes[indexIndex] = pal[i].index;
          indexIndex++;
        }
      }
    }
    return indexIndex - 1;
}