/**
   led灯控制
 * **/
#include "keyboard.h"
#include "ws2812.h"
#include "user_led.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "Arduino.h"
#include "esp32-hal.h"

#define LIGHT_TASK_CORE 1     //CPU1
#define LIGHT_TASK_PRIORITY 1 //优先级为1
#define LIGHT_TASK_STACK 4096 //堆栈字数
#define LIGHT_TASK_DELAY 5    //任务延时

TaskHandle_t LIGHT_TASK_Handle = NULL;  //任务句柄
QueueHandle_t LIGHT_DATA_QUEUE = NULL;  //传递保存亮度，颜色，模式的结构体



void ws2812_task(void *pvParameters)
{
  for (;;)
  {
    //读取模式
    uint8_t light_mode = get_light_mode();
    switch (light_mode)
    {
      case 0: 
        user_mode0();
        break;

      case 1:
        user_mode1();
        break;

      case 2:
        user_mode2();
        break;

      case 3:
        user_mode3();
        break;

      case 4:
        user_mode4();
        break;

      case 5:
        user_mode5();
        break;

      case 6:
        user_mode6();
        break;

      case 7:
        user_mode7();
        break;

      case 8:
        user_mode8();
        break;

      case 9:
        user_mode9();
        break;

      case 10:
        user_mode10();
        break;

      case 11:
        user_mode11();
        break;

      case 12:
        user_mode12();
        break;

      case 13:
        user_gamemode();
        break;

      default: //熄灭
        user_mode0();
        break;
    }

#ifdef LIGHT_TASK_DELAY
    vTaskDelay(LIGHT_TASK_DELAY);
#endif
  }

  LIGHT_TASK_Handle = NULL;
  vTaskDelete(NULL);
}

/**
   name: light_task_begin

   返回值：
    成功返回1 失败返回0

   功能：
    开启LIGHT任务
**/
uint8_t light_task_begin()
{
  if (LIGHT_TASK_Handle != NULL)
  {
    return 1;
  }
  else
  {
    //初始化队列
    if (init_light_queue() == 0)
    {
      return 0;
    }
    //创建任务
    BaseType_t xReturned;
    xReturned = xTaskCreatePinnedToCore(ws2812_task, "ws2812_task", LIGHT_TASK_STACK, NULL, LIGHT_TASK_PRIORITY, &LIGHT_TASK_Handle, LIGHT_TASK_CORE);
    if (xReturned == pdPASS)
    {
      return 1;
    }
  }
  return 0;
}

/**
   name: light_task_end

   返回值：
    成功返回1 失败返回0

   功能：
    关闭LIGHT任务
 **/
void light_task_end()
{
  if (LIGHT_TASK_Handle != NULL)
  {
    //关闭任务
    vTaskDelete(LIGHT_TASK_Handle);
    LIGHT_TASK_Handle = NULL;

    //删除队列–释放分配用于存储放置在队列中的项目的所有内存。
    Config_light config_light;
    while (xQueueReceive(LIGHT_DATA_QUEUE, &config_light, 0) == pdTRUE)
    {
    }
    vQueueDelete(LIGHT_DATA_QUEUE);
    LIGHT_DATA_QUEUE = NULL;
  }
}

/**
   name: clean_led

   返回值：
    成功返回1 失败返回0

   功能：
   熄灭所有锁定键灯珠的状态
 * **/
uint8_t clean_led()
{
  if (LIGHT_DATA_QUEUE != NULL)
  {
    fill_solid(leds, WS2812_NUMBER, CRGB::Black);
    FastLED.show();
    return 1;
  }
  return 0;
}


/**
   name: set_speed

   传参：
    0~12 0/1

   返回值：
    成功返回1 失败返回0

   功能：
   设置灯光速度
 * **/
uint8_t set_speed(uint8_t s)
{
  if (LIGHT_DATA_QUEUE != NULL && s <= LIGHT_SPEED_MAX)
  {
    if (xQueuePeek(LIGHT_DATA_QUEUE, &Keyboard_Config, 5) == pdTRUE)
    {
      Keyboard_Config.L_speed = s;
      xQueueOverwrite(LIGHT_DATA_QUEUE, &Keyboard_Config);
      return 1;
    }
  }
  return ERROR_CODE;
}

/**
   name: get_speed

   传参：
    0~90

   返回值：
    0/1

   功能：
    返回 设置灯光速度 读取错误返回0
 * ***/
uint8_t get_speed(uint8_t *S_)
{
  if (LIGHT_DATA_QUEUE != NULL)
  {
    if (xQueuePeek(LIGHT_DATA_QUEUE, &Keyboard_Config, 5) == pdTRUE)
    {
      *S_ = Keyboard_Config.L_speed;
      return 1;
    }
  }
  return 0;
}

/*
   name: set_rgb

   传参：
    RGB参数 0 ~ LIGHT_#_MAX

   功能：
    设置 LIGHT_COLOR_QUEUE 颜色
 **/
uint8_t set_rgb(uint8_t c)
{
  if (LIGHT_DATA_QUEUE != NULL && c <= LIGHT_CORLOR_MAX)
  {
    if (xQueuePeek(LIGHT_DATA_QUEUE, &Keyboard_Config, 5) == pdTRUE)
    {
      Keyboard_Config.L_color = c;

      xQueueOverwrite(LIGHT_DATA_QUEUE, &Keyboard_Config);
      return 1;
    }
  }
  return 0;
}

/**
   name: get_rgb

   功能：
    从 LIGHT_COLOR_QUEUE 获取颜色
 * */
uint8_t get_rgb(uint8_t *C_)
{
  if (LIGHT_DATA_QUEUE != NULL)
  {
    if (xQueuePeek(LIGHT_DATA_QUEUE, &Keyboard_Config, 5) == pdTRUE)
    {
      *C_ = Keyboard_Config.L_color;
      return 1;
    }
  }
  return 0;
}

/***
   name: set_brgightness

   功能：
   设置 亮度
 * **/
uint8_t set_brgightness(uint8_t l)
{
  if (LIGHT_DATA_QUEUE != NULL && l <= LIGHT_BRGIGHTNESS_MAX)
  {
    Config_light config_light;
    if (xQueuePeek(LIGHT_DATA_QUEUE, &config_light, 5) == pdTRUE)
    {
      config_light.L_brgightness = l;
      xQueueOverwrite(LIGHT_DATA_QUEUE, &config_light);
      return 1;
    }
  }
  return 0;
}

/***
   name: get_brgightness

   返回值：
    返回亮度 0~20 失败返回0
 ***/
uint8_t get_brgightness()
{
  if (LIGHT_DATA_QUEUE != NULL)
  {
    Config_light config_light;
    xQueuePeek(LIGHT_DATA_QUEUE, &config_light, 5);
    return config_light.L_brgightness;
  }
  return 0;
}

/***
   name: set_light_mode

   功能：
    设置灯光模式
    0熄灭/1闪烁/2按亮/3全亮
***/
uint8_t set_light_mode(uint8_t m)
{
  if (LIGHT_DATA_QUEUE != NULL && m <= LIGHT_MODE_NUM)
  {
    Config_light config_light;
    if (xQueuePeek(LIGHT_DATA_QUEUE, &config_light, 5) == pdTRUE)
    {
      config_light.L_mode = m;
      xQueueOverwrite(LIGHT_DATA_QUEUE, &config_light);
      return 1;
    }
  }
  return 0;
}

/**
   name: get_light_mode

   返回值：
    返回模式号 0/1/2/3.....     失败返回0

   功能：
    获取灯光模式
 **/
uint8_t get_light_mode()
{
  if (LIGHT_DATA_QUEUE != NULL)
  {
    Config_light config_light;
    xQueuePeek(LIGHT_DATA_QUEUE, &config_light, 5);
    return config_light.L_mode;
  }
  return 0;
}

/**
   name: init_light_queue

   返回值：
    成功返回1 失败返回0

   功能：
    创建队列
 ***/
uint8_t init_light_queue()
{
  if (LIGHT_DATA_QUEUE == NULL )
  {
    //初始化 LIGHT_DATA_QUEUE
    Config_light config_light;
    LIGHT_DATA_QUEUE = xQueueCreate(1, sizeof(config_light));
    if (LIGHT_DATA_QUEUE != NULL)
    {
      xQueueOverwrite(LIGHT_DATA_QUEUE, &config_light);
    }
    else
    {
      return 0;
    }
  }
  return 1;
}
