/**
 * @file hv_cal_OsdBlend.c
 * @brief Osd Cal blending interface file.
 * @details This file provides the following functions: \n
 *          (1) Osd CAL layer initialization functions \n
 *
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2022-08-31
 * @copyright Copyright(c),2022-8, Hiview Software. All rights reserved.
 * @par History:
 * <table>
 * <tr><th>Author         <th>Date        <th>Change Description
 * <tr><td>OSD Group      <td>2022-08-31   <td>create
 * </table>
*/

#include "hv_drv_Osd.h"
#include "hv_cal_Osd.h"

INT32 Hv_Cal_OsdBlend_GetAddrOffset(OsdBlendingStage enStage)
{
    INT32 iAddrOff = 0;
    OsdWindowPhyId enCurrentWinIndex = Hv_Cal_OsdWindow_GetCurrentWindow();

    switch (enStage)
    {
        case OSD_BLENDING_STAGE_RECT_GROUP:
        {
            if (OSD_WINDOW_IS_NORMAL(enCurrentWinIndex))
            {
                iAddrOff = OSD_WIN_SIZE * enCurrentWinIndex;
            }
            else
            {
                iAddrOff = OSD_WIN_SIZE * (enCurrentWinIndex - PHY_WIN_RECT_0);
            }
            break;
        }
        case OSD_BLENDING_STAGE_RECT_FONT:
        {
            iAddrOff = OSD_WIN_SIZE * enCurrentWinIndex;
            break;
        }
        default:
        {
            break;
        }
    }

    return iAddrOff;
}

VOID Hv_Cal_OsdBlend_SetRectGroupEnable(BOOL bEnable)
{
    INT32 iAddrOff = Hv_Cal_OsdBlend_GetAddrOffset(OSD_BLENDING_STAGE_RECT_GROUP);
    OsdWindowPhyId enCurrentWinIndex = Hv_Cal_OsdWindow_GetCurrentWindow();

    if (OSD_WINDOW_IS_NORMAL(enCurrentWinIndex))
    {
        HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_10, iAddrOff, reg_00_disable_sw, !bEnable);
    }
    else
    {
        HV_W32_FIELD_EX(OSD_KV_RECT_P6_00_0C, iAddrOff, reg_00_disable_sw, !bEnable);
    }
}

VOID Hv_Cal_OsdBlend_SetBackground(OsdBlendingStage enStage, BOOL bEnable, USHORT16 usColor)
{
    INT32 iAddrOff = 0;
    OsdWindowPhyId enCurrentWinIndex = Hv_Cal_OsdWindow_GetCurrentWindow();

    switch (enStage) {
        case OSD_BLENDING_STAGE_RECT_GROUP:
        {
            iAddrOff = Hv_Cal_OsdBlend_GetAddrOffset(OSD_BLENDING_STAGE_RECT_GROUP);
            if (!OSD_WINDOW_IS_NORMAL(enCurrentWinIndex))
            {
                HV_W32_FIELD_EX(OSD_KV_RECT_P6_00_0C, iAddrOff, reg_00_enable_bg, bEnable);
                if (bEnable)
                {
                    HV_W32_FIELD_EX(OSD_KV_RECT_P6_00_0C, iAddrOff, reg_00_bg_color, usColor);
                }
            }
            break;
        }
        case OSD_BLENDING_STAGE_RECT_FONT:
        {
            iAddrOff = Hv_Cal_OsdBlend_GetAddrOffset(OSD_BLENDING_STAGE_RECT_FONT);

            HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_0C, iAddrOff, reg_00_bg_output_enable_rect_font, bEnable);
            if (bEnable)
            {
                HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_0C, iAddrOff, reg_00_bg_color, usColor);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WIN01:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_10, alpha_bg_output_win01, bEnable);
            if (bEnable)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_10, bg_color_win01, usColor);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WIN23:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_14, alpha_bg_output_win23, bEnable);
            if (bEnable)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_14, bg_color_win23, usColor);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WIN0123:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_18, alpha_bg_output_win03, bEnable);
            if (bEnable)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_18, bg_color_win03, usColor);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WINALL:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_1C, alpha_bg_output_win_rect, bEnable);
            if (bEnable)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_1C, bg_color_win_rect, usColor);
            }
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Cal_OsdBlend_SetBackgroundAlpha(OsdBlendingStage enStage, UCHAR8 ucAlpha)
{
    INT32 iAddrOff = 0;
    OsdWindowPhyId enCurrentWinIndex = Hv_Cal_OsdWindow_GetCurrentWindow();

    switch (enStage) {
        case OSD_BLENDING_STAGE_RECT_GROUP:
        {
            iAddrOff = Hv_Cal_OsdBlend_GetAddrOffset(OSD_BLENDING_STAGE_RECT_GROUP);

            if (!OSD_WINDOW_IS_NORMAL(enCurrentWinIndex))
            {
                HV_W32_FIELD_EX(OSD_KV_RECT_P6_00_10, iAddrOff, reg_00_bg_alpha, ucAlpha);
            }
            break;
        }
        case OSD_BLENDING_STAGE_RECT_FONT:
        {
            iAddrOff = Hv_Cal_OsdBlend_GetAddrOffset(OSD_BLENDING_STAGE_RECT_FONT);

            HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_0C, iAddrOff, reg_00_bg_alpha, ucAlpha);
            break;
        }
        case OSD_BLENDING_STAGE_WIN01:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_10, alpha_value_win01, ucAlpha);
            break;
        }
        case OSD_BLENDING_STAGE_WIN23:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_14, alpha_value_win23, ucAlpha);
            break;
        }
        case OSD_BLENDING_STAGE_WIN0123:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_18, alpha_value_win03, ucAlpha);
            break;
        }
        case OSD_BLENDING_STAGE_WINALL:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_1C, alpha_value_win_rect, ucAlpha);
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Cal_OsdBlend_SetForegroundAlpha(OsdBlendingStage enStage, UCHAR8 ucAlpha)
{
    INT32 iAddrOff = 0;
    OsdWindowPhyId enCurrentWinIndex = Hv_Cal_OsdWindow_GetCurrentWindow();

    switch (enStage)
    {
        case OSD_BLENDING_STAGE_RECT_GROUP:
        {
            iAddrOff = Hv_Cal_OsdBlend_GetAddrOffset(OSD_BLENDING_STAGE_RECT_GROUP);

            if (OSD_WINDOW_IS_NORMAL(enCurrentWinIndex))
            {
                HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_10, iAddrOff, reg_00_rect_alpha, ucAlpha);
            }
            else
            {
                HV_W32_FIELD_EX(OSD_KV_RECT_P6_00_0C, iAddrOff, reg_00_alpha, ucAlpha);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WINRECT:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_20, rect_alpha_win_rectx, ucAlpha);
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Cal_OsdBlend_SetSwitch(OsdBlendingStage enStage, BOOL bEnableSwitch)
{
    INT32 iAddrOff = 0;

    switch (enStage)
    {
        case OSD_BLENDING_STAGE_RECT_FONT:
        {
            iAddrOff = Hv_Cal_OsdBlend_GetAddrOffset(OSD_BLENDING_STAGE_RECT_FONT);

            HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_0C, iAddrOff, reg_00_alpha_switch, bEnableSwitch);
            break;
        }
        case OSD_BLENDING_STAGE_WIN01:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_10, alpha_switch_win01, bEnableSwitch);
            break;
        }
        case OSD_BLENDING_STAGE_WIN23:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_14, alpha_switch_win23, bEnableSwitch);
            break;
        }
        case OSD_BLENDING_STAGE_WIN0123:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_18, alpha_switch_win03, bEnableSwitch);
            break;
        }
        case OSD_BLENDING_STAGE_WINALL:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_1C, alpha_switch_win_rect, bEnableSwitch);
            break;
        }
        case OSD_BLENDING_STAGE_GRAPHIC:
        {
            HV_W32_FIELD(DISP_TOP_KOSD_TOP_24, osd_win3all_bmp_alpha_switch, bEnableSwitch);
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Cal_OsdBlend_SetAlphaSelect(OsdBlendingStage enStage, OsdAlphaSelectType enType, UCHAR8 ucValue)
{
    INT32 iAddrOff = 0;

    switch (enStage)
    {
        case OSD_BLENDING_STAGE_RECT_FONT:
        {
            iAddrOff = Hv_Cal_OsdBlend_GetAddrOffset(OSD_BLENDING_STAGE_RECT_FONT);

            HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_0C, iAddrOff, reg_00_alpha_ctrl, enType);
            if (enType > OSD_ALPHA_TYPE_CH1)
            {
                HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_0C, iAddrOff, reg_00_bg_alpha, ucValue);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WIN01:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_10, alpha_ctrl_win01, enType);
            if (enType > OSD_ALPHA_TYPE_CH1)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_10, alpha_value_win01, ucValue);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WIN23:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_14, alpha_ctrl_win23, enType);
            if (enType > OSD_ALPHA_TYPE_CH1)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_14, alpha_value_win23, ucValue);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WIN0123:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_18, alpha_ctrl_win03, enType);
            if (enType > OSD_ALPHA_TYPE_CH1)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_18, alpha_value_win03, ucValue);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WINALL:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_1C, alpha_ctrl_win_rect, enType);
            if (enType > OSD_ALPHA_TYPE_CH1)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_1C, alpha_value_win_rect, ucValue);
            }
            break;
        }
        case OSD_BLENDING_STAGE_GRAPHIC:
        {
            HV_W32_FIELD(DISP_TOP_KOSD_TOP_24, osd_win3all_bmp_alpha_ctrl, enType);
            if (enType > OSD_ALPHA_TYPE_CH1)
            {
                HV_W32_FIELD(DISP_TOP_KOSD_TOP_24, osd_win3all_bmp_alpha_value, ucValue);
            }
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Cal_OsdBlend_SetAlphaOutput(OsdBlendingStage enStage, OsdAlphaOutputType enType, UCHAR8 ucValue)
{
    INT32 iAddrOff = 0;

    switch (enStage)
    {
        case OSD_BLENDING_STAGE_RECT_FONT:
        {
            iAddrOff = Hv_Cal_OsdBlend_GetAddrOffset(OSD_BLENDING_STAGE_RECT_FONT);

            if (enType < OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_0C, iAddrOff, reg_00_alpha_set, 0);
                HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_0C, iAddrOff, reg_00_alpha_select, enType);
            }
            else if (enType == OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_0C, iAddrOff, reg_00_alpha_set, 1);
            }
            if (enType == OSD_ALPHA_OUTPUT_FF_SET || enType == OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_0C, iAddrOff, reg_00_bg_alpha, ucValue);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WIN01:
        {
            if (enType < OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_10, alpha_set_win01, 0);
                HV_W32_FIELD(OSD_KV_TOP_CTRL_10, alpha_select_win01, enType);
            }
            else if (enType == OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_10, alpha_set_win01, 1);
            }
            if (enType == OSD_ALPHA_OUTPUT_FF_SET || enType == OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_10, alpha_value_win01, ucValue);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WIN23:
        {
            if (enType < OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_14, alpha_set_win23, 0);
                HV_W32_FIELD(OSD_KV_TOP_CTRL_14, alpha_select_win23, enType);
            }
            else if (enType == OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_14, alpha_set_win23, 1);
            }
            if (enType == OSD_ALPHA_OUTPUT_FF_SET || enType == OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_14, alpha_value_win23, ucValue);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WIN0123:
        {
            if (enType < OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_18, alpha_set_win03, 0);
                HV_W32_FIELD(OSD_KV_TOP_CTRL_18, alpha_select_win03, enType);
            }
            else if (enType == OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_18, alpha_set_win03, 1);
            }
            if (enType == OSD_ALPHA_OUTPUT_FF_SET || enType == OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_18, alpha_value_win03, ucValue);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WINRECT:
        {
            if (enType == OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_20, output_alpha_ctrl_win_rectx, 1);
                HV_W32_FIELD(OSD_KV_TOP_CTRL_20, rect_alpha_win_rectx, ucValue);
            }
            else
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_20, output_alpha_ctrl_win_rectx, 0);
            }
            break;
        }
        case OSD_BLENDING_STAGE_WINALL:
        {
            if (enType < OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_1C, alpha_set_win_rect, 0);
                HV_W32_FIELD(OSD_KV_TOP_CTRL_1C, alpha_select_win_rect, enType);
            }
            else if (enType == OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_1C, alpha_set_win_rect, 1);
            }
            if (enType == OSD_ALPHA_OUTPUT_FF_SET || enType == OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(OSD_KV_TOP_CTRL_1C, alpha_value_win_rect, ucValue);
            }
            break;
        }
        case OSD_BLENDING_STAGE_GRAPHIC:
        {
            if (enType < OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(DISP_TOP_KOSD_TOP_24, osd_win3all_bmp_alpha_set, 0);
                HV_W32_FIELD(DISP_TOP_KOSD_TOP_24, osd_win3all_bmp_alpha_select, enType);
            }
            else if (enType == OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(DISP_TOP_KOSD_TOP_24, osd_win3all_bmp_alpha_set, 1);
            }
            if (enType == OSD_ALPHA_OUTPUT_FF_SET || enType == OSD_ALPHA_OUTPUT_FORCE)
            {
                HV_W32_FIELD(DISP_TOP_KOSD_TOP_24, osd_win3all_bmp_alpha_value, ucValue);
            }
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Cal_OsdBlend_SetAlphaOutputRatioEnable(OsdBlendingStage enStage, BOOL bEnable)
{
    INT32 iAddrOff = 0;

    switch (enStage)
    {
        case OSD_BLENDING_STAGE_RECT_FONT:
        {
            iAddrOff = Hv_Cal_OsdBlend_GetAddrOffset(OSD_BLENDING_STAGE_RECT_FONT);

            HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_0C, iAddrOff, reg_00_alpha_coef, 0);
            break;
        }
        case OSD_BLENDING_STAGE_WIN01:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_10, alpha_coef_win01, 0);
            break;
        }
        case OSD_BLENDING_STAGE_WIN23:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_14, alpha_coef_win23, 0);
            break;
        }
        case OSD_BLENDING_STAGE_WIN0123:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_18, alpha_coef_win03, 0);
            break;
        }
        case OSD_BLENDING_STAGE_WINALL:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_1C, alpha_coef_win_rect, 0);
            break;
        }
        case OSD_BLENDING_STAGE_GRAPHIC:
        {
            HV_W32_FIELD(DISP_TOP_KOSD_TOP_24, osd_win3all_bmp_alpha_coef, 0);
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Cal_OsdBlend_SetAlphaOutputRatio(OsdBlendingStage enStage, UCHAR8 ucRatio)
{
    INT32 iAddrOff = 0;

    switch (enStage)
    {
        case OSD_BLENDING_STAGE_RECT_FONT:
        {
            iAddrOff = Hv_Cal_OsdBlend_GetAddrOffset(OSD_BLENDING_STAGE_RECT_FONT);

            HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_0C, iAddrOff, reg_00_alpha_coef, 1);
            HV_W32_FIELD_EX(OSD_KV_WIN_P6_00_0C, iAddrOff, reg_00_bg_alpha, 1);
            break;
        }
        case OSD_BLENDING_STAGE_WIN01:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_10, alpha_coef_win01, 1);
            HV_W32_FIELD(OSD_KV_TOP_CTRL_10, alpha_value_win01, ucRatio);
            break;
        }
        case OSD_BLENDING_STAGE_WIN23:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_14, alpha_coef_win23, 1);
            HV_W32_FIELD(OSD_KV_TOP_CTRL_14, alpha_value_win23, ucRatio);
            break;
        }
        case OSD_BLENDING_STAGE_WIN0123:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_18, alpha_coef_win03, 1);
            HV_W32_FIELD(OSD_KV_TOP_CTRL_18, alpha_value_win03, ucRatio);
            break;
        }
        case OSD_BLENDING_STAGE_WINALL:
        {
            HV_W32_FIELD(OSD_KV_TOP_CTRL_1C, alpha_coef_win_rect, 1);
            HV_W32_FIELD(OSD_KV_TOP_CTRL_1C, alpha_value_win_rect, ucRatio);
            break;
        }
        case OSD_BLENDING_STAGE_GRAPHIC:
        {
            HV_W32_FIELD(DISP_TOP_KOSD_TOP_24, osd_win3all_bmp_alpha_coef, 1);
            HV_W32_FIELD(DISP_TOP_KOSD_TOP_24, osd_win3all_bmp_alpha_value, ucRatio);
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Cal_OsdBlend_SetWinrectPriority(BOOL bReversePriority)
{
    HV_W32_FIELD(OSD_KV_TOP_CTRL_20, ch_select_win_rectx, bReversePriority);
}

VOID Hv_Cal_OsdBlend_Init(VOID)
{
    HV_W32_FIELD(DISP_TOP_KOSD_TOP_00, osd_engine_winall_bld0_en, 1);
    HV_W32_FIELD(DISP_TOP_KOSD_TOP_00, osd_engine_winall_bld1_en, 0);
}
