/**
 * @file hv_mw_OsdDynamicUpdate.c
 * @brief osd component update c file.
 * @details This file provides the following functions: \n
 *          (1) Osd component update by userdata functions \n
 *          (2) Osd component update customize functions \n
 *
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2022-09-01
 * @copyright Copyright(c),2022-8, Hiview Software. All rights reserved.
 * @par History:
 * <table>
 * <tr><th>Author       <th>Date            <th>Change Description
 * <tr><td>shanpeng     <td>2022-09-01      <td>create
 * </table>
 */

#include "hv_app_OsdDynamicUpdate.h"
#include "hv_app_OsdDialog.h"
#include "hv_comm_DataBase.h"
#include "hv_mw_OsdDraw.h"
#include "hv_mw_OsdOperation.h"
#include "hv_mw_OsdLog.h"
#include "hv_mw_Factory.h"
#include "hv_app_Osd.h"
#include "hv_app_OsdFactory.h"

VOID Hv_App_Cb_OsdUpdateTextByUserdata(VOID *pstCpProp, USHORT16 usId, UserdataProp *pstUserdata)
{
    OsdText *pstText = (OsdText *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstText);
    HV_ASSERT_VALID_PTR_VOID(pstUserdata);
}

VOID Hv_App_Cb_OsdUpdateTextCustom(VOID *pstCpProp, USHORT16 usId)
{
    OsdText *pstText = (OsdText *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstText);
}

VOID Hv_App_Cb_OsdUpdateTextListByUserdata(VOID *pstCpProp, USHORT16 usId, UserdataProp *pstUserdata)
{
    OsdTextList *pstTextList = (OsdTextList *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstTextList);
    HV_ASSERT_VALID_PTR_VOID(pstUserdata);

    pstTextList->ucStringCurID = MIN((USHORT16)pstUserdata->sOsdValue, pstTextList->ucStringNum - 1);
}

VOID Hv_App_Cb_OsdUpdateTextListCustom(VOID *pstCpProp, USHORT16 usId)
{
    OsdTextList *pstTextList = (OsdTextList *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstTextList);

    switch (usId)
    {
        case TEXTLIST_INPUT_SCENE_INPUT_SOURCE_NORMAL:
        {
            pstTextList->ucStringCurID = MIN(Hv_App_GetOsdDataValue(E_USERDATA_VIDEO_SOURCE), pstTextList->ucStringNum - 1);
            break;
        }
#if 0
        case TEXTLIST_FREESYNC_SCENE_MAIN_NORMAL:
        {
            /* check input source for showing FreeSync or AdaptiveSync */
            if ((UD_VIDEO_SOURCE_V_HDMI == Hv_App_GetOsdDataValue(E_USERDATA_VIDEO_SOURCE)) ||
                (UD_VIDEO_SOURCE_V_VGA == Hv_App_GetOsdDataValue(E_USERDATA_VIDEO_SOURCE)))
            {
                /* FreeSync */
                pstTextList->ucStringCurID = 0;
            }
            else
            {
                /* AdaptiveSync */
                pstTextList->ucStringCurID = 1;
            }
            break;
        }
#endif
        default:
        {
            break;
        }
    }
}

VOID Hv_App_Cb_OsdUpdateNumberByUserdata(VOID *pstCpProp, USHORT16 usId, UserdataProp *pstUserdata)
{
    OsdNumber *pstNumber = (OsdNumber *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstNumber);
    HV_ASSERT_VALID_PTR_VOID(pstUserdata);

    pstNumber->iValue = pstUserdata->sOsdValue;
}

VOID Hv_App_Cb_OsdUpdateNumberCustom(VOID *pstCpProp, USHORT16 usId)
{
    OsdNumber *pstNumber = (OsdNumber *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstNumber);
}

VOID Hv_App_Cb_OsdUpdateAsciiStringByUserdata(VOID *pstCpProp, USHORT16 usId, UserdataProp *pstUserdata)
{
    OsdAsciiString *pstAsciiString = (OsdAsciiString *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstAsciiString);
    HV_ASSERT_VALID_PTR_VOID(pstUserdata);
}

/**
 * @brief 设置OSD菜单显示的timing字符串格式
 * @param[in] pstString 字符串指针
 * @param[in] usH 输入信号宽的值（像素点）
 * @param[in] usV 输入信号高的值（像素点）
 * @param[in] usHz 输入信号的刷新率（Hz）
 * @param[in] bIsVrr 是否为VRR
 * @param[in] bInterlacedMode 是否为Interlaced
 * @return 字符串长度
 */
static USHORT16 SetTimingInfoString(UCHAR8 *pstString, USHORT16 usH, USHORT16 usV, USHORT16 usHz, BOOL bIsVrr, BOOL bInterlacedMode)
{
    if (!bInterlacedMode)
    {
        if (bIsVrr)
        {
            return (pstString == NULL) ? 0 : HV_SNPRINTF(pstString, OSD_ASCII_STRING_LENGTH_MAX, "%dx%d@VRR", usH, usV);
        }
        else
        {
            return (pstString == NULL) ? 0 : HV_SNPRINTF(pstString, OSD_ASCII_STRING_LENGTH_MAX, "%dx%d@%dHz", usH, usV, usHz);
        }
    }
    else
    {
        if (bIsVrr)
        {
            return (pstString == NULL) ? 0 : HV_SNPRINTF(pstString, OSD_ASCII_STRING_LENGTH_MAX, "%dx%dI@VRR", usH, usV);
        }
        else
        {
            return (pstString == NULL) ? 0 : HV_SNPRINTF(pstString, OSD_ASCII_STRING_LENGTH_MAX, "%dx%dI@%dHz", usH, usV, usHz);
        }
    }
}

VOID Hv_App_Cb_OsdUpdateAsciiStringCustom(VOID *pstCpProp, USHORT16 usId)
{
    OsdAsciiString *pstAsciiString = (OsdAsciiString *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstAsciiString);

    if (pstAsciiString->uiDynamicFlag & DYN_RESOURCE)
    {
        UCHAR8 aucString[OSD_ASCII_STRING_LENGTH_MAX] = {0};
        UCHAR8 ucLen = 0;

        switch (usId)
        {
#if 0
            case CUSTOMSTRING_MODEL_SCENE_MAIN_NORMAL:
            {
                ucLen = HV_SNPRINTF(aucString, OSD_ASCII_STRING_LENGTH_MAX, "%s", HV_PROJECT_CONFIG_FACTORY_MONITOR_MODE);
                break;
            }
            case CUSTOMSTRING_SN_SCENE_MAIN_NORMAL:
            {
                FactoryDataDBRegion* pstFacData = Hv_Common_Db_GetFactoryDataDBRegionPtr();
                ucLen = HV_SNPRINTF(aucString, OSD_ASCII_STRING_LENGTH_MAX, "%s", pstFacData->acProductSn);
                break;
            }
            case CUSTOMSTRING_VERSION_SCENE_MAIN_NORMAL:
            {
                ucLen = Hv_App_OsdSetFirmwareVersionString(aucString);   //HV_PROJECT_CONFIG_FACTORY_FW_VERSION
                break;
            }
#endif
            case CUSTOMSTRING_RESOLUTION1_SCENE_MAIN_NORMAL:
            case CUSTOMSTRING_RESOLUTION2_SCENE_MAIN_NORMAL:
            case CUSTOMSTRING_INPUT_SCENE_INPUT_SOURCE_NORMAL:
            {
                USHORT16 usFrameRate = 0;
                if (CUR_TIMING_INFO(bIsVrr))
                {
                    usFrameRate = Hv_Mw_InputPort_GetCurrentFrameRate(CUR_TIMING_INFO(enPort));
                    if (CUR_TIMING_INFO(bInterlacedMode))
                    {
                        usFrameRate /= 2;
                    }
                    usFrameRate = (usFrameRate + 500) / 1000;
                }
                else
                {
                    usFrameRate = CUR_TIMING_INFO(usFrameRate);
                }

                ucLen = SetTimingInfoString(aucString, CUR_TIMING_INFO(usHActive), CUR_TIMING_INFO(usVActive),
                                        usFrameRate, HV_FALSE, CUR_TIMING_INFO(bInterlacedMode));
                break;
            }
            case CUSTOMSTRING_REFRESHRATE_SCENE_REFRESH_RATE_NORMAL:
            {
                UINT32 uiRefreshRate = Hv_Mw_InputPort_GetCurrentFrameRate(CUR_TIMING_INFO(enPort));
                if (CUR_TIMING_INFO(bInterlacedMode))
                {
                    uiRefreshRate /= 2;
                }
                if (CUR_TIMING_INFO(bIsVrr))
                {
                    ucLen = HV_SNPRINTF(aucString, OSD_ASCII_STRING_LENGTH_MAX, "%d.%03dHz", uiRefreshRate / 1000, uiRefreshRate % 1000);
                }
                else
                {
                    ucLen = HV_SNPRINTF(aucString, OSD_ASCII_STRING_LENGTH_MAX, "%dHz", (uiRefreshRate + 500) / 1000);
                }
                break;
            }
            default:
            {
                ucLen = Hv_App_OsdFactoryUpdateAsciiString(usId, aucString);
                break;
                //return;
            }
        }

        if (ucLen > 0)
        {
            for (UCHAR8 ucCount = 0; ucCount < ucLen; ucCount++)
            {
                pstAsciiString->ausString[ucCount] = (USHORT16)(aucString[ucCount]);
            }
            pstAsciiString->ucStringLength = ucLen;
        }
        OSD_LOG_DEBUG("Ascii string(%d): '%s' len=%d", usId, aucString, ucLen);
    }
}

VOID Hv_App_Cb_OsdUpdateIconByUserdata(VOID *pstCpProp, USHORT16 usId, UserdataProp *pstUserdata)
{
    OsdIcon *pstIcon = (OsdIcon *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstIcon);
    HV_ASSERT_VALID_PTR_VOID(pstUserdata);
}

VOID Hv_App_Cb_OsdUpdateIconCustom(VOID *pstCpProp, USHORT16 usId)
{
    OsdIcon *pstIcon = (OsdIcon *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstIcon);
}

VOID Hv_App_Cb_OsdUpdateIconListByUserdata(VOID *pstCpProp, USHORT16 usId, UserdataProp *pstUserdata)
{
    OsdIconList *pstIconList = (OsdIconList *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstIconList);
    HV_ASSERT_VALID_PTR_VOID(pstUserdata);

    pstIconList->ucIconCurID = MIN((USHORT16)pstUserdata->sOsdValue, pstIconList->ucIconNum - 1);
}

VOID Hv_App_Cb_OsdUpdateIconListCustom(VOID *pstCpProp, USHORT16 usId)
{
    OsdIconList *pstIconList = (OsdIconList *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstIconList);
}

VOID Hv_App_Cb_OsdUpdateBmpByUserdata(VOID *pstCpProp, USHORT16 usId, UserdataProp *pstUserdata)
{
    OsdBmp *pstBmp = (OsdBmp *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstBmp);
    HV_ASSERT_VALID_PTR_VOID(pstUserdata);
}

VOID Hv_App_Cb_OsdUpdateBmpCustom(VOID *pstCpProp, USHORT16 usId)
{
    OsdBmp *pstBmp = (OsdBmp *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstBmp);
}

VOID Hv_App_Cb_OsdUpdateBmpListByUserdata(VOID *pstCpProp, USHORT16 usId, UserdataProp *pstUserdata)
{
    OsdBmpList *pstBmpList = (OsdBmpList *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstBmpList);
    HV_ASSERT_VALID_PTR_VOID(pstUserdata);

    pstBmpList->ucBmpCurID = MIN((USHORT16)pstUserdata->sOsdValue, pstBmpList->ucBmpNum - 1);
}

VOID Hv_App_Cb_OsdUpdateBmpListCustom(VOID *pstCpProp, USHORT16 usId)
{
    OsdBmpList *pstBmpList = (OsdBmpList *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstBmpList);
}

VOID Hv_App_Cb_OsdUpdateRectByUserdata(VOID *pstCpProp, USHORT16 usId, UserdataProp *pstUserdata)
{
    OsdRect *pstRect = (OsdRect *)pstCpProp;
    const OsdRect *pstRectProp = OSD_GET_RECT_PROP(usId);
    HV_ASSERT_VALID_PTR_VOID(pstRectProp);
    HV_ASSERT_VALID_PTR_VOID(pstRect);
    HV_ASSERT_VALID_PTR_VOID(pstUserdata);

    /* for v slider bar */
    if ((pstRect->uiDynamicFlag & DYN_Y) && (pstRect->uiDynamicFlag & DYN_HEIGHT))
    {
        if (pstUserdata->sMaxValue == pstUserdata->sMinValue)
        {
            pstRect->usHeight = 0;
        }
        else
        {
            USHORT16 usOriHeight = pstRectProp->usHeight;
            OSD_LOG_DEBUG("Dynamic rect: y = %d, height = %d, ", pstRect->usY, pstRect->usHeight);
            pstRect->usHeight = (USHORT16)(((UINT32)usOriHeight * (UINT32)(pstUserdata->sOsdValue - pstUserdata->sMinValue))
                / (UINT32)(pstUserdata->sMaxValue - pstUserdata->sMinValue));
            pstRect->usY = pstRectProp->usY + usOriHeight - pstRect->usHeight;
            OSD_LOG_DEBUG("Update dynamic rect: y = %d, height = %d, ", pstRect->usY, pstRect->usHeight);
        }
    }

    /* for h slider bar */
    if (pstRect->uiDynamicFlag & DYN_WIDTH)
    {
        if (pstUserdata->sMaxValue == pstUserdata->sMinValue)
        {
            pstRect->usWidth = 0;
        }
        else
        {
            OSD_LOG_DEBUG("Dynamic rect: width = %d", pstRect->usWidth);
            pstRect->usWidth = (USHORT16)(((UINT32)pstRectProp->usWidth * (UINT32)(pstUserdata->sOsdValue - pstUserdata->sMinValue))
                / (UINT32)(pstUserdata->sMaxValue - pstUserdata->sMinValue));
            OSD_LOG_DEBUG("Update dynamic rect: width = %d", pstRect->usWidth);
        }
    }
}

VOID Hv_App_Cb_OsdUpdateRectCustom(VOID *pstCpProp, USHORT16 usId)
{
    OsdRect *pstRect = (OsdRect *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstRect);
}

VOID Hv_App_Cb_OsdUpdateRectGridByUserdata(VOID *pstCpProp, USHORT16 usId, UserdataProp *pstUserdata)
{
    OsdRectGrid *pstRectGrid = (OsdRectGrid *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstRectGrid);
    HV_ASSERT_VALID_PTR_VOID(pstUserdata);
}

VOID Hv_App_Cb_OsdUpdateRectGridCustom(VOID *pstCpProp, USHORT16 usId)
{
    OsdRectGrid *pstRectGrid = (OsdRectGrid *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstRectGrid);
}

VOID Hv_App_Cb_OsdUpdateLineGridByUserdata(VOID *pstCpProp, USHORT16 usId, UserdataProp *pstUserdata)
{
    OsdLineGrid *pstLineGrid = (OsdLineGrid *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstLineGrid);
    HV_ASSERT_VALID_PTR_VOID(pstUserdata);
}

VOID Hv_App_Cb_OsdUpdateLineGridCustom(VOID *pstCpProp, USHORT16 usId)
{
    OsdLineGrid *pstLineGrid = (OsdLineGrid *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstLineGrid);
}

VOID Hv_App_Cb_OsdUpdateLineByUserdata(VOID *pstCpProp, USHORT16 usId, UserdataProp *pstUserdata)
{
    OsdLine *pstLine = (OsdLine *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstLine);
    HV_ASSERT_VALID_PTR_VOID(pstUserdata);
}

VOID Hv_App_Cb_OsdUpdateLineCustom(VOID *pstCpProp, USHORT16 usId)
{
    OsdLine *pstLine = (OsdLine *)pstCpProp;
    HV_ASSERT_VALID_PTR_VOID(pstLine);
}
