#include <esp_random.h>
uint8_t randomValue;
bool is1sec = false;
bool is5sec = false;
bool is1min = false;
bool is5min = false;
u_long time_START;
u_long time_Duration;
uint16_t timer_COUNTER_100ms = 0;
TaskHandle_t taskHandle_WS2812B;
#include <string>
using std::string;
using std::to_string;
#define PIN_LED_BUILTIN 2
#define PIN_BUZZER 15
#define PIN_WS2812B 32
#define NUM_PIXELS              16  // The number of LEDs (pixels) on WS2812B
#define WS2812B_NO_NOTE         0
#define WS2812B_NO_I2C          1
#define WS2812B_NO_WiFi         2
#define WS2812B_NO_MQTT         3
#define WS2812B_NO_API          4
#define WS2812B_NO_TIMER_START  5
#define WS2812B_NO_TIMER_END    7
#define WS2812B_NO_2_START      8   // 第二段 啟始
#define WS2812B_NO_2_END        15  // 第二段 結束
uint16_t WS2812B_SEGMENT_LENGTH = WS2812B_NO_2_END - WS2812B_NO_2_START + 1; // 燈段長度
uint8_t ws2812b_Brightness = 255;     // 最大亮度 預設
uint8_t ws2812b_Brightness_LEVEL = 1; // 最小亮度 7段調整
uint16_t ws2812b_NOTE_HUE = 0;        // loop 指示燈 HUE
bool isBrightness_FULL = true;        // 最大亮度
bool isLED_REVERSE = false;           // 燈條方向
#include <stdint.h>
// WS2812B
#include <Adafruit_NeoPixel.h>
const uint8_t WS2812B_NUM_TIMER = WS2812B_NO_TIMER_END - WS2812B_NO_TIMER_START + 1;
uint8_t ws2812b_NO = WS2812B_NO_TIMER_START;                // 目前燈號
uint8_t noWS2812B_NO_TIMER = WS2812B_NO_TIMER_START - 1;    // 初始設定 第1分鐘內 不變色
uint16_t ws2812b_HUE = 0;   // Hue        65535
// https://www.color-hex.com
#define COLOR_BLACK         0x000000        // 黑
#define COLOR_WHITE         0xFFFFFF        // 白
#define COLOR_RED           0xFF0000        // 紅
#define COLOR_GREEN         0x00FF00        // 綠
#define COLOR_BLUE          0x0000FF        // 藍
#define COLOR_YELLOW        0xFFFF00        // 黃
#define COLOR_CYAN          0x00FFFF        // 青
#define COLOR_MAGENTA       0xFF00FF        // 洋紅
#define COLOR_ORANGE        0xFF4000        // 橘 0xFFA500 0xFF8000 0xFF4000
#define COLOR_Index_BLACK   0               // 黑
#define COLOR_Index_WHITE   1               // 白
#define COLOR_Index_RED     2               // 紅   
#define COLOR_Index_GREEN   3               // 綠
#define COLOR_Index_BLUE    4               // 藍
#define COLOR_Index_YELLOW  5               // 黃
#define COLOR_Index_CYAN    6               // 青
#define COLOR_Index_MAGENTA 7               // 洋紅 <<< 紫
#define COLOR_Index_ORANGE  8               // 橘
#define COLOR_POOLs         9               // 顏色數量
const uint16_t colorHSV[COLOR_POOLs][3] = {
    {0,   0,   0},                                  // 黑     0°   0%   0%
    {0,   0, 255},                                  // 白     0°   0% 100%
    {0, 255, 255},                                  // 紅     0° 100% 100%
    {(int)(65535 * (double)120 / 360), 255, 255},   // 綠   120° 100% 100%
    {(int)(65535 * (double)240 / 360), 255, 255},   // 藍   240° 100% 100%
    {(int)(65535 * (double) 60 / 360), 255, 255},   // 黃    60° 100% 100%
    {(int)(65535 * (double)180 / 360), 255, 255},   // 青   180° 100% 100%
    {(int)(65535 * (double)300 / 360), 255, 255},   // 洋紅 300° 100% 100%
    {(int)(65535 * (double) 15 / 360), 255, 255}    // 橘    15° 100% 100%
  };
const uint8_t colorRGB[COLOR_POOLs][3] = {
    {  0,   0,   0},  // 黑
    {255, 255, 255},  // 白
    {255,   0,   0},  // 紅
    {  0, 255,   0},  // 綠
    {  0,   0, 255},  // 藍
    {255, 255,   0},  // 黃
    {  0, 255, 255},  // 青
    {255,   0, 255},  // 洋紅
    {255,  64,   0}   // 橘
  };
#define COLOR_HSV_Index_MIN 0             // 亮度等級 最小
#define COLOR_HSV_Index_MAX 6             // 亮度等級 最大
int8_t colorHSV_Index = 0;                // 亮度等級 目前
const uint8_t colorHSV_Brightness_FULL[(COLOR_HSV_Index_MAX + 1)] = {0, 1, 51, 102, 153, 204, 255}; // 步階 51 全亮度
const uint8_t colorHSV_Brightness_HALF[(COLOR_HSV_Index_MAX + 1)] = {0, 2, 27, 52, 77, 102, 127};   // 步階 25 半亮度
//
#define COLOR_READY         COLOR_WHITE         // 白
#define COLOR_RUNNING       COLOR_YELLOW        // 黃
#define COLOR_OK            COLOR_GREEN         // 綠
#define COLOR_ERROR         COLOR_RED           // 紅
#define COLOR_INFO          COLOR_BLUE          // 藍
#define COLOR_DEBUG         COLOR_CYAN          // 青
#define COLOR_WARNING       COLOR_ORANGE        // 橘
#define COLOR_ALERT         COLOR_MAGENTA       // 洋紅
//
#define COLOR_Index_READY   COLOR_Index_WHITE   // 白
#define COLOR_Index_RUNNING COLOR_Index_YELLOW  // 黃
#define COLOR_Index_OK      COLOR_Index_GREEN   // 綠
#define COLOR_Index_ERROR   COLOR_Index_RED     // 紅
#define COLOR_Index_INFO    COLOR_Index_BLUE    // 藍
#define COLOR_Index_DEBUG   COLOR_Index_CYAN    // 青
#define COLOR_Index_WARNING COLOR_Index_ORANGE  // 橘
#define COLOR_Index_ALERT   COLOR_Index_MAGENTA // 洋紅
Adafruit_NeoPixel WS2812B(NUM_PIXELS, PIN_WS2812B, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
uint8_t ws2812b_Meteor_Length = COLOR_HSV_Index_MAX; // 流星長度 有亮度的部分
uint32_t myColorHSV(uint8_t colorIndex = COLOR_Index_READY, uint8_t colorHSV_Index = 1) { // 顏色, 亮度
  uint8_t colorHSV_Brightness;
  //
  if (colorHSV_Index > COLOR_HSV_Index_MAX) {
    colorHSV_Index = COLOR_HSV_Index_MAX;
  }
  //
  if (isBrightness_FULL) { // 最大亮度
    if (colorHSV_Brightness_FULL[colorHSV_Index] > colorHSV[colorIndex][2]) {
      colorHSV_Brightness= colorHSV[colorIndex][2];
    } else {
      colorHSV_Brightness = colorHSV_Brightness_FULL[colorHSV_Index];
    }
  } else {
    if (colorHSV_Brightness_HALF[colorHSV_Index] > colorHSV[colorIndex][2]) {
      colorHSV_Brightness= colorHSV[colorIndex][2];
    } else {
      colorHSV_Brightness = colorHSV_Brightness_HALF[colorHSV_Index];
    }
  }
  //
  return WS2812B.ColorHSV(colorHSV[colorIndex][0], colorHSV[colorIndex][1], colorHSV_Brightness);
}
void flashWS2812B(uint8_t noWS2812B, uint32_t colorIndex = COLOR_Index_WHITE) {
  //WS2812B.setPixelColor(noWS2812B, color);
  WS2812B.setPixelColor(noWS2812B, myColorHSV(colorIndex, ws2812b_Brightness_LEVEL)); // 顏色, 亮度
  WS2812B.show();
}
void task_WS2812B(void* pvParameters) {
	u_long time_START;
  u_long time_Duration;
  uint8_t colorIndex = 1;
  uint16_t ws2812b_HUE = 0;
  int8_t colorHSV_Brightness; // 亮度
  int16_t pos_LED;  // 燈號 位置
  uint8_t pos_REVERSE_START, pos_REVERSE; // 反向 起始燈 第幾燈
  //----------------------------------------------------------------------------
  // 呼吸燈
  //----------------------------------------------------------------------------
  for(;;) {
    if (millis() - time_START > 1000) { // 1s
      randomValue = (esp_random() % 10) + 1;  // 亮燈間隔 1 ~ 10 ms
      isBrightness_FULL = ((esp_random() % 2) == 0) ? true : false; // 是否最大亮度
      isLED_REVERSE = ((esp_random() % 2) == 0) ? true : false;     // 燈條方向
      //
      pos_REVERSE_START = 0; // 反向 起始燈 <<< WS2812B_NO_2_END
      for (int16_t pos_START = WS2812B_NO_2_START; pos_START <= (WS2812B_NO_2_END + ws2812b_Meteor_Length); pos_START++) {
        colorHSV_Index = COLOR_HSV_Index_MAX; // 亮度等級 最大
        pos_REVERSE = 0; // 反向 第幾燈
        for (pos_LED = pos_START; pos_LED >= (pos_START - ws2812b_Meteor_Length); pos_LED--) { // 小尾 <<< 大頭
          if ((pos_LED >= WS2812B_NO_2_START) && (pos_LED <= WS2812B_NO_2_END)) {
            if (isBrightness_FULL) {
              colorHSV_Brightness = colorHSV_Brightness_FULL[colorHSV_Index];
            } else {
              colorHSV_Brightness = colorHSV_Brightness_HALF[colorHSV_Index];
            }
            WS2812B.setPixelColor((isLED_REVERSE ? (WS2812B_NO_2_END - pos_REVERSE_START + pos_REVERSE) : pos_LED), WS2812B.ColorHSV(colorHSV[colorIndex][0], colorHSV[colorIndex][1], colorHSV_Brightness));
          }
          //
          colorHSV_Index--; // 漸暗
          if (colorHSV_Index < COLOR_HSV_Index_MIN) {
            colorHSV_Index = COLOR_HSV_Index_MIN;
          }
          WS2812B.show();
          //------------------------------------------------------------------
          // 亮燈間隔 Delay 1 ~ 10ms
          delay(randomValue);
          pos_REVERSE++; // 反向 第幾燈
        }
        //
        pos_REVERSE_START++; // 反向 起始燈 <<< WS2812B_NO_2_END
      }
      //
      colorIndex++;
      if (colorIndex >= COLOR_POOLs) {
        colorIndex = 1;
      }
      //
      time_START = millis();
    }
  }
}
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(PIN_LED_BUILTIN, OUTPUT);
  pinMode(PIN_WS2812B, OUTPUT);
  WS2812B.begin();
  WS2812B.setBrightness(ws2812b_Brightness);
  WS2812B.show();
  xTaskCreatePinnedToCore(
    task_WS2812B,         // Function to implement the task 任務實際對應的 Function
    "taskHandle_WS2812B", // Name of the task 任務名稱
    10000,                // Stack size in words 堆疊空間(常用10000)
    NULL,                 // Task input parameter
    0,                    // Priority of the task 優先序:0代表最低,數字越高越優先
    &taskHandle_WS2812B,  // Task handle 對應的任務變數位址
    0                     // Core where the task should run 指定在核心0執行
  );
}
void loop() {
  for (colorHSV_Index = COLOR_HSV_Index_MIN; colorHSV_Index <= COLOR_HSV_Index_MAX; colorHSV_Index++) { // 亮度 >>> 暗 >>> 亮
    pos_LED = WS2812B_NO_2_END;
    colorHSV_Brightness = colorHSV_Brightness_FULL[colorHSV_Index];
    for (colorIndex = 1; colorIndex < COLOR_POOLs; colorIndex++) { // 顏色
      WS2812B.setPixelColor(pos_LED--, WS2812B.ColorHSV(colorHSV[colorIndex][0], colorHSV[colorIndex][1], colorHSV_Brightness));
    }
    WS2812B.show();
    //
    delay(100);
  }
  // 亮度 >>> 亮 >>> 暗
  for (colorHSV_Index = COLOR_HSV_Index_MAX; colorHSV_Index >= COLOR_HSV_Index_MIN; colorHSV_Index--) { // 亮度 >>> 暗 >>> 亮
    pos_LED = WS2812B_NO_2_END;
    colorHSV_Brightness = colorHSV_Brightness_FULL[colorHSV_Index];
    for (colorIndex = 1; colorIndex < COLOR_POOLs; colorIndex++) { // 顏色
      WS2812B.setPixelColor(pos_LED--, WS2812B.ColorHSV(colorHSV[colorIndex][0], colorHSV[colorIndex][1], colorHSV_Brightness));
    }
    WS2812B.show();
    //
    delay(100);
  }
}