
/**
 ******************************************************************************
 *
 * @file        UserEvent.c
 * @brief       User event routine.
 *
 * @par         Project
 *              MG32x02z
 * @version     V1.01
 * @date        2021/05/31
 * @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 "UserEvent.h"
#include "LCD1_Menu.h"
#include "MG32x02z_EncoderEC11_API.h"
#include "MG32x02z_DACOutput_API.h"
#include "MG32x02z_RGBLED_API.h"
#include "MG32x02z_USBD_MGData.h"
#include "MG32x02z_USBD_AUDIO_CORE.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
                            //1                    12                    23                    34                    45                    56                    67                    78                    89                    9
__IO uint8_t RxBuffer[180] ={"Welcom use megawin Product, the MG0404A Demo Board use MG32F02U128.UART Rx Empty         0123456789            ABCDEFGHIJKLMNOPQRSTUVWXYZ                 abcdefghijklmnopqrstuvwxyz"};
__IO uint8_t RxBufferCount = 0;

__IO static uint8_t gEventBuffer[100];
RingBufferU8 gEventQueue ;
UEvent_HandleTypedef gUEvent;

/* Private function prototypes -----------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External vairables --------------------------------------------------------*/
extern __IO uint8_t gOldSelect;
extern __IO uint8_t gOldMenu;
extern MGData_TypeDef           MGData_CTR;
extern RTC_HandleTypeDef        mRTC;
extern API_DAC_Parameters       API_DAC_Output;
extern Display_HandleTypeDef    LCD1st;


/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   
 * @note        
 * @par         
 *******************************************************************************
 */
void UserEvent_Initial(void)
{
    // User Interface Ring Buffer Initial
    RingBufferU8_Initial(&gEventQueue, (uint8_t *)(&gEventBuffer), sizeof(gEventBuffer));

    // EC11 Initial
    API_EncoderEC11_Init();

    // ADCKey Initial

    // Menu Initial
    gUEvent.Menu = MainMenu;
    gUEvent.Select = 1;
    gUEvent.Option = 0;
    gUEvent.SetIdleTime = 3;
    gUEvent.SetBLE = 1;
    gUEvent.SetWIFI = 0;
    gUEvent.SoundSelect = 1;
    gUEvent.SoundVolume = 1;
    gUEvent.LEDPWMSpeed = 0;
    gUEvent.LEDBreathingSpeed = 0;
    gUEvent.LCDPicture = 0;
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   
 * @note        
 * @par         
 *******************************************************************************
 */
static void MenuEnter(UEvent_HandleTypedef *UEvent)
{
    if(UEvent->Option == 0)
        UEvent->Option = UEvent->Select;
    else
        UEvent->Option = 0;
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   
 * @note        
 * @par         
 *******************************************************************************
 */
volatile uint8_t gEC11_SWKey_PushPop = 0;  // 1:Push  0:Pop
void UserEvent_Decode(UEvent_HandleTypedef *UEvent)
{
    switch(RingBufferU8_ReadByte((RingBufferU8*)&gEventQueue))
    {
        case None :
            break;

        case ADCKEY_KEY11_Push:
        case EC11_KEY_Push:
            gEC11_SWKey_PushPop = 1;
            switch(UEvent->Menu){
                case MainMenu: // Main Menu
                    UEvent->Menu  = UEvent->Select;
                    UEvent->Select = 1;
                    UEvent->Option = 0;
                    break;

                case RGBMenu: // RGB LED Menu
                    if(UEvent->Select == 5) // Back
                    {
                        UEvent->Option = 0;
                        UEvent->Select = RGBMenu;
                        UEvent->Menu = MainMenu; // main Menu
                    }
                    else
                        MenuEnter(UEvent);
                        switch(UEvent->Option){
                            case 1:
                                API_RGBColor_Select(&RGB1, 255, 255, 255);
                                API_RGBMode_Select(&RGB1, RGB_Mode_SPECTRUM);
                                break;
                            case 2:
                                API_RGBColor_Select(&RGB1, 255, 255, 255);
                                API_RGBMode_Select(&RGB1, RGB_Mode_BREATH);
                                break;
                            case 3:
                                API_RGBColor_Select(&RGB1, 255, 255, 255);
                                API_RGBMode_Select(&RGB1, RGB_Mode_PULSING);
                                break;
                            case 4:
                                API_RGBColor_Select(&RGB1, 0, 0, 0);
                                API_RGBMode_Select(&RGB1, RGB_Mode_STATIC);
                                break;
                            case 5:
                                break;
                            default:
                                break;
                        }
                    break;

                case LCDMenu: // LCD Display Menu
                    if(UEvent->Select == 5) // Back
                    {
                        UEvent->Option = 0;
                        UEvent->Select = LCDMenu;
                        UEvent->Menu = MainMenu; // main Menu
                    }
                    else
                        MenuEnter(UEvent);
                        switch(UEvent->Option){
                            case 1: // Feature
                                UEvent->LCDPicture = 2;
                                break;

                            case 2: // Geonetic
                                UEvent->LCDPicture = 250;
                                break;

                            case 3: // Font
                                UEvent->LCDPicture = 254;
                                break;

                            case 4: // Logo
                                UEvent->LCDPicture = 1;
                                break;

                            default:
                                UEvent->LCDPicture = 0;
                                break;
                        }
                    break;

                case SoundMenu: // Sound Menu
                    if(UEvent->Select == 5) // Back
                    {
                        UEvent->Option = 0;
                        UEvent->Select = SoundMenu;
                        UEvent->Menu = 0; // main Menu
                    }
                    else
                        MenuEnter(UEvent);
                        switch(UEvent->Option){
                            case 2:     // Play
                                API_DAC_Output.SongsSelect = UEvent->SoundSelect;
                                API_DAC_StartOutput();
                                break;

                            case 3:     // STop
                                API_DAC_PauseOutput();                      // Pause DAC output
                                API_DAC_Output.State = ResetAudioState;
                                break;

                            default:
                                break;
                        }
                        break;

                case SettingMenu: // Setting
                    if(UEvent->Select == 4)
                    {
                        UEvent->Option = 0;
                        UEvent->Select = 4;
                        UEvent->Menu = MainMenu; // main Menu
                    }
                    else
                        MenuEnter(UEvent);
                        if(UEvent->Option == 3)
                            if(MGData_CTR.AP_Connect != 0)
                                USB_MGCTR_TriggerUpdateCalendar();
                    break;

                default:
                    break;
            }
            break;

        case ADCKEY_KEY_Pop:
        case EC11_KEY_Pop:
            gEC11_SWKey_PushPop = 0;
            switch(UEvent->Menu){
                case RGBMenu:
                    switch(UEvent->Option){
                        case 1:
                        case 2:
                        case 3:
                        case 4:
                            MenuEnter(UEvent);
                    break;
                    }
                break;

                case SoundMenu: // Sound Menu
                    switch(UEvent->Option){
                        case 2:// Play
                        case 3:// Stop
                            MenuEnter(UEvent);
                            break;

                        default:
                            break;
                    }
                    break;

                case SettingMenu: // Setting
                    switch(UEvent->Option){
                        case 3:// Sync Time
                            MenuEnter(UEvent);
                            break;
                        default :
                            break;
                    }
                    break;

                    default :
                        break;
            }
            break;

        case ADCKEY_KEY12_Push:
        case EC11_LEFTROTATE:
            if(gEC11_SWKey_PushPop == 0)
            {
                if(UEvent->Option == 0)
                {
                    UEvent->Select --;
                    switch(UEvent->Menu){
                        case MainMenu: // Main Menu
                        case SettingMenu: // Setting Menu
                                if((UEvent->Select >= 128) || (UEvent->Select == 0))
                                    UEvent->Select = 4;
                            break;
                        case RGBMenu: // RGB LED Menu
                        case LCDMenu: // LCD Display Menu
                        case SoundMenu: // Sound Menu
                                if((UEvent->Select >= 128) || (UEvent->Select == 0))
                                    UEvent->Select = 5;
                            break;
                        default:
                            break;
                    }
                }
                else
                {
                    switch(UEvent->Menu){
                        case RGBMenu:
                            switch(UEvent->Option){
                                case 1:
                                    UEvent->LEDPWMSpeed --;
                                    if(UEvent->LEDPWMSpeed >= 128)
                                        UEvent->LEDPWMSpeed = 10;
                                    break;
                                case 2:
                                    UEvent->LEDBreathingSpeed --;
                                    if(UEvent->LEDBreathingSpeed >= 128)
                                        UEvent->LEDBreathingSpeed = 11;
                                    break;
                                case 3:
                                    UEvent->LEDBLinkingSpeed --;
                                    if(UEvent->LEDBLinkingSpeed >= 128)
                                        UEvent->LEDBLinkingSpeed = 11;
                                    break;
                                default:
                                    break;
                            }
                            break;

                        case LCDMenu:
                            switch(UEvent->Option){
                                case 1:
                                    UEvent->LCDPicture --;
                                    if((UEvent->LCDPicture <= 1) || (UEvent->LCDPicture >= 128))
                                        UEvent->LCDPicture = 9;
                                    break;
                                case 2:
                                    UEvent->LCDPicture --;
                                    if(UEvent->LCDPicture < 247)
                                        UEvent->LCDPicture = 253;
                                    break;
                                case 3:
                                    UEvent->LCDPicture --;
                                    if(UEvent->LCDPicture < 254)
                                        UEvent->LCDPicture = 255;
                                    break;
                                case 4:
                                    if(UEvent->LCDPicture == 1)
                                        UEvent->LCDPicture = 10;
                                    else if(UEvent->LCDPicture == 10)
                                        UEvent->LCDPicture = 1;
                                    break;
                                default:
                                    break;
                            }
                            break;

                        case SoundMenu: // Sound
                            switch(UEvent->Option){
                                case 1: // Music
                                    UEvent->SoundSelect --;
                                    if((UEvent->SoundSelect == 0) || (UEvent->SoundSelect >= 128))
                                        UEvent->SoundSelect = 3;
                                    break;
                                case 4: // Volume
                                    UEvent->SoundVolume --;
                                    if((UEvent->SoundVolume == 0) || (UEvent->SoundVolume >= 128)) 
                                        UEvent->SoundVolume = 5;
                                    API_DAC_Output.AudioVolume = 5 - UEvent->SoundVolume;
                                    break;
                                default:
                                    break;
                            }
                            break;

                        case SettingMenu: // Setting Menu
                            switch(UEvent->Option){
                                case 1:
                                    UEvent->SetIdleTime --;
                                    if(UEvent->SetIdleTime >= 128)
                                        UEvent->SetIdleTime = 8;
                                    break;
                                case 2:
                                    UEvent->SetTempture --;
                                    if(UEvent->SetTempture > 128)
                                        UEvent->SetTempture = 1;
                                    break;
                                default:
                                    break;
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
            break;

        case ADCKEY_KEY10_Push:
        case EC11_RIGHTROTATE:
            if(gEC11_SWKey_PushPop == 0)
            {
                if(UEvent->Option == 0)
                {
                    UEvent->Select ++;
                    switch(UEvent->Menu){
                        case MainMenu: // Main Menu
                        case SettingMenu: // Setting Menu
                                if(UEvent->Select > 4)
                                    UEvent->Select = 1;
                            break;
                        case RGBMenu: // RGB LED Menu
                        case LCDMenu: // LCD Display Menu
                        case SoundMenu: // Sound Menu
                                if(UEvent->Select > 5)
                                    UEvent->Select = 1;
                            break;
                        default:
                            break;
                    }
                }
                else
                {
                    switch(UEvent->Menu){
                        case RGBMenu:
                            switch(UEvent->Option){
                                case 1:
                                    UEvent->LEDPWMSpeed ++;
                                    if(UEvent->LEDPWMSpeed > 10)
                                        UEvent->LEDPWMSpeed = 0;
                                    break;
                                case 2:
                                    UEvent->LEDBreathingSpeed ++;
                                    if(UEvent->LEDBreathingSpeed > 11)
                                        UEvent->LEDBreathingSpeed = 0;
                                    break;
                                case 3:
                                    UEvent->LEDBLinkingSpeed ++;
                                    if(UEvent->LEDBLinkingSpeed > 11)
                                        UEvent->LEDBLinkingSpeed = 0;
                                    break;
                                default:
                                    break;
                            }
                            break;
                        case LCDMenu:
                            switch(UEvent->Option){
                                case 1:
                                    UEvent->LCDPicture ++;
                                    if(UEvent->LCDPicture > 9)
                                        UEvent->LCDPicture = 2;
                                    break;
                                case 2:
                                    UEvent->LCDPicture ++;
                                    if(UEvent->LCDPicture >= 254)
                                        UEvent->LCDPicture = 247;
                                    break;
                                case 3:
                                    UEvent->LCDPicture ++;
                                    if(UEvent->LCDPicture == 0)
                                        UEvent->LCDPicture = 254;
                                    break;
                                case 4:
                                    if(UEvent->LCDPicture == 1)
                                        UEvent->LCDPicture = 10;
                                    else if(UEvent->LCDPicture == 10)
                                        UEvent->LCDPicture = 1;
                                    break;
                                default:
                                    break;
                            }
                            break;
                        case SoundMenu:
                            switch(UEvent->Option){
                                case 1:
                                    UEvent->SoundSelect ++;
                                    if(UEvent->SoundSelect > 3)
                                        UEvent->SoundSelect = 1;
                                    break;
                                case 4:
                                    UEvent->SoundVolume ++;
                                    if(UEvent->SoundVolume > 5)
                                        UEvent->SoundVolume = 1;
                                    API_DAC_Output.AudioVolume = 5 - UEvent->SoundVolume;
                                    break;
                                default:
                                    break;
                            }
                            break;

                        case SettingMenu: // Setting Menu
                            switch(UEvent->Option){
                                case 1:
                                    UEvent->SetIdleTime ++;
                                    if(UEvent->SetIdleTime > 8)
                                        UEvent->SetIdleTime = 0;
                                    break;
                                case 2:
                                    UEvent->SetTempture ++;
                                    if(UEvent->SetTempture > 1)
                                        UEvent->SetTempture = 0;
                                    break;
                                default:
                                    break;
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
            break;

        case ADCKEY_KEY0_Push:
            UEvent->Menu = RGBMenu;
            UEvent->Select = 1;
            UEvent->Option = 1;
            API_RGBColor_Select(&RGB1, 255, 255, 255);
            API_RGBMode_Select(&RGB1, RGB_Mode_SPECTRUM);
            break;

        case ADCKEY_KEY1_Push:
            UEvent->Menu = RGBMenu;
            UEvent->Select = 2;
            UEvent->Option = 2;
            API_RGBColor_Select(&RGB1, 255, 255, 255);
            API_RGBMode_Select(&RGB1, RGB_Mode_BREATH);
            break;

        case ADCKEY_KEY2_Push:
            UEvent->Menu = RGBMenu;
            UEvent->Select = 3;
            UEvent->Option = 3;
            API_RGBColor_Select(&RGB1, 255, 255, 255);
            API_RGBMode_Select(&RGB1, RGB_Mode_PULSING);
            break;

        case ADCKEY_KEY3_Push: // Multimedia Key 0
            //void USB_Audio_TriggerMultimediaControl(MultimediaFunction_TypeDef mFunction, MultimediaStatus_TypeDef MStatus)
            USB_Audio_TriggerMultimediaControl(AUDIO_MULTIMEDIA_VOLUME_UP, AUDIO_MULTIMEDIA_MAKE);
            MID_Delay(2);
            USB_Audio_TriggerMultimediaControl(AUDIO_MULTIMEDIA_VOLUME_UP, AUDIO_MULTIMEDIA_BREAK);
            break;

        case ADCKEY_KEY4_Push: // Multimedia Key 1
            USB_Audio_TriggerMultimediaControl(AUDIO_MULTIMEDIA_PLAY_PAUSE, AUDIO_MULTIMEDIA_MAKE);
            MID_Delay(2);
            USB_Audio_TriggerMultimediaControl(AUDIO_MULTIMEDIA_PLAY_PAUSE, AUDIO_MULTIMEDIA_BREAK);
            break;

        case ADCKEY_KEY5_Push: // Multimedia Key 2
            USB_Audio_TriggerMultimediaControl(AUDIO_MULTIMEDIA_VOLUME_DOWN, AUDIO_MULTIMEDIA_MAKE);
            MID_Delay(2);
            USB_Audio_TriggerMultimediaControl(AUDIO_MULTIMEDIA_VOLUME_DOWN, AUDIO_MULTIMEDIA_BREAK);
            break;

        case ADCKEY_KEY6_Push: // Sound Play / Stop
            if((UEvent->Menu == SoundMenu) && (UEvent->Select == 2))
            {
                UEvent->Menu = SoundMenu;
                UEvent->Select = 3;
                UEvent->Option = 3;
                API_DAC_PauseOutput();                      // Pause DAC output
                API_DAC_Output.State = ResetAudioState;
            }
            else
            {
                UEvent->Menu = SoundMenu;
                UEvent->Select = 2;
                UEvent->Option = 2;
                API_DAC_Output.SongsSelect = UEvent->SoundSelect;
                API_DAC_StartOutput();
            }
            break;

        case ADCKEY_KEY7_Push: // Song Select
            if((UEvent->Menu == SoundMenu) && (UEvent->Option == 1))
            {
                UEvent->SoundSelect ++;
                if(UEvent->SoundSelect > 3)
                    UEvent->SoundSelect = 1;
            }
            else
            {
                UEvent->Menu = SoundMenu;
                UEvent->Select = 1;
                UEvent->Option = 1;
            }
            break;

        case ADCKEY_KEY8_Push: // Return
            UEvent->Menu = MainMenu;
            UEvent->Select = gOldMenu;
            UEvent->Option = 0;
            break;

        default:
            break;
    }
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   
 * @note        
 * @par         
 *******************************************************************************
 */
void USB_MGCTR_UpdateCalendarCallback(uint8_t *CalendarData)
{
    //=========================================
    //Calendar update in :
    // Byte0 is Year low byte 
    // Byte1 is Year high byte
    // Byte2 is Month
    // Byte3 is Day
    // Byte4 is Hour
    // Byte5 is Minute
    // Byte6 is Second

    mRTC.Instance = RTC;
    mRTC.Init.RTC_CK_SEL = RTC_CLK_LS;         //RTC clock source select
    mRTC.Init.RTC_RLR = 0x00000000;             //RTC reload register set 0~0xFFFFFFFE, 0xFFFFFFFF  forbidden.
    mRTC.Init.HourFormat = RTC_HOURFORMAT_12;
    mRTC.sDate.Year = (((uint16_t)CalendarData[1]) << 8) | ((uint16_t)CalendarData[0]);
    mRTC.sDate.Month = (Month_TypeDef)(CalendarData[2] - 1);
    mRTC.sDate.Date = CalendarData[3];
    mRTC.sTime.Hours = CalendarData[4];
    mRTC.sTime.Minutes = CalendarData[5];
    mRTC.sTime.Seconds = CalendarData[6];
    MID_RTC_Init(&mRTC);
}

/**
 *******************************************************************************
 * @brief       
 * @details     
 * @return      
 * @exception   
 * @note        
 * @par         
 *******************************************************************************
 */
// IDLE Count + 1

// IDLE Count Clear

// IDLE Count Compare


