/**
 * @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_comm_DataBase.h"
#include "hv_app_OsdDynamicUpdate.h"
#include "hv_drv_Osd.h"

static OsdTimingInfo s_stCurTiming;
static BOOL s_bShowUnspportTip = HV_FALSE;

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

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

    s_stCurTiming.bSignalSync = 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_VIDEO_SOURCE);

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

    switch (ucSource)
    {
        case UD_VIDEO_SOURCE_V_HDMI1:
        {
            Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT, TEXT_NOSIGNAL_HDMI1_SCENE_NOSIGNAL_NORMAL));
            break;
        }
        case UD_VIDEO_SOURCE_V_HDMI2:
        {
            Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT, TEXT_NOSIGNAL_HDMI2_SCENE_NOSIGNAL_NORMAL));
            break;
        }
        case UD_VIDEO_SOURCE_V_DP1:
        {
            Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT, TEXT_NOSIGNAL_DP1_SCENE_NOSIGNAL_NORMAL));
            break;
        }
        case UD_VIDEO_SOURCE_V_DP2:
        {
            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 OsdUpdateTimingInfo(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;
        }
    }
#if 0
    s_stCurTiming.enColorFmt = stChannelData.stVideoConfigParams.stColor.eClrFormat;
    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)
    {
        /* 关闭运动清晰度 */
        Hv_Mw_OsdAdjustFunction(E_USERDATA_MPRT, ACT_SET, UD_MPRT_V_OFF, SET_ALL);
    }
}

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

    Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_ASCII_STRING, CUSTOMSTRING_INPUT_SCENE_INPUT_SOURCE_NORMAL));
    Hv_Mw_OsdStartAutoRefreshTimer(SCENE_INPUT_SOURCE, HV_PROJECT_CONFIG_OSD_DEFAULT_REFRESH_PERIOD_MS);
}

VOID Hv_App_OsdSourcePlugInEnter(LinkPortIndex enPort)
{
    Hv_Mw_OsdSetAllKeyEnable(HV_TRUE);
    Hv_App_OsdHideAll();
    Hv_Mw_OsdSceneInit(SCENE_INPUT_SOURCE);
    Hv_Mw_OsdSceneShow(SCENE_INPUT_SOURCE);

    //TODO: Hv_Mw_OsdUserdataUpdate(E_USERDATA_VIDEO_SOURCE);
    USHORT16 usSourceID = Hv_Mw_OsdGetMappedOsdValue(E_USERDATA_VIDEO_SOURCE, enPort);
    Hv_Mw_OsdAdjustFunction(E_USERDATA_VIDEO_SOURCE, ACT_SET, usSourceID, SET_OSDDATA);

    Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT_LIST, TEXTLIST_INPUT_SCENE_INPUT_SOURCE_NORMAL));
    //Hv_Mw_OsdComponentUpdateByUserdata(COMPONENT(OSD_CP_TYPE_TEXT_LIST, TEXTLIST_INPUT_SCENE_INPUT_SOURCE_NORMAL), E_USERDATA_NONE);

    Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_ASCII_STRING, CUSTOMSTRING_INPUT_SCENE_INPUT_SOURCE_NORMAL));
    //Hv_Mw_OsdComponentUpdateByUserdata(COMPONENT(OSD_CP_TYPE_ASCII_STRING, CUSTOMSTRING_INPUT_SCENE_INPUT_SOURCE_NORMAL), E_USERDATA_NONE);

    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);
}

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;
    }
}

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

    s_stCurTiming.bSignalSync = HV_FALSE;

    if (!s_stCurTiming.bSignalSync)
    {
        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 usPortIndex = (usValue >> 8) & 0x00FF;

    OSD_LOG_INFO("Port %u signal ready", usPortIndex);
    Hv_App_OsdHideAll();
    OsdUpdateTimingInfo(usPortIndex);
    Hv_App_UpdateSettingByCurrentTiming();
}

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

    s_stCurTiming.bSignalSync = HV_FALSE;

    Hv_Mw_Channel_GetSignalState(CHANNEL_TYPE_MAIN, &enPortIndex, &enSignalState);
    OSD_LOG_INFO("Osd receive signal change: port %u state %u", enPortIndex, enSignalState);

    switch (enSignalState)
    {
        case ChanelSignalState_SearchState:
        {
            OSD_LOG_INFO("Signal start search, hide all");
            Hv_App_OsdHideAll();
            break;
        }
        case ChanelSignalState_NoSignal:
        {
            if (!s_stCurTiming.bSignalSync)
            {
                /* show no signal */
                Hv_App_OsdNoSignalEnter(enPortIndex);
            }
            break;
        }
        case ChanelSignalState_SignalSync:
        {
            /* show video source & timing & frame rate */
            Hv_App_OsdSourcePlugInEnter(enPortIndex);
            s_stCurTiming.bSignalSync = HV_TRUE;
            break;
        }
        default:
        {
            break;
        }
    }
}
