#include "BackgroundLight.h"
#include "BGLInterface.h"
uint16_t IgnOffKeepMs;
uint16_t IgnOnKeepMs;
uint8_t BGLCurIgnSt = BGL_IGN_OFF;
uint8_t BGLWakeupSt = 0u;
BACKLIGHT_PARA BackLightPara[BACKLIGHT_TOTAL];
uint8_t CurBacklightLv = BACKLIGHT_LV100;
static uint8_t BackLightLevelNTC[3] = {100, 80, 40};
uint8_t CurBackLightAdjustNum = 0u;
uint8_t BackLightDerating = 0u;
uint8_t CurBackLightAdjustValid = 0u;
uint16_t BackLightModifyTimer[BACKLIGHT_TOTAL] = {0};
uint16_t ThermistorList[5];
uint16_t ThermistorIndex;
uint16_t ThermistorCurValue;
uint8_t BLEffectFlag = 0u;
uint16_t BackupsDuty[BACKLIGHT_TOTAL] = {0};
void SetBackLightOutput(uint8_t n, uint16_t val)
{
    BGLPwm_Config(n, val);
}

void SetBacklightDestVal(uint8_t n, const uint16_t val)
{

    BackLightPara[n].DestBackLightDuty = val;
}

void SetBacklightCurVal(uint8_t n, uint16_t val)
{

    BackLightPara[n].CurBackLightDuty = val;
}

void SetBacklightMinVal(uint8_t n, uint16_t val)
{

    BackLightPara[n].BackLightDutyMin = val;
}
/**@brief Back Ground  Light walk function
 * @author TYW
 * @param[in] TimeX 时间
 * @since 1.0.0.0
 */
uint16_t NTCUpdateTime = 0u;
void BackLightDamp(uint8_t TimeX)
{
    uint16_t tmpval = 0u;
    uint8_t TmpStep;
    uint8_t i = 0u;
    uint16_t LcdDownDelay = 0u;
    TmpStep = 1u;
    if (BGLCurIgnSt == BGL_IGN_ON)
    {
        LcdDownDelay = 400u;
        TmpStep = 5u;
    }
    else
    {
        LcdDownDelay = 2u;
        TmpStep = 5u;
    }

    if (NTCUpdateTime < 1000u)
    {
        NTCUpdateTime += TimeX;
    }
    else
    {
        CurBackLightAdjustValid = 1u;
        NTCUpdateTime = 0u;
    }
    if ((BGLCurIgnSt == BGL_IGN_ON) || (BGLWakeupSt))
    {
        if (IgnOnKeepMs < 60000u)
        {
            IgnOnKeepMs += TimeX;
        }
        else
        {
            ;
        }
        IgnOffKeepMs = 0u;
    }
    else
    {
        IgnOnKeepMs = 0u;
        if (IgnOffKeepMs < 60000u)
        {
            IgnOffKeepMs += TimeX;
        }
        else
        {
            ;
        }
    }
    if ((IgnOnKeepMs > IGN_ON_BACK_LIGHT_DELAY_MS) || (IgnOffKeepMs > IGN_ON_BACK_LIGHT_DELAY_MS))
    {
        for (i = 0u; i < BACKLIGHT_TOTAL; i++)
        {
            if (BackLightModifyTimer[i] > TimeX)
            {
                BackLightModifyTimer[i] -= TimeX;
            }
            else
            {
                BackLightModifyTimer[i] = 0u;
            }
            if (BackLightModifyTimer[i] == 0u)
            {
                if (BLEffectFlag == BGL_GRADUAL)
                {

                    if (BackLightPara[i].CurBackLightDuty < BackLightPara[i].DestBackLightDuty)
                    {

                        BackLightModifyTimer[i] = (uint16_t)(400u / (BackLightPara[i].DestBackLightDuty - BackLightPara[i].CurBackLightDuty) + 2u);
                        if ((BackLightPara[i].DestBackLightDuty - BackLightPara[i].CurBackLightDuty) >= TmpStep)
                        {
                            BackLightPara[i].CurBackLightDuty += TmpStep;
                        }
                        else
                        {
                            BackLightPara[i].CurBackLightDuty = BackLightPara[i].DestBackLightDuty;
                        }
                    }
                    else if (BackLightPara[i].CurBackLightDuty > BackLightPara[i].DestBackLightDuty)
                    {
                        BackLightModifyTimer[i] = (uint16_t)(LcdDownDelay / (BackLightPara[i].CurBackLightDuty - BackLightPara[i].DestBackLightDuty) + 2u);
                        if ((BackLightPara[i].CurBackLightDuty - BackLightPara[i].DestBackLightDuty) >= TmpStep)
                        {

                            BackLightPara[i].CurBackLightDuty -= TmpStep;
                        }
                        else
                        {
                            BackLightPara[i].CurBackLightDuty = BackLightPara[i].DestBackLightDuty;
                        }
                    }
                    else
                    {
                        BackLightModifyTimer[i] = 2u;
                    }
                }
                else
                {
                    BackLightPara[i].CurBackLightDuty = BackLightPara[i].DestBackLightDuty;
                }
                tmpval = BackLightPara[i].CurBackLightDuty;

                if (tmpval < BackLightPara[i].BackLightDutyMin)
                {
                    tmpval = BackLightPara[i].BackLightDutyMin;
                    BackLightModifyTimer[i] = 2u;
                }
                else
                {
                    ;
                }

                if (((BackLightPara[i].CurBackLightDuty != BackupsDuty[i])) || (BackLightPara[i].CurBackLightDuty == 0u))
                {
                    if (BackLightPara[i].CurBackLightDuty == 0u)
                    {
                        tmpval = 0u;
                    }
                    else
                    {
                        ;
                    }

                    SetBackLightOutput(i, tmpval);
                }
                else
                {
                    ;
                }
                BackupsDuty[i] = BackLightPara[i].DestBackLightDuty;
            }
        }
    }
    else
    {
        ;
    }
}

/*-------------------------------------------------------------------------
* Function Name  : App_SwapShort
* Description    : ½»»»Êý¾Ý
* Input          : None
* Output         : None
* Return         : None
* onther         : qitiancun 2018-9-10
--------------------------------------------------------------------------*/
void AD_SwapShort(uint16_t *pData1, uint16_t *pData2)
{
    uint16_t psw;
    if ((*pData1) > (*pData2))
    {
        psw = (*pData2);
        (*pData2) = (*pData1);
        (*pData1) = psw;
    }
}

/*-------------------------------------------------------------------------
* Function Name  : App_SortShort
* Description    :
* Input          : None
* Output         : None
* Return         : None
* onther         : qitiancun 2018-9-10
--------------------------------------------------------------------------*/
void AD_SortShort(uint16_t SortData[], uint8_t len)
{
    uint8_t n = 0u, m;
    for (; n < len - 1u; n++)
    {
        for (m = n + 1u; m < len; m++)
        {
            AD_SwapShort(&SortData[n], &SortData[m]);
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : calculate_Thermistor
* Description   :
* Input      : None
* Output     : None
* Return     : None
* onther     : qitiancun 2018-9-10
--------------------------------------------------------------------------*/
uint16_t Calculate_Thermistor(BL_STATE_PARA BLFunStatePara)
{
    uint32_t resistance = 0u;
    uint32_t TmpNTCADMax = 0u;
    ThermistorList[ThermistorIndex] = BLFunStatePara.BL_User_NTC_AD;
    TmpNTCADMax = BLFunStatePara.BL_User_NTC_AD_MAX * 10u;
    ThermistorIndex++;
    ThermistorIndex = (ThermistorIndex + 1u) % 5u;

    AD_SortShort(ThermistorList, 5u);

    if ((ThermistorCurValue > (ThermistorList[2u] + 3u)) || ((ThermistorCurValue + 3u) < ThermistorList[2]))
    {
        ThermistorCurValue = ThermistorList[2];
    }
    /*
    ad        10K
    _____ = _____
    4096    10K + x

    (10K+x)*ad = 4096 * 10K

    ad * x= 40960K - 10K * ad
    x = (40960K - 10K * ad) /ad
    */
    if (ThermistorCurValue)
    {
        resistance = ((TmpNTCADMax - (10u * ThermistorCurValue)) * 100u) / ThermistorCurValue;
    }
    else
    {
        resistance = 7851u;
    }
    return (uint16_t)resistance;
}
void BackLightDeal_NTC(BL_USER_PARA BL_FunPara, BL_STATE_PARA BLFunStatePara)
{
    uint16_t tmpval;
    uint16_t NTCresistance;
    uint16_t BacklightTftDestVal;
    uint32_t tmpDestVal;
    NTCresistance = Calculate_Thermistor(BLFunStatePara);
    /* high temprature TFT decrease brightness*/
    if ((NTCresistance >= 1607u) && (NTCresistance <= 1712u))
    {
        CurBacklightLv = BACKLIGHT_LV80;
        BackLightDerating = 1u;
    }
    else if ((NTCresistance >= 217u) && (NTCresistance < 1407u))
    {
        CurBacklightLv = BACKLIGHT_LV40;
        BackLightDerating = 1u;
    }
    else if (NTCresistance > 1912u)
    {
        CurBacklightLv = BACKLIGHT_LV100;
        BackLightDerating = 0u;
        tmpval = BLFunStatePara.BL_User_Lvl;

        CurBackLightAdjustNum = (uint8_t)((tmpval * 100u) / BLFunStatePara.BL_User_Lvl_Total);
    }
    else
    {

        ;
    }

    if (CurBackLightAdjustValid == 1u)
    {
        CurBackLightAdjustValid = 0u;
        if (CurBackLightAdjustNum < BackLightLevelNTC[CurBacklightLv])
        {
            CurBackLightAdjustNum++;
        }
        else if (CurBackLightAdjustNum > BackLightLevelNTC[CurBacklightLv])
        {
            CurBackLightAdjustNum--;
        }
        else
        {
            /* Intentionally Empty */
        }
        if (CurBackLightAdjustNum > 100u)
        {
            CurBackLightAdjustNum = 100u;
        }
        if (CurBackLightAdjustNum < 40u)
        {
            CurBackLightAdjustNum = 40u;
        }
    }
    /* high temprature TFT decrease brightness end*/
    if (BackLightDerating == 1u)
    {
        tmpDestVal = BL_FunPara.BL_User_TFTDuty;
        BacklightTftDestVal = (uint16_t)(tmpDestVal * CurBackLightAdjustNum / 100u);
        SetBacklightDestVal(BL_TFT, BacklightTftDestVal);
    }
}
/*------------------------------------------------------------------------------
Description:  The main function of backlight deal.
Function   :
BackLightDeal
------------------------------------------------------------------------------*/
uint8_t PwmStopFlag[BACKLIGHT_TOTAL] = {0};

void BackLightDeal(BL_USER_PARA BL_FunPara, BL_STATE_PARA BLFunStatePara)
{
    uint8_t i = 0u;
    BGLCurIgnSt = BL_FunPara.BL_User_PowerSt;
    BGLWakeupSt = BL_FunPara.BL_User_WakeFlag;
    BLEffectFlag = BLFunStatePara.BL_User_effect;
    if ((BL_FunPara.BL_User_PowerSt == BGL_IGN_ON) && (IgnOnKeepMs <= IGN_ON_BACK_LIGHT_DELAY_MS))
    {
        SetBacklightDestVal(BL_TFT, BL_FunPara.BL_User_TFTDuty);
        SetBacklightCurVal(BL_TFT, BL_FunPara.BL_User_TFTDuty - 5u);
        SetBacklightDestVal(BL_DIAL, BL_FunPara.BL_User_GaugesDuty);
        // SetBacklightDestVal(BL_R, BL_FunPara.BL_User_RDuty);
        // SetBacklightDestVal(BL_G, BL_FunPara.BL_User_GDuty);
        // SetBacklightDestVal(BL_B, BL_FunPara.BL_User_BDuty);

        SetBacklightMinVal(BL_TFT, BL_FunPara.BL_User_TFTDuty_MIN);
        SetBacklightMinVal(BL_DIAL, BL_FunPara.BL_User_GaugesDuty_MIN);
        // SetBacklightMinVal(BL_R, BL_FunPara.BL_User_RDuty_MIN);
        // SetBacklightMinVal(BL_G, BL_FunPara.BL_User_GDuty_MIN);
        // SetBacklightMinVal(BL_B, BL_FunPara.BL_User_BDuty_MIN);

        BackupsDuty[BL_TFT] = 0u;
        BackupsDuty[BL_DIAL] = 0u;
        // BackupsDuty[BL_R]=0u;
        // BackupsDuty[BL_G]=0u;
        // BackupsDuty[BL_B]=0u;
        for (i = 0u; i < BACKLIGHT_TOTAL; i++)
        {

            BGLPwm_Start(i);
            PwmStopFlag[i] = 0u;
        }
    }

    else if (BL_FunPara.BL_User_PowerSt == BGL_IGN_ON)
    {

        SetBacklightDestVal(BL_TFT, BL_FunPara.BL_User_TFTDuty);
        SetBacklightDestVal(BL_DIAL, BL_FunPara.BL_User_GaugesDuty);
        // SetBacklightDestVal(BL_R, BL_FunPara.BL_User_RDuty);
        // SetBacklightDestVal(BL_G, BL_FunPara.BL_User_GDuty);
        // SetBacklightDestVal(BL_B, BL_FunPara.BL_User_BDuty);
    }
    else if ((BL_FunPara.BL_User_WakeFlag) && (BL_FunPara.BL_User_PowerSt == BGL_IGN_OFF))
    {
        if ((BL_FunPara.BL_User_WakeFlag & 0x01u) == 1u)
        {
            SetBacklightDestVal(BL_TFT, BL_FunPara.BL_User_TFTDuty);
            SetBacklightCurVal(BL_TFT, BL_FunPara.BL_User_TFTDuty - 5u);
        }
        else
        {
            SetBacklightDestVal(BL_TFT, 0u);
            SetBacklightCurVal(BL_TFT, 0u);
            BackupsDuty[BL_TFT] = 0u;
        }
        if ((BL_FunPara.BL_User_WakeFlag & 0x02u) == 2u)
        {
            SetBacklightDestVal(BL_DIAL, BL_FunPara.BL_User_GaugesDuty);
            SetBacklightCurVal(BL_DIAL, BL_FunPara.BL_User_GaugesDuty - 5u);
        }
        else
        {
            SetBacklightDestVal(BL_DIAL, 0u);
            BackupsDuty[BL_DIAL] = 0u;
        }

        // BackupsDuty[BL_R] = 0u;
        // BackupsDuty[BL_G] = 0u;
        // BackupsDuty[BL_B] = 0u;
        // SetBacklightDestVal(BL_R, 0u);
        // SetBacklightDestVal(BL_G, 0u);
        // SetBacklightDestVal(BL_B, 0u);
        /* for ( i = 0u; i < BACKLIGHT_TOTAL; i++)
         {
             if (BackLightPara[i].CurBackLightDuty == 0u)
             {
                 BGLPwm_Stop(i);
                 PwmStopFlag[i]=1u;
             }


         }*/
        for (i = 0u; i < BACKLIGHT_TOTAL; i++)
        {
            if ((BackLightPara[i].DestBackLightDuty != 0u) && (PwmStopFlag[i] == 1u))
            {
                BGLPwm_Start(i);
                PwmStopFlag[i] = 0u;
            }
        }
    }
    else
    {
        SetBacklightDestVal(BL_TFT, 0u);
        SetBacklightCurVal(BL_TFT, 0u);
        SetBacklightDestVal(BL_DIAL, 0u);
        // SetBacklightDestVal(BL_R, 0u);
        // SetBacklightDestVal(BL_G, 0u);
        // SetBacklightDestVal(BL_B, 0u);
        for (i = 0u; i < BACKLIGHT_TOTAL; i++)
        {
            if (BackLightPara[i].CurBackLightDuty == 0u)
            {
                if (IgnOffKeepMs > 400u)
                {

                    BGLPwm_Stop(i);
                    PwmStopFlag[i] = 1u;
                }
            }
        }
    }
    BackLightDeal_NTC(BL_FunPara, BLFunStatePara);
}