/**
 * @file hv_app_OsdDialog.c
 * @brief osd MiddleWare init c file.
 * @details This file provides the following 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_Osd.h"
#include "hv_app_OsdDialog.h"
#include "hv_app_OsdMenu.h"
#include "hv_mw_OsdComm.h"
#include "hv_mw_OsdLog.h"
#include "hv_mw_Channel_Manager.h"
#include "hv_mw_OsdDraw.h"
#include "hv_mw_OsdEvent.h"
#include "hv_mw_OsdOperation.h"
#include "hv_app_OsdDynamicUpdate.h"
#include "hv_drv_Osd.h"

static OsdTimingInfo s_stCurTiming;
static BOOL s_bShowUnspportTip = HV_FALSE;

static UCHAR8 s_ucTimeDelayBackUp = 0;
static UCHAR8 s_bTimeDelayModifyMainFlag = HV_FALSE;
static UCHAR8 s_bTimeDelayModifySubFlag = HV_FALSE;

OsdTimingInfo *Hv_App_OsdGetCurrentTimingInfo(VOID)
{
    return &s_stCurTiming;
}

VOID Hv_App_OsdSignalUnsupportEnter(USHORT16 usValue)
{
    USHORT16 usChannelType = usValue & 0x00FF;
    USHORT16 usPortIndex = (usValue >> 8) & 0x00FF;

    if (usChannelType == CHANNEL_TYPE_MAIN)
    {
        s_stCurTiming.bSignalSync = HV_FALSE;
    }
    else
    {
        s_stCurTiming.bSubSignalSync = HV_FALSE;
    }
    Hv_Mw_OsdSetAllKeyEnable(HV_TRUE);
    Hv_App_OsdHideAll();
    Hv_Mw_OsdSceneInit(SCENE_SIGNAL_UNSUPPORT);
    Hv_Mw_OsdSceneShow(SCENE_SIGNAL_UNSUPPORT);

    Hv_Mw_OsdStartAutoCloseTimer(SCENE_SIGNAL_UNSUPPORT, HV_PROJECT_CONFIG_OSD_DIALOG_SHOW_TIME);
    OSD_LOG_INFO("Show signal unsupport dialog");
}

VOID Hv_App_OsdSignalUnsupportExit(VOID)
{
    Hv_Mw_OsdSceneHide(SCENE_SIGNAL_UNSUPPORT);
    Hv_Mw_OsdSceneClear(SCENE_SIGNAL_UNSUPPORT);
}

VOID Hv_App_OsdFunctionUnsupportEnter(VOID)
{
    Hv_Mw_OsdSetAllKeyEnable(HV_TRUE);
    Hv_App_OsdHideAll();
    Hv_Mw_OsdSceneInit(SCENE_FUNCTION_UNSUPPORT);
    Hv_Mw_OsdSceneShow(SCENE_FUNCTION_UNSUPPORT);

    Hv_Mw_OsdStartAutoCloseTimer(SCENE_FUNCTION_UNSUPPORT, HV_PROJECT_CONFIG_OSD_DIALOG_SHOW_TIME);
    OSD_LOG_INFO("Show function unsupport dialog");
}

VOID Hv_App_OsdFunctionUnsupportExit(VOID)
{
    Hv_Mw_OsdSceneHide(SCENE_FUNCTION_UNSUPPORT);
    Hv_Mw_OsdSceneClear(SCENE_FUNCTION_UNSUPPORT);
}

VOID Hv_App_OsdNoSignalEnter(LinkPortIndex enPort)
{
    UCHAR8 ucSource = Hv_App_GetOsdDataValue(E_USERDATA_VIDEOSOURCE);

    Hv_Mw_OsdSetAllKeyEnable(HV_TRUE);
    Hv_App_OsdHideAll();
    Hv_Mw_OsdSceneInit(SCENE_NOSIGNAL);
    Hv_Mw_OsdSceneShow(SCENE_NOSIGNAL);

    switch (ucSource)
    {
        case UD_VIDEOSOURCE_V_HDMI1:
        {
            Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT, TEXT_NOSIGNAL_HDMI1_SCENE_NOSIGNAL_NORMAL));
            break;
        }
        case UD_VIDEOSOURCE_V_HDMI2:
        {
            Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT, TEXT_NOSIGNAL_HDMI2_SCENE_NOSIGNAL_NORMAL));
            break;
        }
        case UD_VIDEOSOURCE_V_USB_C:
        {
            //Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT, TEXT_NOSIGNAL_USBC_SCENE_NOSIGNAL_NORMAL));
            Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT, TEXT_NOSIGNAL_DP1_SCENE_NOSIGNAL_NORMAL));
            break;
        }
        case UD_VIDEOSOURCE_V_DP:
        {
            //Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT, TEXT_NOSIGNAL_DP_SCENE_NOSIGNAL_NORMAL));
            Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT, TEXT_NOSIGNAL_DP2_SCENE_NOSIGNAL_NORMAL));
            break;
        }
        default:
        {
            Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT, TEXT_NOSIGNAL_HDMI1_SCENE_NOSIGNAL_NORMAL));
            break;
        }
    }

    Hv_Mw_OsdStartAutoCloseTimer(SCENE_NOSIGNAL, HV_PROJECT_CONFIG_OSD_DIALOG_SHOW_TIME);
    OSD_LOG_INFO("Show no signal dialog");
}

VOID Hv_App_OsdNoSignalExit(VOID)
{
    Hv_Mw_OsdSceneHide(SCENE_NOSIGNAL);
    Hv_Mw_OsdSceneClear(SCENE_NOSIGNAL);
}

static VOID Hv_App_OsdSourceUpdateTimingInfo(LinkPortIndex enPort)
{
    const ChannelManager *pstManager = NULL;
    const VideoConfigParams *pstConfigParams = NULL;
    ChannelData stChannelData = {0};

    Hv_Mw_InputPort_GetVideoPara(enPort, &stChannelData);
    s_stCurTiming.enPort = enPort;
    s_stCurTiming.bInterlacedMode = stChannelData.stRxVideoTiming.bInterlacedMode;
    s_stCurTiming.usHActive = stChannelData.stRxVideoTiming.usHActive;
    s_stCurTiming.usVActive = stChannelData.stRxVideoTiming.bInterlacedMode ? stChannelData.stRxVideoTiming.usVActive * 2 : stChannelData.stRxVideoTiming.usVActive;
    if ((s_stCurTiming.usHActive > PANEL_H_ACTIVE) && (s_stCurTiming.usVActive > PANEL_V_ACTIVE))
    {
        if (UD_FREESYNC_V_OFF != Hv_App_GetOsdDataValue(E_USERDATA_FREESYNC))
        {
            /* 关闭freesync，不调用接口，仅设置Userdata */
            Hv_Mw_OsdAdjustFunction(E_USERDATA_FREESYNC, ACT_SET, UD_FREESYNC_V_OFF, SET_OSDDATA);
            s_bShowUnspportTip = HV_TRUE;
        }
    }
    s_stCurTiming.enColorFmt = stChannelData.stVideoConfigParams.stColor.eClrFormat;

#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_LDR)
    if (s_stCurTiming.enColorFmt == ColorFormatType_YCbCr422
        || s_stCurTiming.enColorFmt == ColorFormatType_YCbCr444
        || s_stCurTiming.enColorFmt == ColorFormatType_YCbCr420)
    {
        /* 设置量化范围为限制，不调用接口，仅设置Userdata */
        Hv_Mw_OsdAdjustFunction(E_USERDATA_LDR, ACT_SET, UD_LDR_V_LIMIT, SET_OSDDATA);
    }
    else
    {
        /* 恢复之前RGB信号的量化范围设置值 */
        UCHAR8 ucLdr = HV_COMMON_DATABASE_GET(UserData, ucLdrRgb);
        Hv_Mw_OsdAdjustFunction(E_USERDATA_LDR, ACT_SET, ucLdr, SET_OSDDATA);
        Hv_Mw_OsdAdjustFunction(E_USERDATA_LDR, ACT_SET, ucLdr, SET_INTERFACE);
    }
#endif
    s_stCurTiming.bIsVrr = (stChannelData.stVideoConfigParams.stVRRInfoParam.bVRREnable &&
                            (UD_FREESYNC_V_ON == Hv_App_GetOsdDataValue(E_USERDATA_FREESYNC)));
    s_stCurTiming.bIsFreesync = (stChannelData.stVideoConfigParams.stVRRInfoParam.bVRREnable &&
                                 ((stChannelData.stVideoConfigParams.stVRRInfoParam.eVendor == VendorType_AMD) ||
                                  (stChannelData.stVideoConfigParams.stVRRInfoParam.eVendor == VendorType_AMD_AdaptSync)) &&
                                 (UD_FREESYNC_V_ON == Hv_App_GetOsdDataValue(E_USERDATA_FREESYNC)));
    s_stCurTiming.ucFreesyncVersion = stChannelData.stVideoConfigParams.stVRRInfoParam.uvsi.stAmdSpdInfPara.ucVersion;

    s_stCurTiming.bIsHdr = (stChannelData.stVideoConfigParams.stHdrParam.xType != SDR_TYPE);

    UINT32 uiRefreshRate = Hv_Mw_InputPort_GetCurrentFrameRate(enPort);
    s_stCurTiming.usFrameRate = (uiRefreshRate + 500) / 1000;
    if (s_stCurTiming.bInterlacedMode)
    {
        s_stCurTiming.usFrameRate /= 2;
    }
    s_stCurTiming.bIsFrc = (DATA_PATH_MODE_FRAMESYNC != stChannelData.stVideoConfigParams.enDataPathMode);
    if (s_stCurTiming.bIsFreesync || (s_stCurTiming.usFrameRate < 85) || s_stCurTiming.bIsFrc)
    {
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_MPRT)
        /* 关闭运动清晰度 */
        Hv_Mw_OsdAdjustFunction(E_USERDATA_MPRT, ACT_SET, UD_MPRT_V_OFF, SET_ALL);
#endif
    }
    if ((s_stCurTiming.bIsFreesync) && (s_stCurTiming.ucFreesyncVersion >= 2))
    {
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_HDR)
        Hv_Mw_OsdAdjustFunction(E_USERDATA_HDR, ACT_SET, UD_HDR_V_AUTO, SET_ALL);
#endif
    }

#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_AUDIO_SETTING)
    if (((LINK_PORT_INDEX_DP_RX0 == enPort) || (LINK_PORT_INDEX_DP_RX1 == enPort))
        && ((s_stCurTiming.usHActive < 800) && (s_stCurTiming.usVActive < 600)))
    {
        if ((!s_bTimeDelayModifyMainFlag) && (!s_bTimeDelayModifySubFlag))
        {
            s_ucTimeDelayBackUp = Hv_App_GetOsdDataValue(E_USERDATA_TIME_DELAY);
            /* 设置Audio timedelay为50 */
            Hv_Mw_OsdAdjustFunction(E_USERDATA_TIME_DELAY, ACT_SET, 50, SET_ALL);
        }
        s_bTimeDelayModifyMainFlag = HV_TRUE;
    }
    else if (s_bTimeDelayModifyMainFlag)
    {
        s_bTimeDelayModifyMainFlag = HV_FALSE;
        if (!s_bTimeDelayModifySubFlag)
        {
            /* 还原Audio timedelay */
            Hv_Mw_OsdAdjustFunction(E_USERDATA_TIME_DELAY, ACT_SET, s_ucTimeDelayBackUp, SET_ALL);
        }
    }
#endif

    pstManager = Hv_Mw_Channel_GetManager();
    pstConfigParams = &pstManager->astChannelData[0].stVideoConfigParams;
    Hv_Drv_OsdFrame_ReCalculateTiming(pstConfigParams->uiOutputFrameRate, s_stCurTiming.bIsVrr);
}

#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_PXP)
static VOID Hv_App_OsdSourceUpdateSubTimingInfo(LinkPortIndex enPort)
{
    ChannelData stChannelData = {0};

    Hv_Mw_InputPort_GetVideoPara(enPort, &stChannelData);
    s_stCurTiming.enSubPort = enPort;
    s_stCurTiming.usSubHActive = stChannelData.stRxVideoTiming.usHActive;
    s_stCurTiming.usSubVActive = stChannelData.stRxVideoTiming.bInterlacedMode ? stChannelData.stRxVideoTiming.usVActive * 2 : stChannelData.stRxVideoTiming.usVActive;
    UINT32 uiRefreshRate = Hv_Mw_InputPort_GetCurrentFrameRate(enPort);
    s_stCurTiming.usSubFrameRate = (uiRefreshRate + 500) / 1000;
    s_stCurTiming.enSubColorFmt = stChannelData.stVideoConfigParams.stColor.eClrFormat;

#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_LDR)
    if (s_stCurTiming.enSubColorFmt == ColorFormatType_YCbCr422
        || s_stCurTiming.enSubColorFmt == ColorFormatType_YCbCr444
        || s_stCurTiming.enSubColorFmt == ColorFormatType_YCbCr420)
    {
        /* 设置量化范围为限制，不调用接口，仅设置Userdata */
        Hv_Mw_OsdAdjustFunction(E_USERDATA_LDR, ACT_SET, UD_LDR_V_LIMIT, SET_OSDDATA);
    }
    else
    {
        /* 恢复之前RGB信号的量化范围设置值 */
        UCHAR8 ucLdr = HV_COMMON_DATABASE_GET(UserData, ucLdrRgb);
        Hv_Mw_OsdAdjustFunction(E_USERDATA_LDR, ACT_SET, ucLdr, SET_OSDDATA);
        Hv_Mw_OsdAdjustFunction(E_USERDATA_LDR, ACT_SET, ucLdr, SET_INTERFACE);
    }
#endif

    if (((LINK_PORT_INDEX_DP_RX0 == enPort) || (LINK_PORT_INDEX_DP_RX1 == enPort))
        && ((s_stCurTiming.usSubHActive < 800) && (s_stCurTiming.usSubVActive < 600)))
    {
        if ((!s_bTimeDelayModifyMainFlag) && (!s_bTimeDelayModifySubFlag))
        {
            s_ucTimeDelayBackUp = Hv_App_GetOsdDataValue(E_USERDATA_TIME_DELAY);
            /* 设置Audio timedelay为50 */
            Hv_Mw_OsdAdjustFunction(E_USERDATA_TIME_DELAY, ACT_SET, 50, SET_ALL);
        }
        s_bTimeDelayModifySubFlag = HV_TRUE;
    }
    else if (s_bTimeDelayModifySubFlag)
    {
        s_bTimeDelayModifySubFlag = HV_FALSE;
        if (!s_bTimeDelayModifyMainFlag)
        {
            /* 还原Audio timedelay */
            Hv_Mw_OsdAdjustFunction(E_USERDATA_TIME_DELAY, ACT_SET, s_ucTimeDelayBackUp, SET_ALL);
        }
    }
}
#endif

VOID Hv_App_OsdSourcePlugInUpdate(VOID)
{
    if (!Hv_Mw_OsdSceneIsShowing(SCENE_INPUT_SOURCE))
    {
        return;
    }

    OsdTimingInfo *pstTiming = Hv_App_OsdGetCurrentTimingInfo();

    LinkPortIndex enPortIndex = Hv_App_GetOsdDataValue(E_USERDATA_VIDEOSOURCE);
    UINT32 uiRefreshRate = Hv_Mw_InputPort_GetCurrentFrameRate(enPortIndex);

    if (pstTiming->bInterlacedMode)
    {
        uiRefreshRate /= 2;
    }
    uiRefreshRate = (uiRefreshRate + 500) / 1000;

    UCHAR8 aucString[OSD_ASCII_STRING_LENGTH_MAX] = { 0 };
    USHORT16 usStringLength = Hv_App_OsdSetTimingInfoString(aucString, s_stCurTiming.usHActive, s_stCurTiming.usVActive,
                                                   uiRefreshRate, HV_FALSE, s_stCurTiming.bInterlacedMode);
    Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_ASCII_STRING, CUSTOMSTRING_INPUT_SCENE_INPUT_SOURCE_NORMAL));
    Hv_Mw_OsdDynamicAsciiStringUpdate(CUSTOMSTRING_INPUT_SCENE_INPUT_SOURCE_NORMAL, aucString, usStringLength);

    OSD_LOG_DEBUG("Update signal plug in dialog, port = %d, string: %s", enPortIndex, aucString);

    Hv_Mw_OsdStartAutoRefreshTimer(SCENE_INPUT_SOURCE, HV_PROJECT_CONFIG_OSD_DEFAULT_REFRESH_PERIOD_MS);
}

VOID Hv_App_OsdSourcePlugInEnter(LinkPortIndex enPort)
{
    UserdataValueVideoSource enSourceID = 0;
    UCHAR8 aucString[OSD_ASCII_STRING_LENGTH_MAX] = { 0 };
    USHORT16 usStringLength = 0;

    Hv_Mw_OsdSetAllKeyEnable(HV_TRUE);
    if (!Hv_Mw_OsdSceneIsShowing(SCENE_INPUT_SOURCE_SUB))
    {
        Hv_App_OsdHideAll();
    }
    Hv_Mw_OsdSceneInit(SCENE_INPUT_SOURCE);
    Hv_Mw_OsdSceneShow(SCENE_INPUT_SOURCE);

#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_PXP)
    if (UD_PXPMODE_V_PBP == Hv_App_GetOsdDataValue(E_USERDATA_PXPMODE))
    {
        Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE, HV_TRUE, 25, 0, INVALID_PARAM_USHORT16);
    }
    else
#endif
    {
        Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE, HV_TRUE, 50, 0, INVALID_PARAM_USHORT16);
    }

    switch (enPort)
    {
        case LINK_PORT_INDEX_HDMI_RX0:
        {
            enSourceID = UD_VIDEOSOURCE_V_HDMI1;
            break;
        }
        case LINK_PORT_INDEX_HDMI_RX1:
        {
            enSourceID = UD_VIDEOSOURCE_V_HDMI2;
            break;
        }
        case LINK_PORT_INDEX_DP_RX0:
        {
            enSourceID = UD_VIDEOSOURCE_V_USB_C;
            break;
        }
        case LINK_PORT_INDEX_DP_RX1:
        {
            enSourceID = UD_VIDEOSOURCE_V_DP;
            break;
        }
        default:
        {
            return;
        }
    }
    Hv_Mw_OsdAdjustFunction(E_USERDATA_VIDEOSOURCE, ACT_SET, enSourceID, SET_OSDDATA | SET_RELATED);
    Hv_Mw_OsdComponentUpdateByUserdata(COMPONENT(OSD_CP_TYPE_TEXT_LIST, TEXTLIST_INPUT_SCENE_INPUT_SOURCE_NORMAL), E_USERDATA_VIDEOSOURCE);

    Hv_App_OsdSourceUpdateTimingInfo(enPort);
    usStringLength = Hv_App_OsdSetTimingInfoString(aucString, s_stCurTiming.usHActive, s_stCurTiming.usVActive,
                                                   s_stCurTiming.usFrameRate, HV_FALSE, s_stCurTiming.bInterlacedMode);
    Hv_Mw_OsdDynamicAsciiStringUpdate(CUSTOMSTRING_INPUT_SCENE_INPUT_SOURCE_NORMAL, aucString, usStringLength);


    if (s_stCurTiming.bIsVrr)
    {
        Hv_Mw_OsdStartAutoRefreshTimer(SCENE_INPUT_SOURCE, HV_PROJECT_CONFIG_OSD_DEFAULT_REFRESH_PERIOD_MS);
    }
    else
    {
        Hv_Mw_OsdStopAutoRefreshTimer(SCENE_INPUT_SOURCE);
    }

    Hv_Mw_OsdStartAutoCloseTimer(SCENE_INPUT_SOURCE, HV_PROJECT_CONFIG_OSD_DIALOG_SHOW_TIME);
    OSD_LOG_INFO("Show signal plug in dialog, port = %d, string: %s", enPort, aucString);
}

VOID Hv_App_OsdSourcePlugInExit(VOID)
{
    Hv_Mw_OsdSceneHide(SCENE_INPUT_SOURCE);
    Hv_Mw_OsdSceneClear(SCENE_INPUT_SOURCE);

    if (s_bShowUnspportTip)
    {
        Hv_App_OsdFunctionUnsupportEnter();
        s_bShowUnspportTip = HV_FALSE;
    }
}

#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_PXP)
VOID Hv_App_OsdSubSourcePlugInEnter(LinkPortIndex enPort)
{
    UserdataValueVideoSource enSourceID = 0;
    UCHAR8 aucString[OSD_ASCII_STRING_LENGTH_MAX] = { 0 };
    USHORT16 usStringLength = 0;

    if (UD_PXPMODE_V_PIP == Hv_App_GetOsdDataValue(E_USERDATA_PXPMODE))
    {
        switch (Hv_App_GetOsdDataValue(E_USERDATA_PIP_POSITION))
        {
            case UD_PIP_POSITION_V_LEFTTOP:
            {
                Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE_SUB, HV_TRUE, 1, 0, INVALID_PARAM_USHORT16);
                Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE_SUB, HV_FALSE, 99, 0, INVALID_PARAM_USHORT16);
                break;
            }
            case UD_PIP_POSITION_V_LEFTBOTTOM:
            {
                Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE_SUB, HV_TRUE, 1, 0, INVALID_PARAM_USHORT16);
                Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE_SUB, HV_FALSE, 1, 0, INVALID_PARAM_USHORT16);
                break;
            }
            case UD_PIP_POSITION_V_RIGHTTOP:
            {
                Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE_SUB, HV_TRUE, 99, 0, INVALID_PARAM_USHORT16);
                Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE_SUB, HV_FALSE, 99, 0, INVALID_PARAM_USHORT16);
                break;
            }
            case UD_PIP_POSITION_V_RIGHTBOTTOM:
            {
                Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE_SUB, HV_TRUE, 99, 0, INVALID_PARAM_USHORT16);
                Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE_SUB, HV_FALSE, 1, 0, INVALID_PARAM_USHORT16);
                break;
            }
            default:
            {
                return;
            }
        }
    }
    else if (UD_PXPMODE_V_PBP == Hv_App_GetOsdDataValue(E_USERDATA_PXPMODE))
    {
        Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE_SUB, HV_TRUE, 75, 0, INVALID_PARAM_USHORT16);
        Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE_SUB, HV_FALSE, 50, 0, INVALID_PARAM_USHORT16);
    }
    else
    {
        return;
    }

    Hv_App_OsdSourceUpdateSubTimingInfo(enPort);

    Hv_Mw_OsdSetAllKeyEnable(HV_TRUE);
    if (!Hv_Mw_OsdSceneIsShowing(SCENE_INPUT_SOURCE))
    {
        Hv_App_OsdHideAll();
    }
    Hv_Mw_OsdSceneInit(SCENE_INPUT_SOURCE_SUB);
    Hv_Mw_OsdSceneShow((SCENE_INPUT_SOURCE_SUB));

    switch (enPort)
    {
        case LINK_PORT_INDEX_HDMI_RX0:
        {
            enSourceID = UD_VIDEOSOURCE_V_HDMI1;
            break;
        }
        case LINK_PORT_INDEX_HDMI_RX1:
        {
            enSourceID = UD_VIDEOSOURCE_V_HDMI2;
            break;
        }
        case LINK_PORT_INDEX_DP_RX0:
        {
            enSourceID = UD_VIDEOSOURCE_V_USB_C;
            break;
        }
        case LINK_PORT_INDEX_DP_RX1:
        {
            enSourceID = UD_VIDEOSOURCE_V_DP;
            break;
        }
        default:
        {
            return;
        }
    }
    Hv_Mw_OsdAdjustFunction(E_USERDATA_PXPVIDEOSOURCE, ACT_SET, enSourceID, SET_OSDDATA | SET_RELATED);
    Hv_Mw_OsdComponentUpdateByUserdata(COMPONENT(OSD_CP_TYPE_TEXT_LIST, TEXTLIST_INPUT_SCENE_INPUT_SOURCE_SUB_NORMAL), E_USERDATA_PXPVIDEOSOURCE);
    usStringLength = Hv_App_OsdSetTimingInfoString(aucString, s_stCurTiming.usSubHActive, s_stCurTiming.usSubVActive,
                                                   s_stCurTiming.usSubFrameRate, HV_FALSE, s_stCurTiming.bInterlacedMode);
    Hv_Mw_OsdDynamicAsciiStringUpdate(CUSTOMSTRING_INPUT_SCENE_INPUT_SOURCE_SUB_NORMAL, aucString, usStringLength);

    Hv_Mw_OsdStartAutoCloseTimer(SCENE_INPUT_SOURCE_SUB, HV_PROJECT_CONFIG_OSD_DIALOG_SHOW_TIME);
    OSD_LOG_INFO("Show sub signal plug in dialog, port = %d, string: %s", enPort, aucString);
}
#endif

VOID Hv_App_OsdSubSourcePlugInExit(VOID)
{
    Hv_Mw_OsdSceneHide(SCENE_INPUT_SOURCE_SUB);
    Hv_Mw_OsdSceneClear(SCENE_INPUT_SOURCE_SUB);
}

VOID Hv_App_OsdSourcePlugOut(USHORT16 usValue)
{
    OSD_LOG_INFO("Source plug out");
    USHORT16 usChannelType = usValue & 0x00FF;
    USHORT16 usPortIndex = (usValue >> 8) & 0x00FF;

    if (usChannelType == CHANNEL_TYPE_MAIN)
    {
        s_stCurTiming.bSignalSync = HV_FALSE;
    }
    else
    {
        s_stCurTiming.bSubSignalSync = HV_FALSE;
    }

    if ((!s_stCurTiming.bSignalSync) && (!s_stCurTiming.bSubSignalSync))
    {
        OSD_LOG_INFO("No signal sync, hide all");
        Hv_App_OsdHideAll();
        Hv_Mw_OsdSetKeyState(OSDEVT_KEY_UP, KEY_STATE_REPEATABLE, HV_FALSE);
        Hv_Mw_OsdSetKeyState(OSDEVT_KEY_DOWN, KEY_STATE_REPEATABLE, HV_FALSE);
    }
}

VOID Hv_App_OsdSignalReady(USHORT16 usValue)
{
    USHORT16 usChannelType = usValue & 0x00FF;
    USHORT16 usPortIndex = (usValue >> 8) & 0x00FF;

    Hv_App_UpdateSettingByCurrentTiming();
}

VOID Hv_App_OsdSignalStateEnter(USHORT16 usValue)
{
    LinkPortIndex enPortIndex = LINK_PORT_INDEX_INVALID;
    ChanelSignalState enSignalState = ChanelSignalState_Invalid;
    USHORT16 usChannelType = usValue & 0x00FF;
    //USHORT16 usPortIndex = (usValue >> 8) & 0x00FF;

    if (usChannelType == CHANNEL_TYPE_MAIN)
    {
        s_stCurTiming.bSignalSync = HV_FALSE;
    }
    else
    {
        s_stCurTiming.bSubSignalSync = HV_FALSE;
    }
    Hv_Mw_Channel_GetSignalState(usChannelType, &enPortIndex, &enSignalState);
    OSD_LOG_INFO("Osd receive signal change: port %u state %u", enPortIndex, enSignalState);

    switch (enSignalState)
    {
        case ChanelSignalState_SearchState:
        {
            break;
        }
        case ChanelSignalState_NoSignal:
        {
            if ((!s_stCurTiming.bSignalSync) && (!s_stCurTiming.bSubSignalSync))
            {
                /* show no signal */
                Hv_App_OsdNoSignalEnter(enPortIndex);
            }
            break;
        }
        case ChanelSignalState_SignalSync:
        {
            /* show video source & timing & frame rate */
            if (usChannelType == CHANNEL_TYPE_MAIN)
            {
                Hv_App_OsdSourcePlugInEnter(enPortIndex);
                s_stCurTiming.bSignalSync = HV_TRUE;
            }
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_PXP)
            else
            {
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_MAGNIFY)
                if (UD_MAGNIFY_GLASS_V_OFF == Hv_App_GetOsdDataValue(E_USERDATA_MAGNIFY_GLASS))
                {
                    Hv_App_OsdSubSourcePlugInEnter(enPortIndex);
                }
                else
                {
                    Hv_App_OsdSourceUpdateSubTimingInfo(enPortIndex);
                }
#else
                Hv_App_OsdSubSourcePlugInEnter(enPortIndex);
#endif
                s_stCurTiming.bSubSignalSync = HV_TRUE;
            }
#endif
            break;
        }
        default:
        {
            break;
        }
    }
}
