#include "Communication_Over_CAN.h"
#include "System_Status_Monitor.h"
#include "SEG_DISPLAY.h"
#include "CAN_APP.h"
#include "Gauge_Display.h"
#include "Flash_synchronizer.h"
#include "RTE_TIME.h"
#include "RTC.h"
#include "Key.h"
#include "Services_TripA.h"
#include "Services_ODO.h"
#include "Common_Interface.h"
#include "Telltales_user.h"

RTC_Time_st_t RTCTimeCurrent;
extern uint32_t Factory_ClearOdo_Display_Flag;

const PowerSegMap_st_t PositivePowerSegMap [] = {
    {0u, 0u},
    {12u, 1u},
    {25u, 2u},
    {37u, 3u},
    {50u, 4u},
    {62u, 5u},
    {75u, 6u},
    {87u, 7u},
    {100u, 8u},
    {200u, 8u},

    {0xffffu, 0xffu},
};

const PowerSegMap_st_t NegativePowerSegMap [] = {
    {0u, 0x80u},
    {50u, 0x81u},
    {100u, 0x82u},
    {200u, 0x82u},

    {0xffffu, 0xffu},
};

const BatterySegMap_st_t batterySegMap [] = {
    {5u, 0u},
    {15u, 1u},
    {25u, 2u},
    {35u, 3u},
    {45u, 4u},
    {55u, 5u},
    {65u, 6u},
    {75u, 7u},
    {85u, 8u},
    {95u, 9u},
    {0xFEu, 10u},

    {0xffffu, 0xffu},
};


uint16_t PowerDisplayValue   = 0;
uint8_t  PowerDisplaySeg     = 0;
uint16_t BatteryDisplayValue = 0;
uint8_t  BatteryDisplaySeg   = 0;

//�ⲿ�¶�
uint16_t TEMPInvalidTime   = 0xffffu;
uint8_t  TEMPDisplayStatus = 0u;
uint8_t  TEMPDisplaySymbol = 0u;
uint8_t  TEMPDisplayValue  = 0u;

//��λ��˸����
uint8_t Gear_Flash_Count = 0;
static uint8_t Gear_keep_current = 0;

//�ϵ�ɨ�̿���
uint16_t PowerOn_Scan_Timing = 0;
uint16_t PowerOn_Scan_Flag   = 1;
//uint16_t Gauge_VSpeed_Display_Flag   = 0;
uint16_t Gauge_VSpeed_Display_Flag = 0;
/**************************************************************************
 * \brief      ���ٱ���ʾ����
 * \attention  �÷��������뱻ʵʱ����
 * \retval     ��
 ******************************************************************************/
void Gauge_VSpeed_Display(void)
{
    uint16_t VSpeedDisplayValue  = 0;
    // static uint16_t refresh_timer=0;
    if ( SYS_OPR_STAT_IGN_ON )
    {
        if ( Common_Get_Disp_V_Speed_Valid( ) == 1u )
        {
            //��ʾ����
            VSpeedDisplayValue = Common_Get_Disp_V_Speed( );
            if(Factory_ClearOdo_Display_Flag == 0)
            {
                if(Common_Get_Disp_V_Speed( ) >= 810)
                {
                    SEG_SET_VSpeed_NUM(FLASH_SYNC_1Hz, VSpeedDisplayValue/10);
                    Gauge_VSpeed_Display_Flag = 1;
                }
                else
                {
                    if(Gauge_VSpeed_Display_Flag == 1)
                    {
                        if(Common_Get_Disp_V_Speed( ) < 780)
                        {
                            SEG_SET_VSpeed_NUM(1u, VSpeedDisplayValue/10);
                            Gauge_VSpeed_Display_Flag = 0;
                        }
                        else
                        {
                            SEG_SET_VSpeed_NUM(FLASH_SYNC_1Hz, VSpeedDisplayValue/10);
                        } 
                    }
                    else
                    {
                        SEG_SET_VSpeed_NUM(1u, VSpeedDisplayValue/10);
                        Gauge_VSpeed_Display_Flag = 0;
                    }
                }     
            }  
        }
        else
        {
            //�ź�����������
            VSpeedDisplayValue = 0u;
            SEG_SET_VSpeed_NUM(2u, 0u);
            Gauge_VSpeed_Display_Flag = 0;
        }
    }
    else
    {
        // IGOFFʱ����
        VSpeedDisplayValue = 0u;
        SEG_SET_VSpeed_NUM(0u, 0u);
        Gauge_VSpeed_Display_Flag = 0;
    }
}

/**************************************************************************
 * \brief      ���ʱ���ʾ����
 * \attention  �÷��������뱻ʵʱ����
 * \retval     ��
 ******************************************************************************/

void Gauge_Power_Display(void)
{
    uint8_t  powerSegNum;
    uint16_t powerDisplayValue;
    uint8_t  powerDisplaySign;

    uint32_t powerCurrentValue;
    uint32_t powerRemainingAvailableValue;
    uint8_t  i;
    uint8_t  signFlag = 0;

    if ( SYS_OPR_STAT_IGN_ON )
    {
        if(Factory_ClearOdo_Display_Flag == 0)
        {
            if ( (CAN_MSG_Status(ID_can0x18FAB027_Msg_Count) == 0u) && (CAN_MSG_Status(ID_can0x18FAB327_Msg_Count) == 0u) )      
            {
                //��ȡ��ǰ����
                powerCurrentValue = Get_ID_18FAB027_Sig_VCUPTSysElecPwrInd( ) / 2u;

                powerDisplaySign  = Get_ID_18FAB027_Sig_VCUPTModeInd();

                //��ȡʣ����ù���??
                powerRemainingAvailableValue = Get_ID_18FAB327_Sig_VCU_PTResiduePwrInd( ) / 10u;

                //������ʾ�ٷֱ�
                if ( (powerCurrentValue == 0u) && (powerRemainingAvailableValue == 0u) )
                {
                    powerDisplayValue = 0;
                    powerSegNum       = 0;
                }
                else
                {
                    if ( powerDisplaySign != 1u ) 
                    {
                        signFlag = 0;
                        powerDisplayValue = powerCurrentValue * 100u / (powerCurrentValue + powerRemainingAvailableValue);

                        //�������������??
                        for ( i = 0; i < POSITIVE_POWER_SEG_MAP_MAX; i++ )
                        {
                            if ( powerDisplayValue <= PositivePowerSegMap [ i ].value )
                            {
                                powerSegNum = PositivePowerSegMap [ i ].segNum;
                                break;
                            }
                        }
                    }
                    else
                    {
                        signFlag = 1;
                        powerDisplayValue = powerCurrentValue;
                        //�����ʴ���100��100��ʾ
                        powerDisplayValue = powerDisplayValue * 100u / 40u;
                        if ( powerDisplayValue > 100 )
                        {
                           powerDisplayValue = 100;
                        }
                        //�������������??
                        for ( i = 0; i < NEGATIVE_POWER_SEG_MAP_MAX; i++ )
                        {
                            if ( powerDisplayValue <= NegativePowerSegMap [ i ].value )
                            {
                                powerSegNum = NegativePowerSegMap [ i ].segNum;
                                break;
                            }
                        }
                    }
                }

                //������ʾ
                if ( (powerSegNum != 0xffu) && (powerDisplayValue <= 100u) )
                {
                    //���ٹ����߼�
                    //ʵ�ʳ��٣�2km/h ʱ����ʾ����Ϊ0
                    // 2km/h��ʵ�ʳ��٣�7km/h����������ʾΪ0
                    //ʵ�ʳ��١�7km/h ʱ��������ʾ��
                    if ( (Common_Get_Act_V_Speed( ) < 20u) || ((Common_Get_Act_V_Speed( ) < 70u) && (powerDisplaySign == 1u)) )
                    {
                        SEG_SET_PowerDial(1u, 0u, 0u, 0u);
                    }
                    else
                    {
                        if(powerDisplayValue == 0)
                        {
                            SEG_SET_PowerDial(1u, powerSegNum, 0, powerDisplayValue);
                        }
                        else
                        {
                            SEG_SET_PowerDial(1u, powerSegNum, signFlag, powerDisplayValue);
                        }
                    }
                }
                else
                {
                    //�źŴ�����
                    SEG_SET_PowerDial(1u, 0u, 0u, 0u);
                }
            }
            else
            {
                //���ĵ��ߴ���
                SEG_SET_PowerDial(1u, 0u, 0u, 255u);
            }
        }
        
    }
    else
    {
        // IGOFF����
        SEG_SET_PowerDial(0u, 0u, 0u, 0u);
    }
}
/**************************************************************************
 * \brief      ��������ʾ����
 * \attention  �÷��������뱻ʵʱ����
 * \retval     ��
 ******************************************************************************/
void Gauge_Battery_Display(void)
{
    //uint16_t m_val;
    if ( SYS_OPR_STAT_IGN_ON )
    {
        if(Factory_ClearOdo_Display_Flag == 0)
        {
           if ( (CAN_MSG_Status(ID_can0x18FA40F4_Msg_Count) == 0u) && (Get_ID_18FA40F4_Sig_BMSBattSOC( ) != 0xff) )
            {
                //��ȡ����ʵ��ֵ
                 BatteryDisplayValue = Get_ID_18FA40F4_Sig_BMSBattSOC( ) * 4u / 10u;

                //�������������??
                //����
                if ( BatteryDisplayValue >= (batterySegMap [ BatteryDisplaySeg ].value + 2u) )
                {
                    BatteryDisplaySeg++;
                }
                //�½�
                if ( BatteryDisplaySeg > 0u )
                {
                    if ( BatteryDisplayValue <= (batterySegMap [ BatteryDisplaySeg - 1 ].value /* -2u*/) )
                    {
                        BatteryDisplaySeg--;
                    }
                }

                if(BatteryDisplayValue>=100)
                {
                    BatteryDisplayValue=100;
                }
                //������ʾ
                if ( BatteryDisplaySeg != 0xffu )
                {
                    if(BatteryDisplaySeg == 1)
                    {
                        SEG_SET_EleDial(1u, FLASH_SYNC_1Hz ? BatteryDisplaySeg : 0, BatteryDisplayValue);
                    }
                    else
                    {
                        SEG_SET_EleDial(1u, BatteryDisplaySeg, BatteryDisplayValue);
                    }
                }
                else
                {
                    //�źŴ�����
                    SEG_SET_EleDial(1u, 0u, 0u);
                }
            }
            else
            {
                //���ĵ��ߴ���

                SEG_SET_EleDial(1u, FLASH_SYNC_05Hz ? BatteryDisplaySeg : 0, BatteryDisplayValue);
            } 
        }
        
    }
    else
    {
        // IGOFF����
        SEG_SET_EleDial(0u, 0u, 0u);
    }
}

/**************************************************************************
 * \brief      ʱ����ʾ����
 * \attention  �÷��������뱻ʵʱ����
 * \retval     ��
 ******************************************************************************/
void Gauge_Clock_Display(void)
{
    if ( SYS_OPR_STAT_IGN_ON )
    {
        //��ȡʱ��
        RTCTimeCurrent.Hour   = Get_RTC_HOUR( );
        RTCTimeCurrent.Minute = Get_RTC_MINUTE( );

        //ʱ����ʾ
        if(Factory_ClearOdo_Display_Flag == 0)
        {
            SEG_SET_Clock(RTCTimeCurrent.Hour, RTCTimeCurrent.Minute, FLASH_SYNC_1Hz, 1, 1);
        }
        
    }
    else
    {
        SEG_SET_Clock(0, 0, 0, 0, 0);
    }

    //    //����ʱ��
    //    RTE_RTC_Set_Hour  (  RTCTimeCurrent.Hour  );
    //    RTE_RTC_Set_Minute(  RTCTimeCurrent.Minute   );
    //    RTE_RTC_Confirm_Overwrite();
}
/**************************************************************************
 * \brief      ��ʻ�����ʾ����??
 * \attention  �÷��������뱻ʵʱ����
 * \retval     ��
 ******************************************************************************/
void Gauge_DrivingRange_Display(void)
{
    uint16_t m_DTE;
    if ( SYS_OPR_STAT_IGN_ON )
    {
        if(Factory_ClearOdo_Display_Flag == 0)
        {
            if ( (CAN_MSG_Status(ID_can0x18FAB327_Msg_Count) == 0u) && (Get_ID_18FAB327_Sig_VCU_Cruisingdistance( ) <= 0xFAFFFFFF) )
            {
                m_DTE=Get_ID_18FAB327_Sig_VCU_Cruisingdistance( )>>3;
                if (m_DTE>=999)
                {
                    m_DTE=999;
                }            
                if(m_DTE < 10)            
                {
                    SEG_SET_DTE_NUM(2u, 0u);
                }
                else
                {
                    SEG_SET_DTE_NUM(1u, m_DTE);
                }           
            }
            else
            {
                //�쳣�źŴ���
                SEG_SET_DTE_NUM(2u, 0u);
            }
        }
        
    }
    else
    {
        SEG_SET_DTE_NUM(0u, 0u);
    }
}
/**************************************************************************
 * \brief      С�������ʾ����??
 * \attention  �÷��������뱻ʵʱ����
 * \retval     ��
 ******************************************************************************/
void Gauge_Trip_Display(void)
{
    if ( SYS_OPR_STAT_IGN_ON )
    {
        if(CAN_MSG_Status(ID_can0x18FEBF0B_Msg_Count) == 0u)
        {
            if(Factory_ClearOdo_Display_Flag == 0)
            {
                SEG_SET_TRIP_NUM(1u, Data_Read_TripA( ));
            }
            
        }
        else
        {
            SEG_SET_TRIP_NUM(2u, 0u);
        }
    }
    else
    {
        SEG_SET_TRIP_NUM(0u, 0u);
    } 
}

/**************************************************************************
 * \brief      ��������ʾ����
 * \attention  �÷��������뱻ʵʱ����
 * \retval     ��
 ******************************************************************************/
void Gauge_ODO_Display(void)
{
    if ( SYS_OPR_STAT_IGN_ON )
    {
        if(Factory_ClearOdo_Display_Flag == 0)
        {
           SEG_SET_ODO_NUM(1u, Data_ODO_Read( ) / 10u); 
        }
        
    }
        
    else
        SEG_SET_ODO_NUM(0u, 0u);
}

/**************************************************************************
 * \brief      ��λ��ʾ����
 * \attention  �÷��������뱻ʵʱ����
 * \retval     ��
 ******************************************************************************/
void Gauge_Gear_Display(void)
{
    uint8_t DisplayGear = 0u;

    if ( SYS_OPR_STAT_IGN_ON )
    {
        //�źŵ����ж�
        if ( CAN_MSG_Status(ID_can0x18FAB027_Msg_Count) == 0u )
        {
            //��ʾ��λ����
            switch ( Get_ID_18FAB027_Sig_VCUGearPositionInd( ) )
            {
                case 0xFCu:
                    DisplayGear = 3u;
                    Gear_keep_current = 3;
                    break;
                case 0xDFu:
                    DisplayGear = 1u;
                    Gear_keep_current = 1;
                    break;
                case 0xFDu:
                    DisplayGear = 0xFDu;
                    Gear_keep_current = 0xFDu;
                    break;
                case 0x7Du:
                    DisplayGear = 2u;
                    Gear_keep_current = 2;
                    break;
                default:
                    DisplayGear = 0u;
                    Gear_keep_current = 0;
                    break;
            }
            //�źţ��������� �ж�
            //if ( Get_ID_18FAB027_Sig_PMS_GearOperateErr( ) == 1u )
            //{
            //    if ( Gear_Flash_Count < 6 )
            //    {
            //        if ( (Gear_Flash_Count & 1u) == FLASH_SYNC_1Hz )
            //            Gear_Flash_Count++;
            //    }
            //}
            //else
            //{
            //    Gear_Flash_Count = 0;
            //}

            //��ʾ��λ
            //if ( (Gear_Flash_Count == 0u) || (Gear_Flash_Count >= 6u) )
            if(Factory_ClearOdo_Display_Flag == 0)
            {
                if((DisplayGear != 0xFDu)&&(DisplayGear != 0))
                {
                    SEG_SET_GEAR(1u, DisplayGear);
                }
                else if(DisplayGear == 0xFDu)
                {
                    SEG_SET_GEAR(1u, Gear_keep_current);
                }
                else
                {
                    SEG_SET_GEAR(0u, 0u);
                }
            }
            
        }
        else
        {
            //�źŵ��ߴ���
            SEG_SET_GEAR(0u, 0u);
        }
    }
    else
    {
        SEG_SET_GEAR(0u, 0u);
    }
}



/**************************************************************************
 * \brief      ���������ʾ����??
 * \attention  �÷��������뱻ʵʱ����
 * \retval     ��
 ******************************************************************************/
void Gauge_MaintenanceMileage_Display(void)
{
}
/**************************************************************************
 * \brief      �������յȼ���ʾ����
 * \attention  �÷��������뱻ʵʱ����
 * \retval     ��
 ******************************************************************************/

void Gauge_EnergyRecoveryLevel_Display(void)
{
    if ( SYS_OPR_STAT_IGN_ON )
    {
        if(Factory_ClearOdo_Display_Flag == 0)
        {
            EnergyRecovery_Key_val();
            EnergyRecovery0_Key_val();
            SEG_SET_L8_NUM(1u,EnergyRecovery_Level);    
        }
        
    }
    else
    {
        SEG_SET_L8_NUM(0u, 0u);
    }
}

// 30���ʼ��??
void Gauge_KL30_Init(void)
{
    TEMPInvalidTime   = 0xffffu;
    TEMPDisplayStatus = 0u;
    TEMPDisplaySymbol = 0u;
    TEMPDisplayValue  = 0u;
}

// 15���ʼ��??
void Gauge_KL15_Init(void)
{
    TEMPInvalidTime     = 0xffffu;
    TEMPDisplayStatus   = 0u;
    TEMPDisplaySymbol   = 0u;
    TEMPDisplayValue    = 0u;
    PowerOn_Scan_Timing = 0;
    PowerOn_Scan_Flag   = 1;
}

//����������
// 20ms����
void Gauge_Service(void)
{
    static uint16_t VSpeed_Count = 0u;

    if ( SYS_OPR_STAT_IGN_ON )
    {
        if(Factory_ClearOdo_Display_Flag == 0)
        {
            //�Լ�ɨ��
            if ( PowerOn_Scan_Flag == 1u )
            {
                //�Լ�ʱ���ۼ�
                PowerOn_Scan_Timing += 20;

                SEG_SET_Frame(1u);
                SEG_SET_GEAR(0u, 0u);
                SEG_SET_DTE_NUM(0u, 0u);
                SEG_SET_VSpeed_NUM(0u, 0u);
                SEG_SET_L8_NUM(0u, 0u);
                SEG_SET_ODO_NUM(0u, 0u);
                SEG_SET_TRIP_NUM(0u, 0u);
                SEG_SET_Clock(0u, 0u, 0u, 0u, 0u);


                if ( PowerOn_Scan_Timing <= (POWERON_SCAN_TIMER - 1000ul) / 2 )
                {
                    SEG_Scan_SET_EleDial(PowerOn_Scan_Timing * 10 / ((POWERON_SCAN_TIMER - 1000ul) / 2));
                    SEG_Scan_SET_PowerDial(PowerOn_Scan_Timing * 10 / ((POWERON_SCAN_TIMER - 1000ul) / 2));
                }
                else if ( PowerOn_Scan_Timing <= (POWERON_SCAN_TIMER - 1000ul) )
                {
                    SEG_Scan_SET_EleDial(10 - (PowerOn_Scan_Timing - ((POWERON_SCAN_TIMER - 1000ul) / 2)) * 10 / ((POWERON_SCAN_TIMER - 1000ul) / 2));
                    SEG_Scan_SET_PowerDial(10 - (PowerOn_Scan_Timing - ((POWERON_SCAN_TIMER - 1000ul) / 2)) * 10 / ((POWERON_SCAN_TIMER - 1000ul) / 2));
                }
                else if ( PowerOn_Scan_Timing <= POWERON_SCAN_TIMER )
                {
                    SEG_Scan_SET_EleDial(0u);
                    SEG_Scan_SET_PowerDial(0u);
                }
                else
                {
                    PowerOn_Scan_Flag = 0;
                }


            }
            else
            {
                //�߿�
                SEG_SET_Frame(1u);

                VSpeed_Count++;
                if ( VSpeed_Count >= 10u )
                {
                    Gauge_VSpeed_Display( );
                    VSpeed_Count = 0u;
                }
                Gauge_Power_Display( );
                Gauge_Battery_Display( );

                Gauge_Clock_Display( );
                Gauge_DrivingRange_Display( );
                Gauge_Trip_Display( );
                Gauge_ODO_Display( );
                Gauge_Gear_Display( );
                Gauge_MaintenanceMileage_Display( );
                Gauge_EnergyRecoveryLevel_Display( );
            }
        }
        
    }
    else
    {
        SEG_SET_Frame(0u);

        Gauge_VSpeed_Display( );

        Gauge_Power_Display( );
        Gauge_Battery_Display( );

        Gauge_Clock_Display( );
        Gauge_DrivingRange_Display( );
        Gauge_Trip_Display( );
        Gauge_ODO_Display( );
        Gauge_Gear_Display( );
        Gauge_MaintenanceMileage_Display( );
        Gauge_EnergyRecoveryLevel_Display( );
    }
}

typedef struct
{
    uint16_t Tempval;
    uint16_t ResVal;
}st_TempTab;

const st_TempTab TempTab[]=
{
    { 200, 1427 ,},//0
    { 250, 1081 ,},//1
    { 300,  822 ,},//2
    { 350,  632 ,},//3
    { 400,  489 ,},//4
    { 420,  437 ,},//5
    { 425,  427 ,},//6
    { 430,  416 ,},//7
    { 440,  396 ,},//8
    { 445,  391 ,},//9
    { 450,  380 ,},//10
    { 500,  298 ,},//11
    { 550,  234 ,},//12
    { 600,  186 ,},//13
    { 650,  150 ,},//14
    { 700,  120 ,},//15
    { 750,   98 ,},//16
    { 800,   80 ,},//17 
    { 850,   66 ,},//18 
    { 900,   54 ,},//19 
    { 950,   45 ,},//20 
    {1000,   38 ,},//21 
    {1050,   32 ,},//22 
    {1100,   27 ,},//23
    {1150,   26 ,},//24  
    {1200,   23 ,},//25 
};

uint32_t TempResBuffer [ 20 ];
uint32_t TempResPtr;
uint32_t TempResult;
uint32_t TempOut;
void     Temp_Calc_Init(void)
{
    memset(TempResBuffer, 0u, sizeof(TempResBuffer));
    TempResPtr = 0u;
    TempResult = 255u;
    TempOut    = 255u;
}

void Temp_Calc_Send(void)
{
    uint8_t i,j;
    uint8_t ret;
    //uint32_t tempTmpVal;
    //uint32_t tempResVal;
    if ( ADC_Read_Signal_Valid(ADC_CH_28_R) == 1u )
    {
        TempResBuffer [ TempResPtr ] = ADC_Conv_Single_Channel(ADC_CH_28_R);
        TempResPtr++;
        if ( TempResPtr >= 20u )
        {
            TempResult = 0u;
            for ( i = 0; i <= 20; i++ )
            {
                TempResult += TempResBuffer [ i ];
            }
            TempResult = TempResult / 20;
            TempResPtr = 0u;
        }
        if ( TempResult > TempTab [ 0 ].ResVal )
        {
            TempOut = 200u;
        }
        else if ( TempResult <= TempTab [ 25 ].ResVal )
        {
            TempOut = 1200u;
        }
        else
        {
            j=0;
            ret=0U;
            for ( ;; )
            {
                if ( TempResult > TempTab [ j ].ResVal )
                {
                    ret=1U;
                    break;
                }
                else
                {
                    j++;
                }
                if(j>25)
                {
                    ret=0U;
                    break;
                }
            }
            if(ret==1u)
            {
                //tempResVal=TempTab [ j-1 ].ResVal -TempTab [ j ].ResVal;
                //tempTmpVal=TempTab [ j ].Tempval -TempTab [ j-1 ].Tempval;

                //TempOut =TempTab [ j-1 ].Tempval+((tempTmpVal*(TempResult-TempTab [ j ].ResVal))/tempResVal);
                TempOut = TempTab [ j ].Tempval;
            }

        
        
        }
    }
}

uint32_t Get_Temp_Calc(void)
{
    return TempOut / 10u;
}


