/**
 * @file hv_app_Osd.c
 * @brief osd app operation c file.
 * @details This file provides the following functions: \n
 *          (1) Osd operation 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>HiView SoC Software Team    <td>2022-09-01      <td>create
 * </table>
 */

#include <stdio.h>
#include "hv_comm_DataBase.h"
#include "hv_mw_OsdComm.h"
#include "hv_mw_OsdLog.h"
#include "hv_mw_OsdDraw.h"
#include "hv_mw_OsdEvent.h"
#include "hv_mw_OsdOperation.h"
#include "hv_app_Osd.h"
#include "hv_app_OsdDialog.h"
#include "hv_app_OsdFactory.h"
#include "hv_app_OsdMenu.h"

typedef struct _OsdFunctionTable
{
    USHORT16    usEventId;
    VOID      (*pfOsdFunction)(USHORT16 usValue);
} OsdFunctionTable;

OsdRotationType Hv_App_OsdGetRotateType(VOID)
{
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_OSD_ROTATION)
    return HV_COMMON_DATABASE_GET(UserData, ucOsdRotation);
#else
    return 0;
#endif
}

VOID Hv_App_OsdSetRotateType(OsdRotationType enRotate)
{
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_OSD_ROTATION)
    HV_COMMON_DATABASE_SET(UserData, ucOsdRotation, enRotate);
    Hv_Mw_OsdSetRotateType(enRotate);
    Hv_Mw_OsdRefreshAll();
#endif
}

OsdLanguage Hv_App_OsdGetLanguage(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucOsdLanguage);
}

VOID Hv_App_OsdSetLanguage(OsdLanguage enLang)
{
    HV_COMMON_DATABASE_SET(UserData, ucOsdLanguage, enLang);
    Hv_Mw_OsdSetLanguage(enLang);
    Hv_Mw_OsdRefreshAll();
}

USHORT16 Hv_App_OsdGetMenuTime(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucOsdTime);
}

VOID Hv_App_OsdSetMenuTime(USHORT16 usTimerSec)
{
    HV_COMMON_DATABASE_SET(UserData, ucOsdTime, usTimerSec);
}

USHORT16 Hv_App_OsdGetTrans(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucOsdTrans);
}

VOID Hv_App_OsdSetTrans(USHORT16 usTrans)
{
    HV_COMMON_DATABASE_SET(UserData, ucOsdTrans, usTrans);
    Hv_Mw_OsdSetTransparency(usTrans);
}

BOOL Hv_App_OsdGetLock(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucOsdLock);
}

VOID Hv_App_OsdSetLock(BOOL bLock)
{
    HV_COMMON_DATABASE_SET(UserData, ucOsdLock, bLock);
}

USHORT16 Hv_App_OsdGetCrosshair(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucOsdCrosshair);
}

VOID Hv_App_OsdSetCrosshair(USHORT16 usType)
{
    HV_COMMON_DATABASE_SET(UserData, ucOsdCrosshair, usType);
}

USHORT16 Hv_App_OsdGetFrameRateShow(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucOsdRefreshRate);
}

VOID Hv_App_OsdSetFrameRateShow(USHORT16 usType)
{
    HV_COMMON_DATABASE_SET(UserData, ucOsdRefreshRate, usType);
}

USHORT16 Hv_App_OsdGetTimerCounterShow(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucOsdTimerCounter);
}

VOID Hv_App_OsdSetTimerCounterShow(USHORT16 usType)
{
    HV_COMMON_DATABASE_SET(UserData, ucOsdTimerCounter, usType);
}

USHORT16 Hv_App_OsdGetCustomKey(USHORT16 usKey)
{
    if (1 == usKey)
    {
        return HV_COMMON_DATABASE_GET(UserData, ucOsdCustomKey1);
    }
    else if (2 == usKey)
    {
        return HV_COMMON_DATABASE_GET(UserData, ucOsdCustomKey2);
    }
    else if (3 == usKey)
    {
        return HV_COMMON_DATABASE_GET(UserData, ucOsdCustomKey3);
    }
	else
	{
	    return 0;
	}
}

VOID Hv_App_OsdSetCustomKey(USHORT16 usKey, USHORT16 usType)
{
    if (1 == usKey)
    {
        HV_COMMON_DATABASE_SET(UserData, ucOsdCustomKey1, usType);
    }
    else if (2 == usKey)
    {
        HV_COMMON_DATABASE_SET(UserData, ucOsdCustomKey2, usType);
    }
    else if (3 == usKey)
    {
        HV_COMMON_DATABASE_SET(UserData, ucOsdCustomKey3, usType);
    }
}

USHORT16 Hv_App_OsdGetLightMode(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucLightMode);
}

VOID Hv_App_OsdSetLightMode(USHORT16 usMode)
{
    HV_COMMON_DATABASE_SET(UserData, ucLightMode, usMode);

    USHORT16 usColorType = Hv_App_OsdGetLightColorSelect();
    //TODO: Set app cmd (usMode, usColorType).
}

/* 枚举需替换成真正的枚举，暂时使用osd枚举 */
USHORT16 Hv_App_OsdGetLightColorSelect(VOID)
{
    USHORT16 usMode =HV_COMMON_DATABASE_GET(UserData, ucLightMode);

    if (UD_LIGHT_MODE_V_STEADY == usMode)
    {
        return HV_COMMON_DATABASE_GET(UserData, ucSteadyColor);
    }
    else if (UD_LIGHT_MODE_V_BREATHE == usMode)
    {
        return HV_COMMON_DATABASE_GET(UserData, ucBreatheColor);
    }
    else if (UD_LIGHT_MODE_V_MARQUEEIN == usMode)
    {
        return HV_COMMON_DATABASE_GET(UserData, ucMarqueeInColor);
    }
    else if (UD_LIGHT_MODE_V_MARQUEEOUT == usMode)
    {
        return HV_COMMON_DATABASE_GET(UserData, ucMarqueeOutColor);
    }
	else
	{
	    return UD_LIGHT_MODE_V_OFF;
	}
}

/* 枚举需替换成真正的枚举，暂时使用osd枚举 */
VOID Hv_App_OsdSetLightColorSelect(USHORT16 usColorType)
{
    USHORT16 usMode =HV_COMMON_DATABASE_GET(UserData, ucLightMode);

    if (UD_LIGHT_MODE_V_STEADY == usMode)
    {
        HV_COMMON_DATABASE_SET(UserData, ucSteadyColor, usColorType);
    }
    else if (UD_LIGHT_MODE_V_BREATHE == usMode)
    {
        HV_COMMON_DATABASE_SET(UserData, ucBreatheColor, usColorType);
    }
    else if (UD_LIGHT_MODE_V_MARQUEEIN == usMode)
    {
        HV_COMMON_DATABASE_SET(UserData, ucMarqueeInColor, usColorType);
    }
    else if (UD_LIGHT_MODE_V_MARQUEEOUT == usMode)
    {
        HV_COMMON_DATABASE_SET(UserData, ucMarqueeOutColor, usColorType);
    }
    else
    {
    }

    //TODO: Set app cmd (usMode, usColorType).
}


USHORT16 Hv_App_OsdGetMenuPostion(BOOL bIsX)
{
    if (bIsX)
    {
        return HV_COMMON_DATABASE_GET(UserData, ucOsdMenuHPos);
    }
    else
    {
        return HV_COMMON_DATABASE_GET(UserData, ucOsdMenuVPos);
    }
}

/* Add position-movable scene here */
VOID Hv_App_OsdSetMenuPostion(BOOL bIsX, USHORT16 usRatio)
{
    USHORT16 usLimitPosStart = 0;
    USHORT16 usLimitPosEnd = INVALID_PARAM_USHORT16;

    if (bIsX)
    {
        HV_COMMON_DATABASE_SET(UserData, ucOsdMenuHPos, usRatio);
    }
    else
    {
        HV_COMMON_DATABASE_SET(UserData, ucOsdMenuVPos, usRatio);
    }

    Hv_Mw_OsdSceneSetPositionRatio(SCENE_LOCK, bIsX, usRatio, usLimitPosStart, usLimitPosEnd);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_MODE, bIsX, usRatio, usLimitPosStart, usLimitPosEnd);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT, bIsX, usRatio, usLimitPosStart, usLimitPosEnd);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_BRIGHTNESS, bIsX, usRatio, usLimitPosStart, usLimitPosEnd);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_CONTRAST, bIsX, usRatio, usLimitPosStart, usLimitPosEnd);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_VOLUME, bIsX, usRatio, usLimitPosStart, usLimitPosEnd);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_RESET_ALL, bIsX, usRatio, usLimitPosStart, usLimitPosEnd);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_POWER_TIPS, bIsX, usRatio, usLimitPosStart, usLimitPosEnd);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_FUNCTION_TIPS, bIsX, usRatio, usLimitPosStart, usLimitPosEnd);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_MAIN, bIsX, usRatio, usLimitPosStart, usLimitPosEnd);
}

/* Add position-static scene here */
static VOID SceneStaticPostionInit(VOID)
{
    USHORT16 usLimitPosStart = 0;
    USHORT16 usLimitPosEnd = INVALID_PARAM_USHORT16;

    Hv_Mw_OsdSceneSetPositionRatio(SCENE_CROSSHAIR, HV_TRUE, 50, 0, INVALID_PARAM_USHORT16);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_CROSSHAIR, HV_FALSE, 50, 0, INVALID_PARAM_USHORT16);

    Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE, HV_TRUE, 50, 0, INVALID_PARAM_USHORT16);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_INPUT_SOURCE, HV_FALSE, 50, 0, INVALID_PARAM_USHORT16);

    Hv_Mw_OsdSceneSetPositionRatio(SCENE_NOSIGNAL, HV_TRUE, 50, 0, INVALID_PARAM_USHORT16);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_NOSIGNAL, HV_FALSE, 50, 0, INVALID_PARAM_USHORT16);

    Hv_Mw_OsdSceneSetPositionRatio(SCENE_SIGNAL_UNSUPPORT, HV_TRUE, 50, 0, INVALID_PARAM_USHORT16);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_SIGNAL_UNSUPPORT, HV_FALSE, 50, 0, INVALID_PARAM_USHORT16);

    Hv_Mw_OsdSceneSetPositionRatio(SCENE_AUTO_ADJUSTING, HV_TRUE, 50, 0, INVALID_PARAM_USHORT16);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_AUTO_ADJUSTING, HV_FALSE, 50, 0, INVALID_PARAM_USHORT16);

    Hv_Mw_OsdSceneSetPositionRatio(SCENE_FUNCTION_UNSUPPORT, HV_TRUE, 50, 0, INVALID_PARAM_USHORT16);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_FUNCTION_UNSUPPORT, HV_FALSE, 50, 0, INVALID_PARAM_USHORT16);

    Hv_Mw_OsdSceneSetPositionRatio(SCENE_REFRESH_RATE, HV_TRUE, 1, 0, INVALID_PARAM_USHORT16);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_REFRESH_RATE, HV_FALSE, 99, 0, INVALID_PARAM_USHORT16);

    Hv_Mw_OsdSceneSetPositionRatio(SCENE_TIMER, HV_TRUE, 99, 0, INVALID_PARAM_USHORT16);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_TIMER, HV_FALSE, 99, 0, INVALID_PARAM_USHORT16);

    Hv_Mw_OsdSceneSetPositionRatio(SCENE_OTA, HV_TRUE, 50, 0, INVALID_PARAM_USHORT16);
    Hv_Mw_OsdSceneSetPositionRatio(SCENE_OTA, HV_FALSE, 50, 0, INVALID_PARAM_USHORT16);
}

VOID Hv_App_Cb_OsdInit(VOID)
{
    /* 初始化所有Userdata相关设置 */
    Hv_App_InitToUserSetting();

    /* 初始化所有静态scene的位置 */
    SceneStaticPostionInit();

    /* set ENTER key holdable */
    Hv_Mw_OsdSetKeyState(OSDEVT_KEY_ENTER, KEY_STATE_HOLDABLE, HV_TRUE);
}

USHORT16 Hv_App_OsdSetFirmwareVersionString(UCHAR8 *pucString)
{
    UCHAR8 aucDate[] = "20241209";
    USHORT16 usLen = 0;

    UCHAR8 *apucMonths[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    SHORT16 sMonth;
    for (sMonth = 0; sMonth < 12; sMonth++) {
        if (strncmp(aucDate, apucMonths[sMonth], 3) == 0) {
            break;
        }
    }

    SHORT16 sDay = 0;
    SHORT16 sYear = 0;
    UCHAR8 *pucToken = strtok(aucDate + 4, " ");
    if (pucToken != NULL) {
        sDay = atoi(pucToken);
    }
    pucToken = strtok(NULL, " ");
    if (pucToken != NULL) {
        sYear = atoi(pucToken);
    }
    UCHAR8 ucYear = (sYear - 2023) + 'N';
    usLen = HV_SNPRINTF(pucString, OSD_ASCII_STRING_LENGTH_MAX, "HIVIEW.%c%02d%02d", ucYear, sMonth + 1, sDay);
    OSD_LOG_DEBUG("FW String: %s", pucString);
    return usLen;
}

static VOID Hv_App_OsdRecoverPreviewSetting(UserdataId enUserdata)
{
#if 0
    if ((enUserdata == E_USERDATA_DISPLAY_MODE) ||
        (enUserdata == E_USERDATA_LDR) ||
        (enUserdata == E_USERDATA_GAMMA) ||
        (enUserdata == E_USERDATA_COLOR_TEMP) ||
        (enUserdata == E_USERDATA_COLOR_SPACE) ||
        (enUserdata == E_USERDATA_LOW_BLUE_LIGHT))
    {
        /* 正在预览设置时关闭，需恢复设置值 */
        Hv_Mw_SetFromOsdUserdata(enUserdata);
    }
#endif
}

VOID Hv_App_OsdHideAll(VOID)
{
    USHORT16 usCurFocusing = OSD_GET_FOCUSING();
    if (usCurFocusing != ITEM_NONE_ID)
    {
        UserdataId enUserdata = OSD_GET_USERDATA(usCurFocusing);
        Hv_App_OsdRecoverPreviewSetting(enUserdata);
    }

    Hv_Mw_OsdSceneClearAll();
}

VOID Hv_App_OsdHideAllProc(USHORT16 usValue)
{
    Hv_App_OsdHideAll();

    if (1 == usValue)
    {
        /* 禁用所有按键 */
        Hv_Mw_OsdSetAllKeyEnable(HV_FALSE);
    }
}
#if 0
static VOID Hv_App_OsdKeyHoldProc(USHORT16 usValue)
{
    switch (Hv_Mw_OsdGetHoldKey())
    {
        case OSDEVT_KEY_ENTER:
        {
            if (UD_OSD_LOCK_V_ON == Hv_App_GetOsdDataValue(E_USERDATA_OSD_LOCK))
            {
                Hv_Mw_OsdAdjustFunction(E_USERDATA_OSD_LOCK, ACT_SET, UD_OSD_LOCK_V_OFF, SET_ALL);
                Hv_App_OsdLockEnter();
            }
            break;
        }
        default:
        {
            break;
        }
    }
}
#endif
static VOID Hv_App_OsdAutoClose(USHORT16 usValue)
{
    OSD_LOG_DEBUG("Auto close %s", SCENE_NAME(usValue));
    switch (usValue)
    {
        case SCENE_INPUT_SOURCE:
        {
            if (Hv_Mw_OsdSceneIsShowing(SCENE_INPUT_SOURCE))
            {
                Hv_App_OsdSourcePlugInExit();
            }
            break;
        }
        case SCENE_NOSIGNAL:
        {
            if (Hv_Mw_OsdSceneIsShowing(SCENE_NOSIGNAL))
            {
                Hv_App_OsdNoSignalExit();
            }
            break;
        }
        case SCENE_SIGNAL_UNSUPPORT:
        {
            if (Hv_Mw_OsdSceneIsShowing(SCENE_SIGNAL_UNSUPPORT))
            {
                Hv_App_OsdSignalUnsupportExit();
            }
            break;
        }
        case SCENE_AUTO_ADJUSTING:
        {
            break;
        }
        case SCENE_FUNCTION_UNSUPPORT:
        {
            if (Hv_Mw_OsdSceneIsShowing(SCENE_FUNCTION_UNSUPPORT))
            {
                Hv_App_OsdFunctionUnsupportExit();
            }
            break;
        }
        case SCENE_LOCK:
        {
            if (Hv_Mw_OsdSceneIsShowing(SCENE_LOCK))
            {
                Hv_App_OsdLockExit();
            }
            break;
        }
        case SCENE_MAIN:
        {
            USHORT16 usCurFocusing = OSD_GET_FOCUSING();
            if (usCurFocusing != ITEM_NONE_ID)
            {
                USHORT16 usCurScene = ITEM_GET_SCENEID(usCurFocusing);
                UserdataId enUserdata = OSD_GET_USERDATA(usCurFocusing);
                Hv_App_OsdRecoverPreviewSetting(enUserdata);
                Hv_Mw_OsdItemFocusClear();
                Hv_Mw_OsdSceneHide(usCurScene);
                Hv_Mw_OsdSceneClear(usCurScene);
            }
            break;
        }
        case SCENE_OTA:
        {
            if (Hv_Mw_OsdSceneIsShowing(SCENE_OTA))
            {
                Hv_App_OsdOtaExit();
            }
            break;
        }
        default:
        {
            break;
        }
    }
}

static VOID Hv_App_OsdAutoRefresh(USHORT16 usValue)
{
    OSD_LOG_DEBUG("Auto refresh Scene-%d", usValue);

    switch (usValue)
    {
        case SCENE_REFRESH_RATE:
            Hv_App_OsdRefreshRateUpdate();
            break;
        case SCENE_TIMER:
            Hv_App_OsdTimeCounterUpdate();
            break;
        case SCENE_MAIN:
            Hv_App_OsdMainMenuUpdate();
            break;
        case SCENE_INPUT_SOURCE:
            Hv_App_OsdSourcePlugInUpdate();
            break;
        default:
            break;
    }
}

static BOOL Hv_App_OsdIsShowingExcept(VOID)
{
    for (USHORT16 usId = 0; usId < SCENE_ID_MAX; usId++)
    {
        if ((SCENE_CROSSHAIR == usId) || (SCENE_REFRESH_RATE == usId) || (SCENE_TIMER == usId))
        {
            OSD_LOG_DEBUG("Except Scene-%d", usId);
            continue;
        }

        if (Hv_Mw_OsdSceneIsShowing(usId))
        {
            OSD_LOG_DEBUG("Scene-%d is showing", usId);
            return HV_TRUE;
        }
    }

    OSD_LOG_DEBUG("No Scene is showing");
    return HV_FALSE;
}

static VOID Hv_App_OsdFactoryEnter(USHORT16 usValue)
{
    OSD_LOG_INFO("Enter Factory Mode");
    HV_COMMON_DATABASE_SET(SystemData, bFactoryMode, HV_TRUE);
    Hv_App_OsdHideAll();
}

static VOID Hv_App_OsdFactoryExit(USHORT16 usValue)
{
    OSD_LOG_INFO("Exit Factory Mode");
    HV_COMMON_DATABASE_SET(SystemData, bFactoryMode, HV_FALSE);
    Hv_App_OsdHideAll();
}

static VOID Hv_App_OsdCheckAutoShow(VOID)
{
    BOOL bSignalSync = CUR_TIMING_INFO(bSignalSync);

    /* Crosshair check */
    if (UD_CROSSHAIR_V_NONE != Hv_App_GetOsdDataValue(E_USERDATA_CROSSHAIR))
    {
        if ((!Hv_App_OsdIsShowingExcept()) && (bSignalSync))
        {
            if (!Hv_Mw_OsdSceneIsShowing(SCENE_CROSSHAIR))
            {
                Hv_App_OsdCrosshairEnter();
            }
        }
        else if (Hv_Mw_OsdSceneIsShowing(SCENE_CROSSHAIR))
        {
            Hv_App_OsdCrosshairExit();
        }
    }
    else if (Hv_Mw_OsdSceneIsShowing(SCENE_CROSSHAIR))
    {
        Hv_App_OsdCrosshairExit();
    }

    /* RefreshRate check */
    if (UD_REFRESH_RATE_V_OFF != Hv_App_GetOsdDataValue(E_USERDATA_REFRESH_RATE))
    {
        if ((!Hv_App_OsdIsShowingExcept()) && (bSignalSync))
        {
            if (!Hv_Mw_OsdSceneIsShowing(SCENE_REFRESH_RATE))
            {
                Hv_App_OsdRefreshRateEnter();
            }
        }
        else if (Hv_Mw_OsdSceneIsShowing(SCENE_REFRESH_RATE))
        {
            Hv_App_OsdRefreshRateExit();
        }
    }
    else if (Hv_Mw_OsdSceneIsShowing(SCENE_REFRESH_RATE))
    {
        Hv_App_OsdRefreshRateExit();
    }

    /* TimerCounter check */
    if (UD_TIMER_COUNTER_V_OFF != Hv_App_GetOsdDataValue(E_USERDATA_TIMER_COUNTER))
    {
        if ((!Hv_App_OsdIsShowingExcept()) && (bSignalSync))
        {
            if (!Hv_Mw_OsdSceneIsShowing(SCENE_TIMER))
            {
                Hv_App_OsdTimeCounterEnter();
            }
        }
        else if (Hv_Mw_OsdSceneIsShowing(SCENE_TIMER))
        {
            Hv_App_OsdTimeCounterExit();
        }
    }
    else if (Hv_Mw_OsdSceneIsShowing(SCENE_TIMER))
    {
        Hv_App_OsdTimeCounterExit();
    }
}

VOID Hv_App_Cb_LogoSetting(BOOL bIsShow)
{
    if (bIsShow)
    {
        //Hv_Mw_OsdAdjustFunction(E_USERDATA_COLOR_SPACE, ACT_SET_DEFAULT, 0, SET_INTERFACE);
        Hv_Mw_OsdAdjustFunction(E_USERDATA_OSD_TRANS, ACT_SET, 0, SET_INTERFACE);
    }
    else
    {
        //Hv_Mw_SetFromOsdUserdata(E_USERDATA_COLOR_SPACE);
        Hv_Mw_SetFromOsdUserdata(E_USERDATA_OSD_TRANS);
    }
}

static const OsdFunctionTable s_astOsdFunctionTable[] =
{
    /* 菜单按键事件 */
    {OSD_EVENT_KEY_PRESS,                   Hv_App_OsdMenuOperation},
    /* 自动刷新 */
    {OSD_EVENT_TIMER_AUTO_REFRESH,          Hv_App_OsdAutoRefresh},
    /* 自动关闭 */
    {OSD_EVENT_TIMER_AUTO_CLOSE,            Hv_App_OsdAutoClose},
    /* 长按键 */
    //{OSD_EVENT_TIMER_KEY_HOLD,              Hv_App_OsdKeyHoldProc},
    /* 信号源状态就绪 */
    {OSD_EVENT_SIGNAL_READY,                Hv_App_OsdSignalReady},
    /* 信号源状态改变 */
    {OSD_EVENT_SIGNAL_STATE_CHANGE,         Hv_App_OsdSignalStateEnter},
    /* 信号源不支持 */
    {OSD_EVENT_SIGNAL_TIMING_NOT_SUPPORT,   Hv_App_OsdSignalUnsupportEnter},
    /* 信号源拔出 */
    {OSD_EVENT_SIGNAL_PLUG_OUT,             Hv_App_OsdSourcePlugOut},
    /* 进入工厂模式 */
    {OSD_EVENT_FACTORY_ENTER,               Hv_App_OsdFactoryEnter},
    /* 退出工厂模式 */
    {OSD_EVENT_FACTORY_EXIT,                Hv_App_OsdFactoryExit},
    /* 老化窗口刷新 */
    {OSD_EVENT_FACTORY_AGING_REFRESH,       Hv_App_OsdFactoryAgingEnter},
    /* 老化退出 */
    {OSD_EVENT_FACTORY_AGING_EXIT,          Hv_App_OsdFactoryAgingExit},
    /* 隐藏所有OSD */
    {OSD_EVENT_HIDE_ALL,                    Hv_App_OsdHideAllProc},
#ifdef CONFIG_USER_USB_OTA_ON
    /* USB OTA升级 */
    {OSD_EVENT_USB_OTA,                     Hv_App_OsdOtaUpdate},
#endif
};

Status Hv_App_Cb_OsdOperation(OsdEvent *pstEventMsg)
{
    UCHAR8 ucIndex = 0;
    OSD_LOG_DEBUG("Operation %s", Hv_Mw_OsdGetEventName(pstEventMsg->usEventId));
    if (pstEventMsg->usEventId == OSD_EVENT_MAX)
    {
        OSD_LOG_DEBUG("Do nothing");
        return HV_FAILURE;
    }

    for (ucIndex = 0; ucIndex < ARRAY_SIZE(s_astOsdFunctionTable); ucIndex++)
    {
        if (pstEventMsg->usEventId == s_astOsdFunctionTable[ucIndex].usEventId)
        {
            if (NULL == s_astOsdFunctionTable[ucIndex].pfOsdFunction)
            {
                return HV_FAILURE;
            }
            s_astOsdFunctionTable[ucIndex].pfOsdFunction(pstEventMsg->usValue);
            break;
        }
    }
    if (ucIndex == ARRAY_SIZE(s_astOsdFunctionTable))
    {
        OSD_LOG_DEBUG("No event operation function, event = %s", Hv_Mw_OsdGetEventName(pstEventMsg->usEventId));
        return HV_FAILURE;
    }

    Hv_App_OsdCheckAutoShow();

    return HV_SUCCESS;
}

#ifdef HV_SCALER_DEBUG_VERSION
static HV_TIMER_S* s_pstOsdTestTimer;
static UCHAR8 s_ucTestScene = SCENE_ID_MAX * 2;
BOOL Hv_App_Cb_OsdIsSceneTestRunning(VOID)
{
    return (s_ucTestScene < SCENE_ID_MAX * 2);
}

static VOID OsdSceneTest(VOID *vpArgument, USHORT16 usTimerId)
{
    UCHAR8 ucScene = s_ucTestScene / 2;

    if (0 == (s_ucTestScene % 2))
    {
        Hv_Mw_OsdSceneInit(ucScene);
        Hv_Mw_OsdSceneShow(ucScene);
        switch (ucScene)
        {
            case SCENE_AUTO_ADJUSTING:
            {
                break;
            }
            case SCENE_BRIGHTNESS:
            {
                Hv_Mw_OsdItemShowList(ITEM_BRIGHTNESS_SCENE_BRIGHTNESS);
                break;
            }
            case SCENE_CONTRAST:
            {
                Hv_Mw_OsdItemShowList(ITEM_CONTRAST_SCENE_CONTRAST);
                break;
            }
            case SCENE_CROSSHAIR:
            {
                Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_ICON, IMAGE_CROSSHAIR1_SCENE_CROSSHAIR_NORMAL));
                break;
            }
            case SCENE_FACTORY:
            {
                //Hv_App_OsdFactoryMenuEnter();
                break;
            }
            case SCENE_FACTORY_AGING:
            {
                //Hv_App_OsdFactoryAgingEnter();
                break;
            }
            case SCENE_FUNCTION_TIPS:
            {
                Hv_Mw_OsdItemShowList(ITEM_NO_SCENE_FUNCTION_TIPS);
                Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT, TEXT_ADJ_ADAPTIVESYNC_SCENE_FUNCTION_TIPS_NORMAL));
                break;
            }
            case SCENE_FUNCTION_UNSUPPORT:
            {
                Hv_App_OsdFunctionUnsupportEnter();
                break;
            }
            case SCENE_INPUT:
            {
                Hv_Mw_OsdItemShowList(ITEM_HDMI1_SCENE_INPUT);
                break;
            }
            case SCENE_INPUT_SOURCE:
            {
                Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT_LIST, TEXTLIST_INPUT_SCENE_INPUT_SOURCE_NORMAL));
                //Hv_Mw_OsdSetAsciiString("1920x1080@60Hz Test");
                Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_ASCII_STRING, CUSTOMSTRING_INPUT_SCENE_INPUT_SOURCE_NORMAL));
                break;
            }
            case SCENE_LOCK:
            {
                Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_BMP, IMAGE_LOCK_SCENE_LOCK_NORMAL));
                break;
            }
            case SCENE_MAIN:
            {
                Hv_Mw_OsdItemShowList(MAIN_INPUT_ITEM_SCENE_MAIN);
                Hv_Mw_OsdItemShowListWithSingleValue(CHILD_ITEM(MAIN_INPUT_ITEM_SCENE_MAIN));
                break;
            }
            case SCENE_MODE:
            {
                Hv_Mw_OsdItemShow(ITEM_MODE_SCENE_MODE);
                break;
            }
            case SCENE_NOSIGNAL:
            {
                Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT, TEXT_NOSIGNAL_HDMI1_SCENE_NOSIGNAL_NORMAL));
                break;
            }
#if 0
            case SCENE_OTA:
            {
                Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_TEXT, TEXT_PREPARE_SCENE_OTA_NORMAL));
                break;
            }
#endif
            case SCENE_POWER_TIPS:
            {
                Hv_Mw_OsdItemShowList(ITEM_NO_SCENE_POWER_TIPS);
                break;
            }
            case SCENE_REFRESH_RATE:
            {
                //Hv_Mw_OsdSetAsciiString("999Hz");
                Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_ASCII_STRING, CUSTOMSTRING_REFRESHRATE_SCENE_REFRESH_RATE_NORMAL));
                break;
            }
            case SCENE_RESET_ALL:
            {
                Hv_Mw_OsdItemShowList(ITEM_NO_SCENE_RESET_ALL);
                break;
            }
            case SCENE_SIGNAL_UNSUPPORT:
            {
                break;
            }
            case SCENE_TIMER:
            {
                //Hv_Mw_OsdSetAsciiString("99:59");
                Hv_Mw_OsdComponentShow(COMPONENT(OSD_CP_TYPE_ASCII_STRING, CUSTOMSTRING_TIMER_SCENE_TIMER_NORMAL));
                break;
            }
            case SCENE_VOLUME:
            {
                Hv_Mw_OsdItemShowList(ITEM_VOLUME_SCENE_VOLUME);
                break;
            }
            default:
            {
                return;
            }
        }
        s_ucTestScene++;
    }
    else
    {
        Hv_App_OsdHideAll();
        s_ucTestScene++;
        if (s_ucTestScene == SCENE_ID_MAX * 2)
        {
            s_ucTestScene = 0;
        }
    }

    //Hv_Mw_OsdDrawSetFrameModify();
    OsdEvent stOsdEvent = { 0 };
    Hv_Mw_OsdDraw(&stOsdEvent);

    Hv_Vos_Timer_Rstart(s_pstOsdTestTimer, 1000);
}

VOID Hv_App_Cb_OsdSceneTest(BOOL bStart)
{
    if (bStart)
    {
        OSD_LOG_INFO("Osd scene test start!");
        if (NULL == s_pstOsdTestTimer)
        {
            HV_TIMER_INIT_PARAMS stParam = \
                {"OsdSceneTestTimer", 1000, HV_FALSE, NULL, OsdSceneTest, OSD_EVENT_TIMER_END};
            s_pstOsdTestTimer = Hv_Vos_Timer_Create(&stParam);
        }
        else
        {
            Hv_Vos_Timer_Stop(s_pstOsdTestTimer);
            Hv_Vos_Timer_ChangePeriod(s_pstOsdTestTimer, 1000);
        }
        Hv_Vos_Timer_Start(s_pstOsdTestTimer);
        s_ucTestScene = 0;
    }
    else
    {
        OSD_LOG_INFO("Osd scene test stop!");
        if (NULL != s_pstOsdTestTimer)
        {
            Hv_Vos_Timer_Stop(s_pstOsdTestTimer);
        }
        s_ucTestScene = SCENE_ID_MAX * 2;
    }
}
#endif
