/**
 ******************************************************************************
 *
 * @file        
 * @brief       
 *
 * @par         Project
 *              MG32F02N128
 * @version     V1.00
 * @date        2024/08/28
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2017 MegaWin Technology Co., Ltd.
 *              All rights reserved.
 *
 ******************************************************************************* 
 * @par Disclaimer
 * The Demo software is provided "AS IS" without any warranty, either
 * expressed or implied, including, but not limited to, the implied warranties
 * of merchantability and fitness for a particular purpose. The author will
 * not be liable for any special, incidental, consequential or indirect
 * damages due to loss of data or any other reason.
 * These statements agree with the world wide and local dictated laws about
 * authorship and violence against these laws.
 *******************************************************************************
 *******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "Drama.h"
#include "Calendar.h"
#include "BSP_VariableResistor.h"
#include "BSP_LED.h"
#include "BSP_ARGB_WS2812.h"
#include "BSP_TemperatureSensor.h"
#include <stdarg.h>

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ARGB_DRAMA_PIECE        4
#define ARGB_DRAMA_BYTE         (ARGB_DRAMA_PIECE * 3)

#define ARGB_DRAMA_COLOR_TOTAL  6
#define ARGB_DRAMA_COLOR_G      0
#define ARGB_DRAMA_COLOR_R      1
#define ARGB_DRAMA_COLOR_B      2

#define LCD_SPLASHSCREEN_PATTERN_TOTAL   36
#define LCD_SPLASHSCREEN_PATTERN_HALF    18

#define LCD_SPLASHSCREEN_P2     0
#define LCD_SPLASHSCREEN_P3     1
#define LCD_SPLASHSCREEN_P5     2
#define LCD_SPLASHSCREEN_P6     3
#define LCD_SPLASHSCREEN_P8     4
#define LCD_SPLASHSCREEN_P19    5
#define LCD_SPLASHSCREEN_P20    6

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static uint8_t  Drama_LCD_State;

static uint32_t FirmwareLoadCnt;
static uint32_t FirmwareLoadPulseCnt;
static uint8_t  FirmwareLoad;
static uint8_t  FirmwareLoadDirection;

static uint32_t BatteryCnt;
static uint8_t  BatteryStatus;

static uint32_t SignalStrengthCnt;
static uint8_t  SignalStrengthStatus;

static float    mVoltage;
static float    mCurrent;
static float    Humidity;
static float    KPa;

static int16_t  Temperture;

static uint8_t  Calendar_Second_point;
static uint8_t  Calendar_Second_Record;

static uint8_t  VarPercentage;
static uint8_t  VarBeforePercentage;

static uint8_t  LED_Drama_State;
static uint8_t  LED_Drama_Act;
static uint32_t LED_Drama_ActionCmp;
static uint32_t LED_Drama_ActionCnt;

static uint8_t  ARGB_Drama_State;
static uint8_t  ARGB_Drama_Act;
static uint8_t  ARGB_Drama_Action;
static uint8_t  ARGB_Drama_Buf[ARGB_DRAMA_BYTE];
static uint8_t  ARGB_Drama_ColorTable[ARGB_DRAMA_COLOR_TOTAL][3] =
{
    {0x00, 0x05, 0x00},
    {0x05, 0x05, 0x00},
    {0x05, 0x00, 0x00},
    {0x05, 0x00, 0x05},
    {0x00, 0x00, 0x05},
    {0x00, 0x05, 0x05}
};  /*!< { G, R, B}*/

static uint8_t ARGB_Drama_MappingTable[ARGB_DRAMA_PIECE] = {1, 2, 3, 0};

static const uint8_t Drama_LCD_SplashScreenTable[LCD_SPLASHSCREEN_PATTERN_TOTAL][7] =
{
    /* P2   P3    P5    P6    P8    P19   P20*/
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01},
    {0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01},
    {0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01},
    {0x03, 0x02, 0x00, 0x00, 0x00, 0x02, 0x01},
    {0x03, 0x02, 0x01, 0x00, 0x00, 0x02, 0x01},
    {0x03, 0x02, 0x01, 0x01, 0x00, 0x02, 0x01},
    {0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01},
    {0x03, 0x02, 0x01, 0x01, 0x03, 0x02, 0x01},

    {0x03, 0x02, 0x01, 0x01, 0x03, 0x0A, 0x01},
    {0x03, 0x02, 0x01, 0x01, 0x03, 0x0A, 0x09},
    {0x0B, 0x02, 0x01, 0x01, 0x03, 0x0A, 0x09},
    {0x0F, 0x02, 0x01, 0x01, 0x03, 0x0A, 0x09},
    {0x0F, 0x02, 0x01, 0x01, 0x03, 0x0A, 0x09},
    {0x0F, 0x02, 0x05, 0x01, 0x03, 0x0A, 0x09},
    {0x0F, 0x02, 0x05, 0x09, 0x03, 0x0A, 0x09},
    {0x0F, 0x02, 0x05, 0x09, 0x0B, 0x0A, 0x09},
    {0x0F, 0x02, 0x05, 0x09, 0x0F, 0x0A, 0x09},

    {0x0F, 0x02, 0x05, 0x09, 0x0F, 0x0A, 0x09},
    {0x0F, 0x02, 0x05, 0x09, 0x0F, 0x0A, 0x09},
    {0x0F, 0x02, 0x05, 0x09, 0x0F, 0x0A, 0x09},

    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},

    {0x0F, 0x02, 0x05, 0x09, 0x0F, 0x0A, 0x09},
    {0x0F, 0x02, 0x05, 0x09, 0x0F, 0x0A, 0x09},
    {0x0F, 0x02, 0x05, 0x09, 0x0F, 0x0A, 0x09},

    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},

    {0x0F, 0x02, 0x05, 0x09, 0x0F, 0x0A, 0x09},
    {0x0F, 0x02, 0x05, 0x09, 0x0F, 0x0A, 0x09},
    {0x0F, 0x02, 0x05, 0x09, 0x0F, 0x0A, 0x09},

    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
};

/* Private function ----------------------------------------------------------*/
static void Drama_LCD_SplashScreen(uint8_t SplashScreen_Step);

static void LCD_Drama_Calendar(void);
static void LCD_Drama_Measure( uint32_t Show_Mode, float Show_Value, uint8_t Decimal_Point);

static void LCD_Drama_Page(uint8_t PageNumber);
static void LCD_Drama_16SegmentString(const char *SEG16_String, ...);

static void LCD_Drama_VendorBlock1( uint8_t VendorBlock1_Number);
static void LCD_Drama_VendorBlock2( uint8_t VendorBlock1_Number);

static void ARGB_Drama_ClearBuf(void);

/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External variables --------------------------------------------------------*/

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
void Drama_Init(void)
{
   BatteryCnt             = 0;
   FirmwareLoadCnt        = 0;
   FirmwareLoadPulseCnt   = 0;
   FirmwareLoadDirection  = 0;
   SignalStrengthCnt      = 0;

   FirmwareLoad           = 30;

   BatteryStatus          = BSP_LCD_BATTERY_LEVEL3;
   SignalStrengthStatus   = BSP_LCD_SINGSTRENGTH_LEVLE1;
   mVoltage               = 3300;
   mCurrent               = 20;
   KPa                    = (float)101.325;
   Temperture             = 0;
   Humidity               = 61;

   Calendar_Second_point  = 0; 
   Calendar_Second_Record = Calendar_CTR.Second;

   VarPercentage          = 0;
   VarBeforePercentage    = 0;

   Drama_LCD_State        = 0;

   Drama_LEDMode_Config(LED_DRAMA_FLASHING);

   Drama_ARGBMode_Config(ARGB_DRAMA_SPLASH_SCREEN);
//   Drama_ARGBMode_Config(ARGB_DRAMA_OFF);
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */ 
uint8_t Drama_LCD_Handler(void)
{
    /*Parameter declare*/
    uint8_t LCD_DramaHandler_UpdateFlag;

    /*Parameter initial*/
    LCD_DramaHandler_UpdateFlag = 0;

    /*Calendar handler*/
    #if 1
        if( Calendar_CTR.mSecond == 500)
        {
            Calendar_Second_point       = 0;
            LCD_DramaHandler_UpdateFlag = 1;
        }
        else if(Calendar_CTR.Second!=Calendar_Second_Record)
        {
            Calendar_Second_point       = 1;
            Calendar_Second_Record      = Calendar_CTR.Second;
            LCD_DramaHandler_UpdateFlag = 1;
        }
    #endif
    /*Battery pattern handler*/
    #if 1

        if( BatteryCnt < 1000)
        {
            BatteryCnt ++;
        }
        else
        {
            BatteryCnt = 0;
            if( BatteryStatus == BSP_LCD_BATTERY_LEVEL3)
            {
                BatteryStatus = BSP_LCD_BATTERY_LEVEL0;
            }
            else
            {
                BatteryStatus ++;
            }
            LCD_DramaHandler_UpdateFlag = 1;
        }

    #endif
    /*Firmware loading pattern handler*/
    #if 1
        if( FirmwareLoadCnt < 5)
        {
            FirmwareLoadCnt ++; 
        }
        else
        {
            FirmwareLoadCnt = 0;

            if( FirmwareLoadPulseCnt < 10)
            {
                if( FirmwareLoad == 80)
                {
                    FirmwareLoadPulseCnt ++;
                    FirmwareLoadDirection = 1;
                }
                else if( FirmwareLoad == 40)
                {
                    FirmwareLoadDirection = 0;
                }
            }
            else
            {
                if( FirmwareLoad == 120)
                {
                    FirmwareLoadPulseCnt = 0;
                    FirmwareLoadDirection = 1;
                }
                else if( FirmwareLoad == 40)
                {
                    FirmwareLoadDirection = 0;
                }
            }

            if( FirmwareLoadDirection == 0)
            {
                FirmwareLoad ++;
            }
            else
            {
                FirmwareLoad --;
            }

            LCD_DramaHandler_UpdateFlag = 1;
        }
    #endif
    /*Signal strength pattern handler*/
    #if 1
        if( SignalStrengthCnt < 2000)
        {
            SignalStrengthCnt ++;
        }
        else
        {
            SignalStrengthCnt = 0;

            if( SignalStrengthStatus == BSP_LCD_SINGSTRENGTH_LEVLE2)
            {
                SignalStrengthStatus = BSP_LCD_SINGSTRENGTH_LEVLE0;
            }
            else
            {
                SignalStrengthStatus ++;
            }

            LCD_DramaHandler_UpdateFlag = 1;
        }
    #endif

    return(LCD_DramaHandler_UpdateFlag);
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */ 
void BSP_VR_ChangeCallback(void)
{
    VarPercentage = BSP_VR_GetPercentage();
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */    
uint8_t Drama_LCD_Update( uint8_t Drama_LCD_Mode)
{
    uint8_t Drama_LCD_UpdateResult;
    BSP_LCD_ClearDataBuffer();

    if(Drama_LCD_Mode == LCD_DRAMA_BREAK)
    {
        Drama_LCD_UpdateResult = BSP_LCD_TriggerUpdate();
        return(Drama_LCD_UpdateResult);
    }
    else if( Drama_LCD_Mode == LCD_DRAMA_SPLASH_SCREEN)
    {
        LCD_Drama_16SegmentString("MG32");

        Drama_LCD_SplashScreen(Drama_LCD_State);

        Drama_LCD_UpdateResult = BSP_LCD_TriggerUpdate();
        if(Drama_LCD_UpdateResult == BSP_LCD_SUCCESS)
        {
            if( Drama_LCD_State == (LCD_SPLASHSCREEN_PATTERN_TOTAL - 1))
            {
                Drama_LCD_SplashScreen_CpltCallback();
            }
            else
            {
                Drama_LCD_State++;
                if( Drama_LCD_State == LCD_SPLASHSCREEN_PATTERN_HALF)
                {
                    Drama_LCD_SplashScreen_HalfCallback();
                }
            }
        }
        return(Drama_LCD_UpdateResult);
    }
    else if( Drama_LCD_Mode == LCD_DRAMA_CALENDAR)
    {
        LCD_Drama_Calendar();
    }
    else
    {
        switch(Drama_LCD_Mode)
        {
            case LCD_DRAMA_DC_mA:
                                   LCD_Drama_16SegmentString("DC");
                                   LCD_Drama_Measure(BSP_LCD_CURRENT_mA_MODE, mCurrent, 1); 
                                   break;

            case LCD_DRAMA_DC_A:
                                   LCD_Drama_16SegmentString("DC");
                                   LCD_Drama_Measure(BSP_LCD_CURRENT_A_MODE, (mCurrent / 1000), 2);
                                   break;

            case LCD_DRAMA_VOLT_mV:
                                   LCD_Drama_16SegmentString("VOLT");
                                   LCD_Drama_Measure(BSP_LCD_VOLTAGE_mV_MODE, mVoltage, 1);
                                   break;

            case LCD_DRAMA_VOLT_V:
                                   LCD_Drama_16SegmentString("VOLT");
                                   LCD_Drama_Measure(BSP_LCD_VOLTAGE_V_MODE, (mVoltage / 1000), 2);
                                   break;

            case LCD_DRAMA_ATM_MPa:
                                   LCD_Drama_16SegmentString("ATM");
                                   LCD_Drama_Measure(BSP_LCD_PRESSURE_MPA_MODE, (KPa / 1000), 2);
                                   break;

            case LCD_DRAMA_ATM_KPa:
                                   LCD_Drama_16SegmentString("ATM");
                                   LCD_Drama_Measure(BSP_LCD_PRESSURE_KPA_MODE, KPa, 1);
                                   break;

            case LCD_DRAMA_RH:
                                   LCD_Drama_16SegmentString("RH");
                                   LCD_Drama_Measure(BSP_LCD_HUMIDITY_MODE, Humidity, 2);
                                   break;

            case LCD_DRAMA_TEMP:
            default:
                                   LCD_Drama_16SegmentString("TEMP");
                                   LCD_Drama_Measure(BSP_LCD_TEMPERTURE_MODE, Temperture, 0);
                                   break;
        }

        LCD_Drama_Page((Drama_LCD_Mode-1));
        LCD_Drama_VendorBlock1(VarPercentage);
    }

    BSP_LCD_Battery(BatteryStatus );
    BSP_LCD_SignalStrength(SignalStrengthStatus);
    BSP_LCD_Percentage(FirmwareLoad);

    Drama_LCD_UpdateResult = BSP_LCD_TriggerUpdate();
    return(Drama_LCD_UpdateResult);
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
static void Drama_LCD_SplashScreen(uint8_t SplashScreen_Step)
{
    LCD_PIN2_Tmp.B  |= Drama_LCD_SplashScreenTable[SplashScreen_Step][LCD_SPLASHSCREEN_P2];
    LCD_PIN3_Tmp.B  |= Drama_LCD_SplashScreenTable[SplashScreen_Step][LCD_SPLASHSCREEN_P3];
    LCD_PIN5_Tmp.B  |= Drama_LCD_SplashScreenTable[SplashScreen_Step][LCD_SPLASHSCREEN_P5];
    LCD_PIN6_Tmp.B  |= Drama_LCD_SplashScreenTable[SplashScreen_Step][LCD_SPLASHSCREEN_P6];
    LCD_PIN8_Tmp.B  |= Drama_LCD_SplashScreenTable[SplashScreen_Step][LCD_SPLASHSCREEN_P8];
    LCD_PIN19_Tmp.B |= Drama_LCD_SplashScreenTable[SplashScreen_Step][LCD_SPLASHSCREEN_P19];
    LCD_PIN20_Tmp.B |= Drama_LCD_SplashScreenTable[SplashScreen_Step][LCD_SPLASHSCREEN_P20]; 
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
__WEAK void Drama_LCD_SplashScreen_CpltCallback(void)
{
    //=========================================================
    //Note : This function should not be modified, when the callback
    //       is needed, the Drama_LCD_SplashScreen_CpltCallback can
    //       be implemented in the user file.
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
__WEAK void Drama_LCD_SplashScreen_HalfCallback(void)
{
    //=========================================================
    //Note : This function should not be modified, when the callback
    //       is needed, the Drama_LCD_SplashScreen_HalfCallback can
    //       be implemented in the user file.
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
void Drama_LEDMode_Config(uint8_t Drama_LED_Mode)
{
    if( LED_Drama_State == Drama_LED_Mode)
    {
        return;
    }

    BSP_LED_Cmd(BSP_LED0,BSP_LED_OFF);
    BSP_LED_Cmd(BSP_LED1,BSP_LED_OFF);

    switch(Drama_LED_Mode)
    {
        case LED_DRAMA_FLASHING:
                                LED_Drama_Act       = 0;
                                LED_Drama_ActionCmp = 500;
                                LED_Drama_ActionCnt = 500;
                                break;

        case LED_DRAMA_VAR:
                                VarPercentage = VarBeforePercentage;
                                LED_Drama_ActionCnt = 0;
                                LED_Drama_ActionCmp = 1000;
                                break;

        case LED_DRAMA_OFF:
        default:
                                LED_Drama_State = LED_DRAMA_OFF;
                                return;
    }

    LED_Drama_State = Drama_LED_Mode;
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
void Drama_LED_Handler(void)
{
    switch(LED_Drama_State)
    {
        case LED_DRAMA_FLASHING:
                                if( LED_Drama_ActionCnt == LED_Drama_ActionCmp)
                                {
                                    LED_Drama_ActionCnt = 0;
                                    if( LED_Drama_Act == 0)
                                    {
                                        BSP_LED_Cmd(BSP_LED0, BSP_LED_OFF);
                                        BSP_LED_Cmd(BSP_LED1, BSP_LED_OFF);
                                        LED_Drama_Act = 1;
                                    }
                                    else
                                    {
                                        BSP_LED_Cmd(BSP_LED0, BSP_LED_ON);
                                        BSP_LED_Cmd(BSP_LED1, BSP_LED_ON);
                                        LED_Drama_Act = 0;
                                    }
                                }
                                else
                                {
                                    LED_Drama_ActionCnt ++;
                                }
                                break;

        case LED_DRAMA_VAR:
                                if( VarPercentage != VarBeforePercentage)
                                {
                                    LED_Drama_ActionCnt = 0;
                                    BSP_LED_Cmd(BSP_LED1, BSP_LED_OFF);
                                    BSP_LED_Cmd(BSP_LED0, BSP_LED_OFF);

                                    if( VarPercentage > VarBeforePercentage)
                                    {
                                        BSP_LED_Cmd(BSP_LED1, BSP_LED_ON);
                                    }
                                    else
                                    {
                                        BSP_LED_Cmd(BSP_LED0, BSP_LED_ON);
                                    }
                                    VarBeforePercentage = VarPercentage;
                                }
                                else if( LED_Drama_ActionCnt < LED_Drama_ActionCmp)
                                {
                                    LED_Drama_ActionCnt ++;
                                }
                                else if( LED_Drama_ActionCnt == LED_Drama_ActionCmp)
                                {
                                    BSP_LED_Cmd(BSP_LED1, BSP_LED_OFF);
                                    BSP_LED_Cmd(BSP_LED0, BSP_LED_OFF);
                                    LED_Drama_ActionCnt ++;
                                }
                                return;

        case LED_DRAMA_OFF:
        default:
                                break;
    }
    VarBeforePercentage = VarPercentage;
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
void Drama_ARGBMode_Config( uint8_t Drama_ARGB_Mode)
{
    if( Drama_ARGB_Mode == ARGB_Drama_State)
    {
        return;
    }

    switch(Drama_ARGB_Mode)
    {
        case ARGB_DRAMA_OFF:
        case ARGB_DRAMA_SPLASH_SCREEN:
                                      break;

        case ARGB_DRAMA_CALENDAR:
                                      ARGB_Drama_Act    = 0;
                                      ARGB_Drama_Action = 0;
                                      ARGB_Drama_ClearBuf();
                                      break;

        default:
                                      ARGB_Drama_State = ARGB_DRAMA_NA;
                                      return;
    }

    ARGB_Drama_State = Drama_ARGB_Mode;
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
void Drama_ARGB_Handler(void)
{
    switch(ARGB_Drama_State)
    {
        case ARGB_DRAMA_OFF:
                                      ARGB_Drama_ClearBuf();
                                      ARGB_Drama_State = ARGB_DRAMA_NA;
                                      break;

        case ARGB_DRAMA_SPLASH_SCREEN:
                                      ARGB_Drama_ClearBuf();
                                      ARGB_Drama_Buf[(ARGB_Drama_MappingTable[3] * 3) + ARGB_DRAMA_COLOR_B] = 0x0A;
                                      ARGB_Drama_Buf[(ARGB_Drama_MappingTable[0] * 3) + ARGB_DRAMA_COLOR_B] = 0x0A;
                                      ARGB_Drama_Buf[(ARGB_Drama_MappingTable[1] * 3) + ARGB_DRAMA_COLOR_R] = 0x0A;
                                      ARGB_Drama_Buf[(ARGB_Drama_MappingTable[2] * 3) + ARGB_DRAMA_COLOR_R] = 0x0A;
                                      ARGB_Drama_State = ARGB_DRAMA_NA;
                                      break;

        case ARGB_DRAMA_CALENDAR:
                                      if(Calendar_CTR.mSecond!=0)
                                      {
                                          return;
                                      }

                                      switch( ARGB_Drama_Act)
                                      {
                                          case 0:
                                                 ARGB_Drama_Buf[(ARGB_Drama_MappingTable[0] * 3) + ARGB_DRAMA_COLOR_R] = ARGB_Drama_ColorTable[ARGB_Drama_Action][ARGB_DRAMA_COLOR_R];
                                                 ARGB_Drama_Buf[(ARGB_Drama_MappingTable[0] * 3) + ARGB_DRAMA_COLOR_G] = ARGB_Drama_ColorTable[ARGB_Drama_Action][ARGB_DRAMA_COLOR_G];
                                                 ARGB_Drama_Buf[(ARGB_Drama_MappingTable[0] * 3) + ARGB_DRAMA_COLOR_B] = ARGB_Drama_ColorTable[ARGB_Drama_Action][ARGB_DRAMA_COLOR_B];
                                                 ARGB_Drama_Act ++;
                                                 if(ARGB_Drama_Action == (ARGB_DRAMA_COLOR_TOTAL - 1))
                                                 {
                                                     ARGB_Drama_Action = 0;
                                                 }
                                                 else
                                                 {
                                                     ARGB_Drama_Action ++;
                                                 }
                                                 break;

                                          case 1:
                                                 ARGB_Drama_Buf[(ARGB_Drama_MappingTable[1] * 3) + ARGB_DRAMA_COLOR_R] = ARGB_Drama_Buf[(ARGB_Drama_MappingTable[0] * 3) + ARGB_DRAMA_COLOR_R];
                                                 ARGB_Drama_Buf[(ARGB_Drama_MappingTable[1] * 3) + ARGB_DRAMA_COLOR_G] = ARGB_Drama_Buf[(ARGB_Drama_MappingTable[0] * 3) + ARGB_DRAMA_COLOR_G];
                                                 ARGB_Drama_Buf[(ARGB_Drama_MappingTable[1] * 3) + ARGB_DRAMA_COLOR_B] = ARGB_Drama_Buf[(ARGB_Drama_MappingTable[0] * 3) + ARGB_DRAMA_COLOR_B];
                                                 ARGB_Drama_Act ++;
                                                 break;

                                          case 2:
                                                 ARGB_Drama_Buf[(ARGB_Drama_MappingTable[2] * 3) + ARGB_DRAMA_COLOR_R] = ARGB_Drama_Buf[(ARGB_Drama_MappingTable[1]*3) + ARGB_DRAMA_COLOR_R];       
                                                 ARGB_Drama_Buf[(ARGB_Drama_MappingTable[2] * 3) + ARGB_DRAMA_COLOR_G] = ARGB_Drama_Buf[(ARGB_Drama_MappingTable[1]*3) + ARGB_DRAMA_COLOR_G];
                                                 ARGB_Drama_Buf[(ARGB_Drama_MappingTable[2] * 3) + ARGB_DRAMA_COLOR_B] = ARGB_Drama_Buf[(ARGB_Drama_MappingTable[1]*3) + ARGB_DRAMA_COLOR_B];
                                                 ARGB_Drama_Act ++;
                                                 break;

                                          case 3:
                                                 ARGB_Drama_Buf[(ARGB_Drama_MappingTable[3] * 3) + ARGB_DRAMA_COLOR_R] = ARGB_Drama_Buf[(ARGB_Drama_MappingTable[2] * 3) + ARGB_DRAMA_COLOR_R];
                                                 ARGB_Drama_Buf[(ARGB_Drama_MappingTable[3] * 3) + ARGB_DRAMA_COLOR_G] = ARGB_Drama_Buf[(ARGB_Drama_MappingTable[2] * 3) + ARGB_DRAMA_COLOR_G];
                                                 ARGB_Drama_Buf[(ARGB_Drama_MappingTable[3] * 3) + ARGB_DRAMA_COLOR_B] = ARGB_Drama_Buf[(ARGB_Drama_MappingTable[2] * 3) + ARGB_DRAMA_COLOR_B];
                                                 ARGB_Drama_Act = 0;
                                                 break;
                                      }
                                      break;

        case ARGB_DRAMA_NA:
        default:
                                      return;
    }

    BSP_ARGB_SendData(ARGB_Drama_Buf, ARGB_DRAMA_BYTE);
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
void BSP_TemperatureSensor_CpltCallback(void)
{
    Temperture = BSP_TemperatureSensor_GetDegree();
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
static void LCD_Drama_Calendar(void)
{
    /*Show T symbol*/
    BSP_LCD_Symbol_T();

    /*Show year*/
    LCD_Drama_16SegmentString(" %d", Calendar_CTR.Year);

    /*Show Month*/
    LCD_Drama_VendorBlock1(Calendar_CTR.Month);

    /*Show Day*/
    LCD_Drama_VendorBlock2(Calendar_CTR.Day);

    /*Show Hour*/
    BSP_LCD_7Segment(BSP_LCD_SEG7_6, (Calendar_CTR.Hour / 10));
    BSP_LCD_7Segment(BSP_LCD_SEG7_7, (Calendar_CTR.Hour % 10));

    /*Show Minute*/
    BSP_LCD_7Segment_6_10_Point(BSP_LCD_SEG7_6to10_S15);
    BSP_LCD_7Segment(BSP_LCD_SEG7_8, (Calendar_CTR.Minute / 10));
    BSP_LCD_7Segment(BSP_LCD_SEG7_9, (Calendar_CTR.Minute % 10));

    /*Show Second*/
    if( Calendar_Second_point == 1)
    {
        BSP_LCD_7Segment_6_10_Point(BSP_LCD_SEG7_6to10_S17);
    }
    BSP_LCD_7Segment(BSP_LCD_SEG7_10, (Calendar_CTR.Second / 10));
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note       需加入負號顯示  
 *******************************************************************************
 */
static void LCD_Drama_Measure( uint32_t Show_Mode, float Show_Value, uint8_t Decimal_Point)
{
    int32_t LCD_wMeasurePattern_dividendTmp;
    int32_t LCD_wMeasurePattern_QuotientTmp;
    int32_t LCD_wMeasurePattern_RemainderTmp;
    uint8_t LCD_wMeasurePattern_ShowFlag;
    uint8_t LCD_wMeasurePattern_NegFlag;
    uint8_t LCD_wMeasurePattern_SigFigs;

    /*Parameter initial*/
    LCD_wMeasurePattern_ShowFlag = 0;
    LCD_wMeasurePattern_SigFigs  = 0;
    LCD_wMeasurePattern_NegFlag  = 0;

    /*Symbol Unit*/
    switch( Show_Mode)
    {
        case BSP_LCD_TEMPERTURE_MODE:
                                       BSP_LCD_Symbol_Degree();
                                       break;

        case BSP_LCD_HUMIDITY_MODE:
                                       BSP_LCD_Symbol_Percentage();
                                       break;

        case BSP_LCD_VOLTAGE_V_MODE:
                                       BSP_LCD_Symbol_V();
                                       break;

        case BSP_LCD_VOLTAGE_mV_MODE:
                                       BSP_LCD_Symbol_m();
                                       BSP_LCD_Symbol_V();
                                       break;

        case BSP_LCD_CURRENT_A_MODE:
                                       BSP_LCD_Symbol_A();
                                       break;

        case BSP_LCD_CURRENT_mA_MODE:
                                       BSP_LCD_Symbol_m();
                                       BSP_LCD_Symbol_A();
                                       break;

        case BSP_LCD_PRESSURE_KPA_MODE:
                                       BSP_LCD_Symbol_KPa();
                                       break;

        case BSP_LCD_PRESSURE_MPA_MODE:
                                       BSP_LCD_Symbol_MPa();
                                       break;

        default:
                                       break;
    }

    /*Point*/
    if( Decimal_Point == 1)
    {
        BSP_LCD_7Segment_6_10_Point(BSP_LCD_SEG7_6to10_S17);
    }
    else if( Decimal_Point == 2)
    {
        BSP_LCD_7Segment_6_10_Point(BSP_LCD_SEG7_6to10_S16);
    }

    /*Number*/
    if( Decimal_Point == 1)
    {
        LCD_wMeasurePattern_dividendTmp = (int32_t)(Show_Value * 10);

        if( LCD_wMeasurePattern_dividendTmp > 99999)
        {
            LCD_wMeasurePattern_dividendTmp = 99999;
        }
        else if(LCD_wMeasurePattern_dividendTmp < -9999)
        {
            LCD_wMeasurePattern_dividendTmp = -9999;
        }
    }
    else if( Decimal_Point == 2)
    {
        LCD_wMeasurePattern_dividendTmp = (int32_t)(Show_Value * 100);

        if( LCD_wMeasurePattern_dividendTmp > 99999)
        {
            LCD_wMeasurePattern_dividendTmp = 99999;
        }
        else if(LCD_wMeasurePattern_dividendTmp < -9999)
        {
            LCD_wMeasurePattern_dividendTmp = -9999;
        }
    }
    else if( Decimal_Point == 0)
    {
        if( Show_Value > 99999)
        {
            LCD_wMeasurePattern_dividendTmp = 9999;
        }
        else if(Show_Value < -9999)
        {
            LCD_wMeasurePattern_dividendTmp = -9999;
        }
        else
        {
            LCD_wMeasurePattern_dividendTmp = (int32_t)Show_Value;
        }
    }
    else
    {
        return;
    }

    if( LCD_wMeasurePattern_dividendTmp < 0)
    {
        LCD_wMeasurePattern_dividendTmp = LCD_wMeasurePattern_dividendTmp * (-1);
        LCD_wMeasurePattern_NegFlag = 1;
    }

    LCD_wMeasurePattern_QuotientTmp  = LCD_wMeasurePattern_dividendTmp / 10000;
    LCD_wMeasurePattern_RemainderTmp = LCD_wMeasurePattern_dividendTmp % 10000;

    if( LCD_wMeasurePattern_QuotientTmp!= 0)
    {
        LCD_wMeasurePattern_ShowFlag = 1;
    }
    if(LCD_wMeasurePattern_ShowFlag == 1)
    {
        BSP_LCD_7Segment(BSP_LCD_SEG7_6,(uint8_t)LCD_wMeasurePattern_QuotientTmp);
        LCD_wMeasurePattern_SigFigs++;
    }

    LCD_wMeasurePattern_QuotientTmp  = LCD_wMeasurePattern_RemainderTmp / 1000;
    LCD_wMeasurePattern_RemainderTmp = LCD_wMeasurePattern_RemainderTmp % 1000;

    if(LCD_wMeasurePattern_QuotientTmp != 0)
    {
        LCD_wMeasurePattern_ShowFlag = 1;
    }

    if(LCD_wMeasurePattern_ShowFlag == 1)
    {
        BSP_LCD_7Segment(BSP_LCD_SEG7_7,(uint8_t)LCD_wMeasurePattern_QuotientTmp);
        LCD_wMeasurePattern_SigFigs++;
    }

    /*=====================================*/
    LCD_wMeasurePattern_QuotientTmp  = LCD_wMeasurePattern_RemainderTmp / 100;
    LCD_wMeasurePattern_RemainderTmp = LCD_wMeasurePattern_RemainderTmp % 100;

    if( Decimal_Point != 2)
    {
        if(LCD_wMeasurePattern_QuotientTmp != 0)
        {
            LCD_wMeasurePattern_ShowFlag = 1;
        }
        if(LCD_wMeasurePattern_ShowFlag == 1)
        {
            BSP_LCD_7Segment(BSP_LCD_SEG7_8,(uint8_t)LCD_wMeasurePattern_QuotientTmp);
            LCD_wMeasurePattern_SigFigs++;
        }
    }
    else
    {
        BSP_LCD_7Segment(BSP_LCD_SEG7_8,(uint8_t)LCD_wMeasurePattern_QuotientTmp);
        LCD_wMeasurePattern_SigFigs++;
    }

    /*======================================*/
    LCD_wMeasurePattern_QuotientTmp  = LCD_wMeasurePattern_RemainderTmp / 10;
    LCD_wMeasurePattern_RemainderTmp = LCD_wMeasurePattern_RemainderTmp % 10;

    if( Decimal_Point == 0)
    {
        if(LCD_wMeasurePattern_QuotientTmp != 0)
        {
            LCD_wMeasurePattern_ShowFlag = 1;
        }
        if(LCD_wMeasurePattern_ShowFlag == 1)
        {
            BSP_LCD_7Segment(BSP_LCD_SEG7_9, (uint8_t)LCD_wMeasurePattern_QuotientTmp);
            LCD_wMeasurePattern_SigFigs++;
        }
    }
    else
    {
        BSP_LCD_7Segment(BSP_LCD_SEG7_9, (uint8_t)LCD_wMeasurePattern_QuotientTmp);
        LCD_wMeasurePattern_SigFigs++;
    }

    BSP_LCD_7Segment(BSP_LCD_SEG7_10, (uint8_t)LCD_wMeasurePattern_RemainderTmp);
    LCD_wMeasurePattern_SigFigs++;

    if( LCD_wMeasurePattern_NegFlag == 1)
    {
        BSP_LCD_7Segment_6_10_NegativeSymbol(LCD_wMeasurePattern_SigFigs);
    }
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
static void LCD_Drama_Page(uint8_t PageNumber)
{
    LCD_Drama_VendorBlock2(PageNumber);
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
static void LCD_Drama_16SegmentString(const char *SEG16_String, ...)
{
    char     Seg16_16SegBuf[6];
    va_list  parameter; 
    int      str;
    uint8_t  Seg16_Cnt = 0;
    char     *pSeg16_String;
    uint8_t  Seg16_Rem;
    uint8_t  Seg16_StringCnt;

    va_start(parameter, SEG16_String);
    for (; *SEG16_String != 0; ++SEG16_String)
    {
        if( *SEG16_String == '%')
        {
            ++SEG16_String;
            str = va_arg(parameter, int);

            if(*SEG16_String == 'd')
            {
                pSeg16_String   = Seg16_16SegBuf + 5;
                *pSeg16_String  = '\0';
                Seg16_StringCnt = 0;
                while(str)
                {
                    Seg16_Rem = (uint8_t)(str % 10);
                    *--pSeg16_String = (uint8_t)('0' + Seg16_Rem);
                    Seg16_StringCnt++;
                    str /= 10;
                }
                if((Seg16_Cnt + Seg16_StringCnt)>5)
                {
                    LCD_Drama_16SegmentString("ERROR");
                    break;
                }
                else
                {
                    for(; *pSeg16_String; ++pSeg16_String)
                    {
                        BSP_LCD_16SegmentChar(Seg16_Cnt, *pSeg16_String);
                        Seg16_Cnt++;
                    }
                }
            }
            else
            {
                // No Support
            }
        }
        else
        {
            BSP_LCD_16SegmentChar(Seg16_Cnt, *SEG16_String);
            Seg16_Cnt++;
            
            if( Seg16_Cnt > 5)
            {
                LCD_Drama_16SegmentString("ERROR");
                break;
            }
        }
    }

    va_end(parameter);
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
static void LCD_Drama_VendorBlock1(uint8_t VendorBlock1_Number)
{
    /*Parameter declare*/
    uint32_t LCD_wVendorPattern_dividendTmp;
    uint32_t LCD_wVendorPattern_QuotientTmp;
    uint32_t LCD_wVendorPattern_RemainderTmp;
    uint32_t LCD_wVendorPattern_ShowFlag;

    /*Parameter initial*/
    LCD_wVendorPattern_dividendTmp = VendorBlock1_Number;
    LCD_wVendorPattern_ShowFlag    = 0;

    LCD_wVendorPattern_QuotientTmp  = LCD_wVendorPattern_dividendTmp / 100;
    LCD_wVendorPattern_RemainderTmp = LCD_wVendorPattern_dividendTmp % 100;

    if( LCD_wVendorPattern_QuotientTmp != 0)
    {
        LCD_wVendorPattern_ShowFlag = 1;
    }

    if( LCD_wVendorPattern_ShowFlag == 1)
    {
        BSP_LCD_7Segment(BSP_LCD_SEG7_1, (uint8_t)LCD_wVendorPattern_QuotientTmp);
    }

    LCD_wVendorPattern_QuotientTmp  = LCD_wVendorPattern_RemainderTmp / 10;
    LCD_wVendorPattern_RemainderTmp = LCD_wVendorPattern_RemainderTmp % 10;

    if( LCD_wVendorPattern_QuotientTmp != 0)
    {
        LCD_wVendorPattern_ShowFlag = 1;
    }

    if( LCD_wVendorPattern_ShowFlag == 1)
    {
        BSP_LCD_7Segment(BSP_LCD_SEG7_2, (uint8_t)LCD_wVendorPattern_QuotientTmp);
    }

    BSP_LCD_7Segment(BSP_LCD_SEG7_3, (uint8_t)LCD_wVendorPattern_RemainderTmp);
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
static void LCD_Drama_VendorBlock2(uint8_t VendorBlock1_Number)
{
    /*Parameter declare*/
    uint32_t LCD_wVendor1Pattern_QuotientTmp;
    uint32_t LCD_wVendor1Pattern_RemainderTmp;

    LCD_wVendor1Pattern_QuotientTmp  = VendorBlock1_Number / 10;
    LCD_wVendor1Pattern_RemainderTmp = VendorBlock1_Number % 10;
    if( LCD_wVendor1Pattern_QuotientTmp != 0)
    {
        BSP_LCD_7Segment(BSP_LCD_SEG7_4, (uint8_t)LCD_wVendor1Pattern_QuotientTmp);
    }
    BSP_LCD_7Segment(BSP_LCD_SEG7_5, (uint8_t)LCD_wVendor1Pattern_RemainderTmp);
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @param[in]   
 * @exception   
 * @note        
 *******************************************************************************
 */
static void ARGB_Drama_ClearBuf(void)
{
    uint8_t ARGB_Drama_clrBufTmp;

    for( ARGB_Drama_clrBufTmp = 0; ARGB_Drama_clrBufTmp < ARGB_DRAMA_BYTE; ARGB_Drama_clrBufTmp ++)
    {
        ARGB_Drama_Buf[ARGB_Drama_clrBufTmp] = 0x00;
    }
}

