#include "Telltales.h"
#include "Common_Interface.h"
#include "Line_In.h"
#include "Telltales_user.h"
#include "Sound_Scheduler.h"
#include "CAN_Communication_Matrix.h"
#include "System_Monitor.h"

LED_Operation_st LED_Operation;

void Telltales_Wakeup_Init(void)
{
    LED_Operation.IG_ON_Timer = 0U;
    LED_Operation.IG_OFF_Timer = 0U;
    LED_Operation.IG_Status = LED_PWR_OFF;
    LED_Operation.LED_CheckFinish = LED_CheckFinished;
    LED_Operation.LED_WorkPhase = LED_OFF_State;
    LED_Operation.LED_Judgment_Cbk = NULL;
    LED_Operation.LED_Execution_Cbk = NULL;
}

void Telltales_KL30_Init(void)
{
    LED_Operation.IG_ON_Timer = 0U;
    LED_Operation.IG_OFF_Timer = 0U;
    LED_Operation.IG_Status = LED_PWR_OFF;
    LED_Operation.LED_CheckFinish = LED_CheckFinished;
    LED_Operation.LED_WorkPhase = LED_OFF_State;
    LED_Operation.LED_Judgment_Cbk = NULL;
    LED_Operation.LED_Execution_Cbk = NULL;
}

void Telltales_KL15_Init(void)
{
    LED_Operation.IG_ON_Timer = 0U;
    LED_Operation.IG_OFF_Timer = 0U;
    LED_Operation.IG_Status = LED_PWR_ON;
    LED_Operation.LED_CheckFinish = LED_CheckNoFinish;
    LED_Operation.LED_WorkPhase = LED_ON_State;
    LED_Operation.LED_Judgment_Cbk = NULL;
    LED_Operation.LED_Execution_Cbk = NULL;

    TelltalesFlag_KL15_Init();
    LED_TurnLeft_Execution(0x01u);
    LED_TurnRight_Execution(0x01u);
}

void Telltales_SetPara(ExternalPara_st *Para)
{
    LED_Operation.IG_Status = Para->IG_Status;
    LED_Operation.LED_CheckFinish = Para->LED_CheckFinish;
    LED_Operation.IG_ON_Timer = Para->IG_ON_Timer;
    LED_Operation.IG_OFF_Timer = Para->IG_OFF_Timer;
}

uint8_t TimeOutOffSts;

void Telltales_Management(void)
{
    uint8_t u8Condition = Line_In_Get_Status(LINE_IN_ChargeWake);

    LED_Operation.IG_Status = Common_Get_IG_Sts();
    LED_Operation.IG_ON_Timer = Common_GetIgnOnTime();
    LED_Operation.IG_OFF_Timer = Common_GetIgnOffTime();
 
    if ((u8Condition/* || (Get_ID_18F141F3_Sig_BMS_ChgWrCntSts() == 0x55u)*/) && (System_FUN_KL15_Status_Get() == 0u))
    {
        TimeOutOffSts = 1u;
    }
    else
    {
        TimeOutOffSts = 0u;
    }
    
    if (LED_Operation.IG_Status == LED_PWR_ON) /* IG ON */
    {
        if (LED_Operation.LED_CheckFinish == LED_CheckFinished)
        {
            //LED_Operation.IG_ON_Timer = 0x7FFFFFFFUL; //20230816同步VE21自检灯偶发不自检问题
        }
        LED_Operation.LED_WorkPhase = LED_ON_State;
    }
    else
    {
        LED_Operation.LED_CheckFinish = LED_CheckFinished;
        LED_Operation.IG_ON_Timer = 0u;
        LED_Operation.LED_WorkPhase = LED_OFF_State;  /* IG OFF */
    }

    switch (LED_Operation.LED_WorkPhase)
    {
    case LED_OFF_State:/* IG OFF */
        Telltales_IGOFF_Work();
        break;
    case LED_ON_State:/* IG ON Self Check Finish */
        Telltales_IG_ON_Work();
        break;
    default:
        LED_Operation.LED_WorkPhase = LED_OFF_State;
        break;
    }
}

void Telltales_IG_ON_Work(void)
{
    uint16_t i;
    
    for (i=0u; i<LED_Max; i++)
    {
        if ((LED_Attribute[i].WorkSts == LED_IGN_ON) || (LED_Attribute[i].WorkSts == LED_IGN_ON_OFF))
        {
            if ((LED_Operation.IG_ON_Timer < LED_Attribute[i].CheckEnd) && \
                (LED_Operation.IG_ON_Timer >= Telltales_SelfCheckOffset + LED_Attribute[i].CheckStart))
            {
                if (LED_Attribute[i].isSelfCheck == SelfCheck)
                {
                    if (LED_Attribute[i].isExCheck == NoExterNalCheck)/*According to the Attribute Table*/
                    {
                        LED_Operation.u8LED_Status[i] = LED_ON;
                        LED_Operation.LED_Execution_Cbk = LED_Attribute[i].LED_Execution_Cbk;
                        if (LED_Operation.LED_Execution_Cbk != NULL)
                        {
                            LED_Operation.LED_Execution_Cbk(LED_Operation.u8LED_Status[i]);
                        }
                    }
                    else/*According to the external Signal*/
                    {
                        LED_Operation.LED_Judgment_Cbk = LED_Attribute[i].LED_Judgment_Cbk;
                        if (LED_Operation.LED_Judgment_Cbk != NULL)
                        {
                            LED_Operation.u8LED_Status[i] = LED_Operation.LED_Judgment_Cbk();
                        }
                        else
                        {
                            /*can not reach*/
                            LED_Operation.u8LED_Status[i] = LED_OFF;
                        }

                        LED_Operation.LED_Execution_Cbk = LED_Attribute[i].LED_Execution_Cbk;
                        
                        if (LED_Operation.LED_Execution_Cbk != NULL)
                        {
                            LED_Operation.LED_Execution_Cbk(LED_Operation.u8LED_Status[i]);
                        }
                    }
                }
                else
                {
                    if (LED_Attribute[i].isExCheck == NoExterNalCheck)
                    {
                        LED_Operation.u8LED_Status[i] = LED_OFF;
                        LED_Operation.LED_Execution_Cbk = LED_Attribute[i].LED_Execution_Cbk;
                        
                        if (LED_Operation.LED_Execution_Cbk != NULL)
                        {
                            LED_Operation.LED_Execution_Cbk(LED_Operation.u8LED_Status[i]);
                        }
                    }
                    else /*According to the external Signal*/
                    {
                        LED_Operation.LED_Judgment_Cbk = LED_Attribute[i].LED_Judgment_Cbk;
                        
                        if (LED_Operation.LED_Judgment_Cbk != NULL)
                        {
                            LED_Operation.u8LED_Status[i] = LED_Operation.LED_Judgment_Cbk();
                        }
                        else
                        {
                            /*can not reach*/
                            LED_Operation.u8LED_Status[i] = LED_OFF;
                        }

                        LED_Operation.LED_Execution_Cbk = LED_Attribute[i].LED_Execution_Cbk;
                        if (LED_Operation.LED_Execution_Cbk != NULL)
                        {
                            LED_Operation.LED_Execution_Cbk(LED_Operation.u8LED_Status[i]);
                        }
                    }
                }
            }
            else/* 大部分灯自检完了 剩余少部分自检灯仍然自检中   */
            {
                LED_Operation.LED_Judgment_Cbk = LED_Attribute[i].LED_Judgment_Cbk;
                
                if (LED_Operation.LED_Judgment_Cbk != NULL)
                {
                    LED_Operation.u8LED_Status[i] = LED_Operation.LED_Judgment_Cbk();
                }
                else
                {
                    /*can not reach*/
                    LED_Operation.u8LED_Status[i] = LED_OFF;
                }

                LED_Operation.LED_Execution_Cbk = LED_Attribute[i].LED_Execution_Cbk;
                
                if (LED_Operation.LED_Execution_Cbk != NULL)
                {
                    LED_Operation.LED_Execution_Cbk(LED_Operation.u8LED_Status[i]);
                }
            }
        }
        else
        {
            LED_Operation.u8LED_Status[i] = LED_OFF;
            LED_Operation.LED_Execution_Cbk = LED_Attribute[i].LED_Execution_Cbk;
            
            if (LED_Operation.LED_Execution_Cbk != NULL)
            {
                LED_Operation.LED_Execution_Cbk(LED_Operation.u8LED_Status[i]);
            }
        }
    }
}

void Telltales_IGOFF_Work(void)
{
    uint16_t i = 0u;
    
    for (i=0u; i<LED_Max; i++)
    {
        if ((LED_Attribute[i].WorkSts == LED_IGN_OFF) || (LED_Attribute[i].WorkSts == LED_IGN_ON_OFF))
        {
            LED_Operation.LED_Judgment_Cbk = LED_Attribute[i].LED_Judgment_Cbk;
            
            if (LED_Operation.LED_Judgment_Cbk != NULL)
            {
                LED_Operation.u8LED_Status[i] = LED_Operation.LED_Judgment_Cbk();
            }
            else
            {
                /*can not reach*/
                LED_Operation.u8LED_Status[i] = LED_OFF;
            }

            LED_Operation.LED_Execution_Cbk = LED_Attribute[i].LED_Execution_Cbk;
            
            if (LED_Operation.LED_Execution_Cbk != NULL)
            {
                LED_Operation.LED_Execution_Cbk(LED_Operation.u8LED_Status[i]);
            }
        }
        else    /* ON ������ OFF��ҪϨ��  */
        {
            LED_Operation.u8LED_Status[i] = LED_OFF;
            LED_Operation.LED_Execution_Cbk = LED_Attribute[i].LED_Execution_Cbk;
            if (LED_Operation.LED_Execution_Cbk != NULL)
            {
                LED_Operation.LED_Execution_Cbk(LED_Operation.u8LED_Status[i]);
            }
        }
    }
}

uint8_t Telltales_Get_LedStatus(LED_Idx_t u8Index)
{
    uint8_t u8LedStatus;
    if (u8Index<LED_Max)
    {
        u8LedStatus = LED_Operation.u8LED_Status[u8Index];
    }
    else
    {
        u8LedStatus =0u;
    }
    
    return u8LedStatus;
}