/**

* @file    Gauges.c
* @details Gauges management.
* @author     TYW_TianYu
* @date       2021-2-22
* @version A001
* @par Copyright (c):
*   TIANYOUWEI
* @par History:
*   version: author, date, desc\n
*/
#include "Gauges.h"
#define   GAUGES_TOTAL_NUM  8u
#define   GAUGES_INIT_TIME_MAX  3000u

uint16_t  GaugesCurrentPos[GAUGES_TOTAL_NUM] ;
uint16_t  BackupDestPostion[GAUGES_TOTAL_NUM];
uint16_t  GaugesDisPos[GAUGES_TOTAL_NUM];
uint16_t  GaugesDisDelay[GAUGES_TOTAL_NUM];
uint16_t  DestPostion[GAUGES_TOTAL_NUM];
uint16_t  GaugesStarMoveTimeMax[GAUGES_TOTAL_NUM];
uint8_t   DirecSign[GAUGES_TOTAL_NUM];
uint8_t   GaugesModuleType[GAUGES_TOTAL_NUM];
uint8_t   DisplayModeTmp[GAUGES_TOTAL_NUM];
uint16_t  GaugesInitTimes;
uint8_t   GaugesPowerState = 0u;
uint16_t  GaugesFreeSetTimes = 0u;
const uint16_t  Gauages_Init_Time_Max[2] = {3000, 6000};
uint8_t   ModeGaugesTestFlag[GAUGES_TOTAL_NUM] = {0u};
/*两套参数第一个是正常走行速度，第二个为快速走动8*/
const uint16_t GaugesDisDelayMax[2u][IndicatTypeTOtal] =
{

    /*StepperMotor  MotorGasType MotorTempType LCDGasType LEDOtherType GasType TempType 不同类型表头走行速度不同*/
    {0u,            20u,         20u,          40u,          2u,        20u,     200u},
    {0u,            0u,           0u,           2u,           2u,        2u,      5u},
};

/**@brief Query Sector function
* @author TYW
* @param[in] GParam  Gauge Struct
* @since 1.0.0.0
*/
uint8_t QuerySector(_GaugesInfoInit *GParam, uint8_t  DirecSignPara, uint8_t SubAscf)
{
    uint8_t i  = 0u;
    uint8_t SectorID = 0u;

    for (i = 0u; i < GParam->SectorNum - 1u; i++)
    {
        if (SubAscf == 1u)
        {
            if (DirecSignPara == 1u)
            {
                if (*GParam->GaugesDataIn >= GParam->ReferenceDataInUp[i])
                {
                    SectorID++;
                }
                else
                {
                    ;
                }
            }
            else
            {
                if (*GParam->GaugesDataIn >= GParam->ReferenceDataInDown[i])
                {
                    SectorID++;
                }
                else
                {
                    ;
                }
            }
        }
        else
        {
            if (DirecSignPara == 1u)
            {
                if (*GParam->GaugesDataIn <= GParam->ReferenceDataInUp[i])
                {
                    SectorID++;
                }
                else
                {
                    ;
                }
            }
            else
            {
                if (*GParam->GaugesDataIn <= GParam->ReferenceDataInDown[i])
                {
                    SectorID++;
                }
                else
                {
                    ;
                }
            }


        }
    }
    
    return SectorID;
}
/**@brief Get the target position Subfunction
* @author TYW
* @param[in] GParam  Gauge Struct
* @param[in] SubAscf
* @param[in] SectorID
* @param[in] DirecSignPara
* @since 1.0.0.0
*/

uint16_t GetGaugestargetPosSub( _GaugesInfoInit *GParam, uint8_t SubAscf, uint8_t SectorID, uint8_t DirecSignPara )
{
    uint16_t StepCnTmp       = 0u;
    uint32_t PerCentum    = 0u; /*DVAL???ù?ú?éADμ?°ù·?êy*100 */

    if ((SectorID > 0u) && (SectorID < (GParam->SectorNum)))
    {
        if (SubAscf == 1u)
        {
            if (DirecSignPara == 1u)
            {
                PerCentum = ((*GParam->GaugesDataIn - GParam->ReferenceDataInUp[SectorID - 1u]));
                PerCentum = PerCentum * 100u;
                PerCentum = PerCentum / (GParam->ReferenceDataInUp[SectorID] - GParam->ReferenceDataInUp[SectorID - 1u]);
            }
            else if (DirecSignPara == 2u)
            {
                PerCentum = ((*GParam->GaugesDataIn - GParam->ReferenceDataInDown[SectorID - 1u]));
                PerCentum = PerCentum * 100u;
                PerCentum = PerCentum / (GParam->ReferenceDataInDown[SectorID] - GParam->ReferenceDataInDown[SectorID - 1u]);
            }
            else
            {
                ;
            }
        }
        
        if (SubAscf == 2u)
        {
            if (DirecSignPara == 1u)
            {
                PerCentum = ((GParam->ReferenceDataInUp[SectorID - 1u] - *GParam->GaugesDataIn) );
                PerCentum = PerCentum * 100u;
                PerCentum = PerCentum / (GParam->ReferenceDataInUp[SectorID - 1u] - GParam->ReferenceDataInUp[SectorID]);
            }
            else if (DirecSignPara == 2u)
            {
                PerCentum = ((GParam->ReferenceDataInDown[SectorID - 1u] - *GParam->GaugesDataIn));
                PerCentum = PerCentum * 100u;
                PerCentum = PerCentum / (GParam->ReferenceDataInDown[SectorID - 1u] - GParam->ReferenceDataInDown[SectorID]);
            }
            else
            {
                ;
            }
        }
        if (GParam->GaugesType < LEDOtherType)
        {
            StepCnTmp = (uint16_t)(PerCentum * (GParam->ReferenceDataInOut[SectorID] - GParam->ReferenceDataInOut[SectorID - 1u])   / 100u + GParam->ReferenceDataInOut[SectorID - 1u]);
        }
        else
        {
            if ((GParam->GaugesType == FreeMoveType) || (GParam->GaugesType == LEDTempType))
            {

                StepCnTmp = (uint16_t)((PerCentum * (GParam->ReferenceDataInOut[SectorID] - GParam->ReferenceDataInOut[SectorID - 1u])) / 10u + (GParam->ReferenceDataInOut[SectorID - 1u] * 10u));
                if((PerCentum>0u)&&(PerCentum<10u))
                {
                    StepCnTmp=StepCnTmp+1u;
                }
                else
                {
                    ;
                }
            }   

            else
            {
              StepCnTmp = (uint16_t)((PerCentum * (GParam->ReferenceDataInOut[SectorID] - GParam->ReferenceDataInOut[SectorID - 1u]))  + (GParam->ReferenceDataInOut[SectorID - 1u] * 100u));
            }
        }
    }
    else
    {
        ;
    }

    return StepCnTmp;
}
/**@brief Gauges Forward Para Manage function
* @author TYW
* @param[in] GParam  Gauge Struct
* @param[in] DirecSignPara
* @since 1.0.0.0
*/

void GaugesForwardParaManage( _GaugesInfoInit *GParam, uint8_t DirecSignPara )
{
    if (DirecSignPara == 1u)
    {
        if (*GParam->GaugesDataIn >= GParam->ReferenceDataInUp[GParam->SectorNum - 1u])
        {
            *GParam->GaugesDataIn = GParam->ReferenceDataInUp[GParam->SectorNum - 1u];
        }
        else
        {
            ;
        }
        if (*GParam->GaugesDataIn <= GParam->ReferenceDataInUp[0u])
        {
            *GParam->GaugesDataIn = GParam->ReferenceDataInUp[0u];
        }
        else
        {
            ;
        }
    }
    else if (DirecSignPara == 2u)
    {
        if (*GParam->GaugesDataIn >= GParam->ReferenceDataInDown[GParam->SectorNum - 1u])
        {
            *GParam->GaugesDataIn = GParam->ReferenceDataInDown[GParam->SectorNum - 1u];
        }
        else
        {
            ;
        }
        if (*GParam->GaugesDataIn <= GParam->ReferenceDataInDown[0u])
        {
            *GParam->GaugesDataIn = GParam->ReferenceDataInDown[0u];
        }
        else
        {
            ;
        }
    }
    else
    {
        ;
    }
}

/**@brief Gauges Inversion Para Manage function
* @author TYW
* @param[in] GParam  Gauge Struct
* @param[in] DirecSignPara
* @since 1.0.0.0
*/

void GaugesInversionParaManage( _GaugesInfoInit *GParam, uint8_t DirecSignPara )
{
    if (DirecSignPara == 1u)
    {
        if (*GParam->GaugesDataIn <= GParam->ReferenceDataInUp[GParam->SectorNum - 1u])
        {
            *GParam->GaugesDataIn = GParam->ReferenceDataInUp[GParam->SectorNum - 1u];
        }
        if (*GParam->GaugesDataIn >= GParam->ReferenceDataInUp[0u])
        {
            *GParam->GaugesDataIn = GParam->ReferenceDataInUp[0u];
        }
    }
    else if (DirecSignPara == 2u)
    {
        if (*GParam->GaugesDataIn <= GParam->ReferenceDataInDown[GParam->SectorNum - 1u])
        {
            *GParam->GaugesDataIn = GParam->ReferenceDataInDown[GParam->SectorNum - 1u];
        }
        if (*GParam->GaugesDataIn >= GParam->ReferenceDataInDown[0u])
        {
            *GParam->GaugesDataIn = GParam->ReferenceDataInDown[0u];
        }
    }
    else
    {
        ;
    }
}
/**@brief Get the target position function
* @author TYW
* @param[in] GParam  Gauge Struct
* @since 1.0.0.0
*/
uint16_t GetGaugestargetPos( _GaugesInfoInit *GParam, uint8_t  DirecSignPara)
{
    uint8_t  SectorID     = 0u;
    uint16_t StepCn       = 0u;
    uint8_t  ParaDirection  = 0u;

    if (GParam->ReferenceDataInUp[GParam->SectorNum - 1u] > GParam->ReferenceDataInUp[0u])
    {
        ParaDirection = 1u;
        GaugesForwardParaManage( GParam, DirecSignPara );
    }
    else
    {
        ParaDirection = 2u;
        GaugesInversionParaManage(GParam, DirecSignPara);
    }

    if (DirecSignPara != 0u)
    {

        SectorID = QuerySector(GParam, DirecSignPara, ParaDirection);
        StepCn =  GetGaugestargetPosSub(GParam, ParaDirection, SectorID, DirecSignPara) ;
    }
    else
    {
        ;
    }

    return StepCn;
}
/**@brief Gauge Display Mode function
* @author TYW
* @param[in] GaugeNum  Gauge Postion
* @since 1.0.0.0
*/
void GetGaugesDisplayMode (uint8_t GaugesNum)
{
    if (GaugesCurrentPos[GaugesNum] < DestPostion[GaugesNum])
    {
        if ((DestPostion[GaugesNum] - GaugesCurrentPos[GaugesNum]) > 300u)
        {
            DisplayModeTmp[GaugesNum] = 1u;
        }
        else
        {
            ;
        }
    }
    else
    {
        if ((GaugesCurrentPos[GaugesNum] - DestPostion[GaugesNum]) > 300u)
        {
            DisplayModeTmp[GaugesNum] = 1u;
        }
        else
        {
            ;
        }
        if (GaugesInitTimes > (GaugesStarMoveTimeMax[GaugesNum] + Gauages_Init_Time_Max[ModeGaugesTestFlag[GaugesNum]]))
        {
            if (GaugesCurrentPos[GaugesNum] == DestPostion[GaugesNum])
            {
                DisplayModeTmp[GaugesNum] = 0u;
            }
            else
            {
                ;
            }
        }
        else
        {
            ;
        }
    }

}
/**@brief Gauge Moveing function
* @author TYW
* @param[in] GaugeNum  Gauge Postion
* @since 1.0.0.0
*/
void GaugeMoveing(uint8_t GaugesNum)
{
    uint16_t GaugesMoveTimesTmp;
    uint16_t MoveTypePara;
    uint16_t tmp;
    MoveTypePara = 100u;
    GaugesMoveTimesTmp = 0u;
    if (GaugesModuleType [GaugesNum] != StepperMotor)
    {
        tmp = (GaugesInitTimes < (GaugesStarMoveTimeMax[GaugesNum] + Gauages_Init_Time_Max[ModeGaugesTestFlag[GaugesNum]]));
        GetGaugesDisplayMode (GaugesNum);
        if ((GaugesModuleType [GaugesNum] == FreeMoveType) || (GaugesModuleType [GaugesNum] == LEDTempType))
        {
            if (ModeGaugesTestFlag[GaugesNum] && tmp)
            {
                GaugesMoveTimesTmp = 5u;
            }
            else
            {
                if (GaugesModuleType [GaugesNum] == FreeMoveType)
                {
                    GaugesMoveTimesTmp = GaugesFreeSetTimes;
                }
                else
                {
                   GaugesMoveTimesTmp = GaugesDisDelayMax[DisplayModeTmp[GaugesNum]][GaugesModuleType [GaugesNum]]; 
                }
            }
            MoveTypePara = 10u;
        }
        else
        {
            if (ModeGaugesTestFlag[GaugesNum] && tmp)
            {
                GaugesMoveTimesTmp = 2u;
            }
            else
            {
                GaugesMoveTimesTmp = GaugesDisDelayMax[DisplayModeTmp[GaugesNum]][GaugesModuleType [GaugesNum]];
            }

            MoveTypePara = 100u;
        }

        if (GaugesDisDelay[GaugesNum] >= GaugesMoveTimesTmp)
        {
            if (GaugesInitTimes > GaugesStarMoveTimeMax[GaugesNum])
            {
                if (GaugesCurrentPos[GaugesNum] < DestPostion[GaugesNum])
                {
                    GaugesCurrentPos[GaugesNum]++;
                }
                else if (GaugesCurrentPos[GaugesNum] > DestPostion[GaugesNum])
                {
                    GaugesCurrentPos[GaugesNum]--;
                }
                else
                {
                    ;
                }
            }
            else
            {
                ;
            }
            GaugesDisDelay[GaugesNum] = 0u;
        }
        else
        {
            ;
        }
        if (GaugesModuleType [GaugesNum] >= LEDOtherType)
        {
            if (GaugesCurrentPos[GaugesNum] % MoveTypePara == 0u)
            {
                GaugesDisPos[GaugesNum] = GaugesCurrentPos[GaugesNum] / MoveTypePara;
            }
            else
            {
                ;
            }
        }
        else
        {
            GaugesDisPos[GaugesNum] = GaugesCurrentPos[GaugesNum] ;
        }
    }
    else
    {
        GaugesDisPos[GaugesNum] = DestPostion[GaugesNum];
    }
}
/**@brief Gauge Schedule function
* @author TYW
* @param[in] GaugeNum  Gauge Postion
* @param[in] GParam  Gauge Struct
* @since 1.0.0.0
*/
void GaugeSchedule(uint8_t GaugesNum, _GaugesInfoInit *GParam)
{
    uint8_t tmp;
    if (GaugesPowerState == 0u)
    {
        *GParam->GaugesDataIn = 0u;
    }
    else
    {
        tmp = (GaugesInitTimes < (GaugesStarMoveTimeMax[GaugesNum] + Gauages_Init_Time_Max[0]));
        if (GParam->GaugesTestFlag && tmp)
        {

            if (GaugesInitTimes > 1500u)
            {
                *GParam->GaugesDataIn =  GParam->ReferenceDataInUp[0u];
            }
            else if (GaugesInitTimes > 0u)
            {
                *GParam->GaugesDataIn =  GParam->ReferenceDataInUp[GParam->SectorNum - 1u];
            }
            else
            {
                ;
            }
        }
        else
        {
            ;
        }
    }
    if ( BackupDestPostion[GaugesNum] < *GParam->GaugesDataIn)
    {
        DirecSign[GaugesNum] = 1u;
    }
    else if (BackupDestPostion[GaugesNum] > *GParam->GaugesDataIn)
    {
        DirecSign[GaugesNum] = 2u;
    }
    else
    {
        ;
    }

    BackupDestPostion[GaugesNum] = *GParam->GaugesDataIn;
    DestPostion[GaugesNum] = GetGaugestargetPos(GParam, DirecSign[GaugesNum]);
    GaugesModuleType [GaugesNum] = GParam->GaugesType;
    GaugesStarMoveTimeMax[GaugesNum] = GParam->GaugesStartTime;
    ModeGaugesTestFlag[GaugesNum] = GParam->GaugesTestFlag;

}
/**@brief Get Current Postion function
得到当前的显示步
* @author TYW
* @param[in] GaugeNum  Gauge Postion
* @since 1.0.0.0
*/

uint16_t GetGaugesCurrentPos(uint8_t GaugesNum)
{
    return GaugesDisPos[GaugesNum];
}
/**@brief Get Current Step function
得到格的内部小步
* @author TYW
* @param[in] GaugeNum  Gauge Postion
* @since 1.0.0.0
*/

uint16_t GetGaugesCurrentStep(uint8_t GaugesNum)
{
    return GaugesCurrentPos[GaugesNum];
}
/**@brief Gauge Init ON function
* @author TYW
* @param[in] GaugeNum  Gauge Postion
* @since 1.0.0.0
*/
void GaugesK15Init_ON(void)
{
    uint8_t i = 0u;
    GaugesInitTimes = 0u;
    for (i = 0u; i < GAUGES_TOTAL_NUM; i++)
    {
        DestPostion[i] = 0u;
        BackupDestPostion[i] = 0u;
        DirecSign[i] = 0u;
        GaugesCurrentPos[i] = 0u;
        GaugesDisPos[i] = 0u;
        GaugesDisDelay[i] = 0u;
        DisplayModeTmp[i] = 1u;
        GaugesStarMoveTimeMax[i] = 1u;
    }
    GaugesPowerState = 1u;
}
/**@brief Gauge Init OFF function
* @author TYW
* @param[in] GaugeNum  Gauge Postion
* @since 1.0.0.0
*/
void GaugesK15Init_OFF(void)
{
    uint8_t i = 0u;
    GaugesInitTimes = 0u;
    for (i = 0u; i < GAUGES_TOTAL_NUM; i++)
    {
        DestPostion[i] = 0u;
        BackupDestPostion[i] = 0u;
        DirecSign[i] = 0u;
        GaugesCurrentPos[i] = 0u;
        GaugesDisPos[i] = 0u;
        GaugesDisDelay[i] = 0u;
        DisplayModeTmp[i] = 1u;
        GaugesStarMoveTimeMax[i] = 1u;
    }
    GaugesPowerState = 0u;
}
/**@brief Gauges Time function
* @author TYW
* @param[in] Xms  Time Parameter
* @since 1.0.0.0
*/
void Gauges_Time_Xms_Count(uint8_t Xms)
{
    uint8_t i = 0u;
    for (i = 0u; i < GAUGES_TOTAL_NUM; i++)
    {
        if (GaugesCurrentPos[i] != DestPostion[i])
        {
            if (GaugesDisDelay[i] < 60000u)
            {
                GaugesDisDelay[i] += Xms;
            }
            else
            {
                ;
            }
        }
        else
        {
            GaugesDisDelay[i] = 0u;
        }
        GaugeMoveing(i) ;
    }
    if (GaugesPowerState == 1u)
    {
        if (GaugesInitTimes < 60000u)
        {
            GaugesInitTimes += Xms;
        }
        else
        {
            ;
        }
    }
    else
    {
        GaugesInitTimes = 0u;
    }
}
/**@brief Get Veh Dis Val function
* @author TYW
* @param[in] 目标步 表头初始化结构体
* @since 1.0.0.0
*/
uint16_t GetVehDisVal(uint16_t VehCurPos, _GaugesInfoInit *GParam)
{

    uint8_t  SectorID     = 0u;
    uint32_t PerCentum    = 0u;
    uint32_t StepCn       = 0u;
    uint8_t i             = 0u;

    for (i = 0u; i < GParam->SectorNum - 1u; i++)
    {

        if (VehCurPos >= GParam->ReferenceDataInOut[i])
        {
            SectorID++;
        }
    }

    PerCentum = ((VehCurPos - GParam->ReferenceDataInOut[SectorID - 1u]) );
    PerCentum = PerCentum * 1000u;
    PerCentum = PerCentum / (GParam->ReferenceDataInOut[SectorID] - GParam->ReferenceDataInOut[SectorID - 1u]);
    StepCn = (GParam->ReferenceDataInUp[SectorID] - GParam->ReferenceDataInUp[SectorID - 1u]) * PerCentum / 1000u + GParam->ReferenceDataInUp[SectorID - 1u];
    StepCn += 5u;
    return (uint16_t)(StepCn);
}
/**@brief Set Free Move Times function
* @author TYW
* @param[in]设置每步走动的时间
* @since 1.0.0.0
*/
void SetFreeMoveTimes(uint16_t GaugesMoveTimes)
{
    GaugesFreeSetTimes = GaugesMoveTimes;
}