#include "Components.h"
#include "Driving_Information\Data_Time.h"

DataTimeStruct_st_t Time;

uint16_t u16EngineTimeCount;
uint8_t g_u8ID339flag = 0U;
uint8_t g_u8SixHoursCompensationFlag = 0U;

void Data_Time_KL30_Init(void)
{
    Time.SingleHour = 0U;
    Time.SingleHourHistory = 0U;
    Time.SingleMin = 0U;
    Time.TotalHour = 0U;
    Time.SingleValid = 0U;
    Time.KeepTimeCount = 0U;
    u16EngineTimeCount = 0U;
    g_u8ID339flag = 0U;
    g_u8SixHoursCompensationFlag = 1U;
}

void Data_Time_KL15_Init(void)
{
    uint16_t u16Result = 0U;
    uint32_t u32Data_read[1] = {0};
    Time.KeepTimeCount = 0U;
    u16EngineTimeCount = 0U;
    g_u8ID339flag = 0U;
    g_u8SixHoursCompensationFlag = 1U;
    #if (PART_NUMBER == G54_A01)
    for(uint8_t i = 0U; i < 3U; i++ )
    {
        u16Result = eeprom_ReadRecord(EEPROM_BLOCK_00, (uint8_t *)u32Data_read, 4);
        if(u16Result == 0x2U)
        {
            break;
        }
    }
    if (u32Data_read[0] == 0xFFFFFFFFU)
    {
        Time.TotalHour = 0U;
    }
    else if (u32Data_read[0] > 65535U)
    {
        u32Data_read[0] = 65535U;
        Time.TotalHour = u32Data_read[0];
    }
    else 
    {
        Time.TotalHour = u32Data_read[0];
    }
    #endif
}

void Data_Time_Single_Working_Hours(void)
{
    #if (PART_NUMBER == RMR42E_60)
        uint8_t Clock_all = 0;
        if ((Common_Get_IG_Sts() == COMMON_POWER_ON) && (Charge_OFF_Flag == 0) && (Get_CAN_Power_State() != KEY_OFF) && (Get_CAN_Power_State() != PKEY_ON) && (System_Indicator_CANFlag != 1))
        {
            Clock_all = Get_CAN_Num_MMCU_SingleWorkingHours();
            Time.SingleHour = Clock_all / 10U;
            Time.SingleMin = (Clock_all % 10U) * 6U;
            Time.SingleValid = 1;
        }
        else
        {
            Time.SingleValid = 0;
        }
    #else
        if (Get_CAN_Power_State() == KEY_ACC)
        {
            if(Time.KeepTimeCount >= SINGLE_MAX_TIME_SECOND)
            {
                Time.KeepTimeCount = SINGLE_MAX_TIME_SECOND;
            }
            Time.SingleHour = (uint8_t)(Time.KeepTimeCount / 3600U);
            Time.SingleMin = (uint8_t)((Time.KeepTimeCount % 3600U) / 60U);
            Time.SingleValid = 1;
            if (Time.SingleHour != Time.SingleHourHistory)
            {
                /*时钟误差，每小时补偿1s*/
                Time.KeepTimeCount ++;
                Time.SingleHourHistory = Time.SingleHour;
            }

            /*每6小时再多补偿1s*/
            if (((Time.SingleHour % 6U) == 0U) && (Time.SingleHour != 0U))
            {
                if (g_u8SixHoursCompensationFlag == 1U)
                {
                    Time.KeepTimeCount ++;
                    g_u8SixHoursCompensationFlag = 0U;
                }
            }
            else 
            {
                g_u8SixHoursCompensationFlag = 1U;
            }
        }
        else 
        {
            Time.SingleHour = 0U;
            Time.SingleMin = 0U;
            Time.SingleValid = 0U;
        }
        
    #endif
}

uint32_t u32Data_read[1] = {0};
uint32_t CumulativeWorkHours_Writeback = 0;
uint32_t CumulativeWorkHours_readDiffer = 0;
uint8_t CumulativeWorkHours_MAX_flag = 0;
void Data_Time_Total_Working_Hours(void)
{
    #if (PART_NUMBER == RMR42E_60)
    uint32_t u32Data[1] = {0};
    eeprom_ReadRecord(EEPROM_BLOCK_00, (uint8_t *)u32Data_read, 4);
    if (u32Data_read[0] > 99999)
    {
        u32Data[0] = 99999;
        eeprom_WriteRecord(EEPROM_BLOCK_00, (uint8_t *)u32Data, 4);
        CumulativeWorkHours_MAX_flag = 1;
    }
    else
    {
        CumulativeWorkHours_MAX_flag = 0;
    }
    Time.TotalHour = u32Data_read[0];
    #else
    uint16_t u16Result = 0U;
    uint32_t AccumulatedWorkHours = 0U;
    
    if ((CAN_MSG_Status(&CAN_CH0_CanMsgOp, Co_Can_ConvertSubID_CAN_CH0(CAN_CH0_ID_CAN_0x339_Msg)) == CAN_SIG_NORMAL) && (g_u8ID339flag == 1U))
    {
        AccumulatedWorkHours = (uint32_t) Get_CAN_CH0_ID_339_Sig_MMCU_AccumulatedWorkHours();
        if(AccumulatedWorkHours != Time.TotalHour)
        {
            Time.TotalHour = AccumulatedWorkHours;
            u32Data_read[0] = AccumulatedWorkHours;
            for(uint8_t i = 0U; i < 3U; i++ )
            {
                u16Result = eeprom_WriteRecord(EEPROM_BLOCK_00, (uint8_t *)u32Data_read, 4);
                if(u16Result == 0x2U)
                {
                    break;
                }
            }
        }
    }
    #endif
}

void Data_CumulativeWorkHours_EEPROM_Write(void)
{
    #if (PART_NUMBER == RMR42E_60)
    uint32_t CurrentData = 0;
    uint32_t u32Data[1] = {0};
    if ((Common_Get_IG_Sts() == COMMON_POWER_ON) && (Charge_OFF_Flag == 0) && (Get_CAN_Power_State() != KEY_OFF) && (Get_CAN_Power_State() != PKEY_ON) && (System_Indicator_CANFlag != 1))
    {
        CurrentData = Get_CAN_Num_MMCU_AccumulatedWorkHours();
        if (CumulativeWorkHours_MAX_flag == 0)
        {
            if (CurrentData > CumulativeWorkHours_Writeback)
            {
                CumulativeWorkHours_readDiffer = CurrentData - CumulativeWorkHours_Writeback;
                eeprom_ReadRecord(EEPROM_BLOCK_00, (uint8_t *)u32Data_read, 4);
                u32Data[0] = u32Data_read[0] + CumulativeWorkHours_readDiffer;
                eeprom_WriteRecord(EEPROM_BLOCK_00, (uint8_t *)u32Data, 4);
                CumulativeWorkHours_Writeback = CurrentData;
            }
            else if (CurrentData < CumulativeWorkHours_Writeback)
            {
                CumulativeWorkHours_readDiffer = CumulativeWorkHours_Writeback - CurrentData;
                eeprom_ReadRecord(EEPROM_BLOCK_00, (uint8_t *)u32Data_read, 4);
                u32Data[0] = u32Data_read[0] - CumulativeWorkHours_readDiffer;
                eeprom_WriteRecord(EEPROM_BLOCK_00, (uint8_t *)u32Data, 4);
                CumulativeWorkHours_Writeback = CurrentData;
            }
        }
        else
        {
            if (CumulativeWorkHours_Writeback != 0)
            {
                if (CurrentData < CumulativeWorkHours_Writeback)
                {
                    CumulativeWorkHours_readDiffer = CumulativeWorkHours_Writeback - CurrentData;
                    eeprom_ReadRecord(EEPROM_BLOCK_00, (uint8_t *)u32Data_read, 4);
                    u32Data[0] = u32Data_read[0] - CumulativeWorkHours_readDiffer;
                    eeprom_WriteRecord(EEPROM_BLOCK_00, (uint8_t *)u32Data, 4);
                }
                CumulativeWorkHours_Writeback = CurrentData;
            }
        }
    }
    #endif
}

/*发动机运行时间计时函数，为防止计时误差大，放在50μs中断中运行*/
void Single_Working_Hours_Count(void)
{
    #if (PART_NUMBER == G54_A01)
        
        if(g_ReadyStatus == 1U)
        {
            u16EngineTimeCount++ ;
            if(u16EngineTimeCount == 20000U)
            {
                Time.KeepTimeCount++;
                u16EngineTimeCount = 0U;
            }
        }
    #endif
}

/******************************************************************************
函数名：Get_SingleHour_Display
功  能：获取单次工作时长小时数函数
参  数：无
返回值：Time.SingleHour x1
******************************************************************************
注  意：该函数必须每 ms被调用一次
******************************************************************************/
uint8_t Get_SingleHour_Display(void)
{
    return Time.SingleHour;
}

/******************************************************************************
函数名：Get_SingleMin_Display
功  能：获取单次工作时长分钟数函数
参  数：无
返回值：Time.SingleMin x1
******************************************************************************
注  意：该函数必须每 ms被调用一次
******************************************************************************/
uint8_t Get_SingleMin_Display(void)
{
    return Time.SingleMin;
}

/******************************************************************************
函数名：Get_Single_Working_Hours_Status
功  能：获取单次工作时长状态函数
参  数：无
返回值：Time.SingleValid 0--无效， 1--有效
******************************************************************************
注  意：该函数必须每 ms被调用一次
******************************************************************************/
uint8_t Get_Single_Working_Hours_Status(void)
{
    return Time.SingleValid;
}

/******************************************************************************
函数名：Get_Total_Working_Hours
功  能：获取累计工作时长函数
参  数：无
返回值：Time.TotalHour x10
******************************************************************************
注  意：该函数必须每 ms被调用一次
******************************************************************************/
uint32_t Get_Total_Working_Hours(void)
{
    return Time.TotalHour;
}

/******************************************************************************
函数名：Get_Clock_All_lenth
功  能：获取累计工作时长数值长度函数
参  数：无
返回值：num x1
******************************************************************************
注  意：该函数必须每 ms被调用一次
******************************************************************************/
uint8_t Get_Clock_All_lenth(void)
{
    uint8_t num = 0;
    if (Time.TotalHour > 999)
    {
        num = 2;
    }
    else if (Time.TotalHour > 9)
    {
        num = 1;
    }
    return num;
}

