// #include "BLESerial.h"
#include <Arduino.h>
#include <FastLED.h>

// constants
const int BOARD_STANDARD = 0;
const int BOARD_MINI = 1;
#define COLOR_SATURATION 255

// custom settings
int board = BOARD_STANDARD;           // Define the board type : mini or standard (to be changed depending of board type used)
const int LED_OFFSET = 1;             // Light every "LED_OFFSET" LED of the LEDs strip
const uint8_t PIXEL_PIN = 2;          // Use pin D2 of Arduino Nano 33 BLE (to be changed depending of your pin number used)
const bool CHECK_LEDS_AT_BOOT = true; // Test the led sysem at boot if true
const int NUM_LEDS = 200;

// variables used inside project
int ledsByBoard[] = {200, 150};                                                  // LEDs: usually 150 for MoonBoard Mini, 200 for a standard MoonBoard
int rowsByBoard[] = {18, 12};                                                    // Rows: usually 12 for MoonBoard Mini, 18 for a standard MoonBoard
String namesByBoard[] = {"Moonboard Standard", "Moonboard Mini"};                // Names of moonboards
// BLESerial bleSerial;                                                             // BLE serial emulation
String bleMessage = "l#S69,S4,P93,P81,P49,P28,P10,E54#";                                                          // BLE buffer message
bool bleMessageStarted = false;                                                  // Start indicator of problem message
bool bleMessageEnded = false;                                                    // End indicator of problem message
CRGB leds[NUM_LEDS]; 

/**
 * @brief Process the BLE message to light the matching LEDs
 *
 */
void processBleMesage()
{
  /*
   * Example of received BLE messages:
   *    "~D*l#S69,S4,P82,P8,P57,P49,P28,E54#"
   *    "l#S69,S4,P93,P81,P49,P28,P10,E54#"
   *
   * first message part (separator = '#')
   *    - "~D*1" : light 2 LEDs, the selected hold and the LED above it
   *    - "1" : light the the selected hold
   *
   * second message part (separator = '#') is the problem string separated by ','
   *    - format: "S12,P34, ... ,E56"
   *    - where S = starting hold, P = intermediate hold, E = ending hold
   *    - where the following numbers are the LED position on the strip
   */

  Serial.println("--------------------");
  Serial.print("Message: ");
  Serial.println(bleMessage);
  Serial.println();

  int indexHashtag1 = 0;
  int indexHashtag2 = 0;
  bool ledAboveHoldEnabled = false;

  // explode the message with char '#'
  while ((indexHashtag2 = bleMessage.indexOf('#', indexHashtag1)) != -1)
  {
    String splitMessage = bleMessage.substring(indexHashtag1, indexHashtag2);
    indexHashtag1 = indexHashtag2 + 1;

    if (splitMessage[0] == 'l') // process conf part of the ble message
    {
      ledAboveHoldEnabled = false;
    }
    else if (splitMessage[0] == '~') // process conf part of the ble message
    {
      ledAboveHoldEnabled = true;
    }
    else // process the problem part of the ble message
    {
      int indexComma1 = 0;
      int indexComma2 = 0;
      while (indexComma2 != -1)
      {
        indexComma2 = splitMessage.indexOf(',', indexComma1);
        String holdMessage = splitMessage.substring(indexComma1, indexComma2);
        indexComma1 = indexComma2 + 1;

        char holdType = holdMessage[0];                         // holdType is the first char of the string
        int holdPosition = holdMessage.substring(1).toInt();    // holdPosition start at second char of the string
        lightHold(holdType, holdPosition, ledAboveHoldEnabled); // light the hold on the board
      }
    }
  }
}

/**
 * @brief Check LEDs by cycling through the colors red, green, blue, violet and then turning the LEDs off again
 *
 */
void checkLeds()
{
    Serial.println("Checking leds");
  if (CHECK_LEDS_AT_BOOT)
  {
    CRGB colors[] = {CRGB::White, CRGB::Red, CRGB::Blue, CRGB::Violet};
    int fadeDelay = 25;
    
    for (int i = 0; i < leds; i++)
    {
      Serial.println("Showing pixel: ");
      Serial.print(i + 1);
      leds[i] = colors[0];
      FastLED.show();
      Serial.println("Should have shown");
      delay(fadeDelay);
    }

        for (int i = 0; i < leds; i++)
    {
      Serial.println("Showing pixel: ");
      Serial.print(i + 1);
      leds[i] = colors[1];
      FastLED.show();
      Serial.println("Should have shown");
      delay(fadeDelay);
    }
  }
}

/**
 * @brief Initialization
 *
 */
void setup()
{
  Serial.begin(115200);
  char bleName[] = "MoonBoard A";
  // bleSerial.begin(bleName);
  FastLED.addLeds<WS2812B, 2, GRB>(leds, NUM_LEDS);
  // strip.Show();

  Serial.println("-----------------");
  Serial.print("Initialization completed for ");
  Serial.println(namesByBoard[board]);
  Serial.println("Waiting for the mobile app to connect ...");
  Serial.println("-----------------");
}

/**
 * @brief Infinite loop processed by the chip
 *
 */
void loop()
{
  if (!bleMessageStarted) {
  processBleMesage();
  bleMessageStarted = true;
  }
}