/*
Author : Qi tian cun
Date : 2021/02/22
*/

#include "Gauges.h"
#include "GaugesInterface.h"
#include "Data_VehicleSpeed\Data_VehicleSpeed.h"
#define  VEH_SPEED_CURVE_NUM         12u
uint16_t RevDispSpeed = 0u;
uint16_t RevTargetSpeed = 0u;
uint16_t RevCurrentSpeed = 0u;

typedef struct
{
    uint16_t InputSpeed; /* 外界输入车速或者频率计算车速 */
    uint16_t DispSpeed;  /* 指针显示或者数字显示车速 */
} VehSpeedCurve_t;

/*
10倍车速
关键点按照放大系数计算出来,其他值根据曲线分段性计算
如果不准就增加数组,调整VEH_SPEED_CURVE_NUM的数值
*/
const VehSpeedCurve_t VehSpeedCurve[ VEH_SPEED_CURVE_NUM ] =
{
    {0u   , 0u},
    {200u , 210u},
    {400u , 420u},
    {600u , 630u},
    {800u , 830u},
    {1000u, 1030u},
    {1200u, 1250u},
    {1400u, 1450u},
    {1600u, 1650u},
    {1800u, 1850u},
    {2000u, 2050u},
    {2200u, 2250u},
};

uint8_t  VehSpeedFindSector(uint16_t speed);
uint16_t VehSpeedAmplification(uint16_t Speed);

/*--------------------------------------------------------------------------
* Function Name  : VehSpeedFindSector
* Description    :
* Input          :
* Output         : None
* Return         : INT16U
* onther         : 此函数内容不可更改,如有问题及时反馈
--------------------------------------------------------------------------*/
uint8_t VehSpeedFindSector(uint16_t speed)
{
    uint8_t i = 0u;
    uint8_t Order = 0u;
    uint8_t SectorID = 0u;

    if (VehSpeedCurve[ 0u ].InputSpeed > VehSpeedCurve[ VEH_SPEED_CURVE_NUM - 1u ].InputSpeed)
    {
        Order = 0u;
    }
    else
    {
        Order = 1u;
    }

    for (i = 0u; i < (VEH_SPEED_CURVE_NUM - 1u); i++)
    {
        if (Order == 1u)
        {
            if (speed >= VehSpeedCurve[ i ].InputSpeed)
            {
                SectorID++;
            }
        }
        if (Order == 0u)
        {
            if (speed <= VehSpeedCurve[ i ].InputSpeed)
            {
                SectorID++;
            }
        }
    }
    return SectorID;
}

/*-------------------------------------------------------------------------
* Function Name  : VehSpeedAmplification
* Description    : 车速显示放大
* Input          : CAN或者频率计算车速
* Output         : 经过放大的车速
* Return         : None
* onther         : 此函数内容不可更改,如有问题及时反馈
--------------------------------------------------------------------------*/
uint16_t VehSpeedAmplification(uint16_t Speed)
{
    uint8_t  i            = 0u;
    uint8_t  SectorID     = 0u;
    uint32_t PerCentum    = 0u;
    uint8_t  ASCF         = 0u;
    uint32_t wTemp        = 0u;
    uint32_t DispSpeed    = 0u;
    uint8_t  validflag    = 1u;

    SectorID = VehSpeedFindSector(Speed);

    if (SectorID > (VEH_SPEED_CURVE_NUM - 1u))
    {
        validflag = 0u;
    }

    if (VEH_SPEED_CURVE_NUM < 2u)
    {
        validflag = 0u;
    }

    if (validflag == 1u)
    {
        if (VehSpeedCurve[ 1u ].InputSpeed > VehSpeedCurve[ 0u ].InputSpeed)
        {
            ASCF = 1u;
        }
        if (VehSpeedCurve[ 1u ].InputSpeed < VehSpeedCurve[ 0u ].InputSpeed)
        {
            ASCF = 2u;
        }

        if (ASCF == 1u)
        {
            for (i = 0u; i < (VEH_SPEED_CURVE_NUM - 2u); i++)
            {
                if ((VehSpeedCurve[ i ].InputSpeed < VehSpeedCurve[ i + 1u ].InputSpeed) || \
                        (VehSpeedCurve[ i ].DispSpeed > VehSpeedCurve[ i + 1u ].DispSpeed))
                {
                    validflag = 0u;
                    break;
                }
            }

            if (validflag == 1u)
            {
                wTemp = ((uint32_t)Speed - (uint32_t)(VehSpeedCurve[ SectorID - 1u ].InputSpeed));
                PerCentum = wTemp * 1000u;

                PerCentum = PerCentum / ((uint32_t)(VehSpeedCurve[ SectorID ].InputSpeed) - (uint32_t)(VehSpeedCurve[ SectorID - 1u ].InputSpeed));
            }
        }

        if (ASCF == 2u)
        {
            for (i = 0u; i < (VEH_SPEED_CURVE_NUM - 2u); i++)
            {
                if ((VehSpeedCurve[ i ].InputSpeed > VehSpeedCurve[ i + 1u ].InputSpeed) || \
                        (VehSpeedCurve[ i ].DispSpeed > VehSpeedCurve[ i + 1u ].DispSpeed))
                {
                    validflag = 0u;
                    break;
                }
            }

            if (validflag == 1u)
            {
                wTemp = (uint32_t)VehSpeedCurve[ SectorID - 1u ].InputSpeed - Speed;
                PerCentum = wTemp * 1000u;

                PerCentum = PerCentum / ((uint32_t)(VehSpeedCurve[ SectorID - 1u ].InputSpeed) - (uint32_t)(VehSpeedCurve[ SectorID ].InputSpeed));
            }
        }

        if (validflag == 1u)
        {
            wTemp = (uint32_t)(VehSpeedCurve[ SectorID ].DispSpeed) - (uint32_t)(VehSpeedCurve[ SectorID - 1u ].DispSpeed);
            wTemp = wTemp * PerCentum;

            wTemp += 500u; /* 四舍五入 */

            DispSpeed = wTemp / 1000u + (uint32_t)(VehSpeedCurve[ SectorID - 1u ].InputSpeed);
        }
    }

    return (uint16_t)(DispSpeed);
}
/**@brief Rev Speed Manage function处理怠速抖动问题
* @author TYW
* @param[in] 输入转速
* @param[Out] 经过处理的转速
* @since 1.0.0.0
*/
uint8_t RevJumpFlag = 0u;
uint16_t RevSpeedManage(uint16_t Speed)
{
    RevTargetSpeed = Speed;
    if (RevCurrentSpeed >= (RevTargetSpeed + 50u))
    {
        RevCurrentSpeed -= 50u;
    }
    else
    {
        if ((RevCurrentSpeed + 50u) <= RevTargetSpeed)
        {

            RevCurrentSpeed += 50u;
        }
        else
        {
            ;
        }
    }
    if ((RevTargetSpeed < 500u) || (RevTargetSpeed > 900u))
    {
        RevCurrentSpeed = RevTargetSpeed;
        RevDispSpeed = RevCurrentSpeed;
        RevJumpFlag = 0u;
    }
    else
    {
        if (RevJumpFlag == 0u)
        {
            RevJumpFlag = 1u;
            RevCurrentSpeed = RevTargetSpeed;
            RevDispSpeed = RevCurrentSpeed;
        }
        else
        {
            ;
        }
        if (RevCurrentSpeed % 100u == 0u)
        {
            RevDispSpeed = RevCurrentSpeed;
        }
        else
        {
            ;
        }
    }

    return RevDispSpeed;

}

/**@brief Cal Veh  Val function���㳵��
* @author TYW
* @param[in]
* @param[out] ����10������
* @since 1.0.0.0
*/

uint16_t Cal_Veh_Val(void)
{
    return (uint16_t)Speed_Get_ActualValue();
}