/**
 * @file hv_cal_OsdLine.c
 * @brief Osd Cal Line 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"

static OsdLinePhyId g_enCurrentLineIndex = PHY_WIN0_LINE_0;

static OsdWindowPhyId Hv_Cal_OsdLine_GetWindowIndex(VOID)
{
    return g_enCurrentLineIndex >> 1;
}

static UINT32 Hv_Cal_OsdLine_GetBaseAddr(VOID)
{
    OsdWindowPhyId enWinIndex = Hv_Cal_OsdLine_GetWindowIndex();
    UINT32 uiBaseAddr = Hv_Cal_OsdWindow_GetBaseAddr(enWinIndex);

    if (OSD_WINDOW_IS_NORMAL(enWinIndex))
    {
        return uiBaseAddr + _NORMAL_WIN_LINE_OFFSET + (g_enCurrentLineIndex - (enWinIndex << 1)) * OSD_LINE_SIZE;
    }
    else
    {
        return uiBaseAddr + _RECT_WIN_LINE_OFFSET + (g_enCurrentLineIndex - (enWinIndex << 1)) * OSD_LINE_SIZE;
    }
}

static INT32 Hv_Cal_OsdLine_GetAddrOffset(VOID)
{
    OsdWindowPhyId enWinIndex = Hv_Cal_OsdLine_GetWindowIndex();
    INT32 iAddrOff = 0;

    iAddrOff = enWinIndex * OSD_WIN_SIZE + (g_enCurrentLineIndex - (enWinIndex << 1)) * OSD_LINE_SIZE;

    if (!OSD_WINDOW_IS_NORMAL(enWinIndex))
    {
        iAddrOff += _RECT_WIN_LINE_OFFSET - _NORMAL_WIN_LINE_OFFSET;
    }

    return iAddrOff;
}

VOID Hv_Cal_OsdLine_SetCurrentLine(OsdLinePhyId enIndex)
{
    HV_ASSERT_TRUE_VOID(enIndex < PHY_LINE_ID_MAX);

    g_enCurrentLineIndex = enIndex;
}

VOID Hv_Cal_OsdLine_SetEnable(OsdRegionType enType, BOOL bEnable)
{
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();

    if (OSD_REGION_NO_HIGHLIGHT == enType)
    {
        HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_4C, iAddrOff, reg_00_enable0_line0, bEnable);
    }
    else if (OSD_REGION_HIGHLIGHT == enType)
    {
        HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_54, iAddrOff, reg_00_enable1_line1, bEnable);
    }
    else
    {
        return;
    }
}

BOOL Hv_Cal_OsdLine_GetEnable(OsdRegionType enType)
{
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();
    HV_R32_DECL_VAR();

    if (OSD_REGION_NO_HIGHLIGHT == enType)
    {
        return HV_R32_FIELD_EX(OSD_KV_WIN_P2_00_4C, iAddrOff, reg_00_enable0_line0);
    }
    else if (OSD_REGION_HIGHLIGHT == enType)
    {
        return HV_R32_FIELD_EX(OSD_KV_WIN_P2_00_54, iAddrOff, reg_00_enable1_line1);
    }
    else
    {
        return HV_FALSE;
    }
}

VOID Hv_Cal_OsdLine_SetPos(USHORT16 usX, USHORT16 usY)
{
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();

    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_44, iAddrOff, reg_00_start_x_line01, usX + 1);
    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_44, iAddrOff, reg_00_start_y_line01, usY + 1);
}

VOID Hv_Cal_OsdLine_GetPos(USHORT16 *pusX, USHORT16 *pusY)
{
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();
    HV_R32_DECL_VAR();

    *pusX = HV_R32_FIELD_EX(OSD_KV_WIN_P2_00_44, iAddrOff, reg_00_start_x_line01);
    *pusX = (*pusX > 0) ? (*pusX - 1) : 0;
    *pusY = HV_R32_FIELD_EX(OSD_KV_WIN_P2_00_44, iAddrOff, reg_00_start_y_line01);
    *pusY = (*pusY > 0) ? (*pusY - 1) : 0;
}

VOID Hv_Cal_OsdLine_SetLineNum(UCHAR8 ucHnum, UCHAR8 ucVnum)
{
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();

    /* IP restriction */
    ucHnum = (ucHnum > 0) ? (ucHnum - 1) : 0;
    ucHnum = (ucHnum > OSD_HNUM_MAX) ? OSD_HNUM_MAX : ucHnum;
    ucVnum = (ucVnum > OSD_VNUM_MAX) ? OSD_VNUM_MAX : ucVnum;

    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_40, iAddrOff, reg_00_num_h_line01, ucHnum);
    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_40, iAddrOff, reg_00_num_v_line01, ucVnum);
}

VOID Hv_Cal_OsdLine_GetLineNum(UCHAR8 *pucHnum, UCHAR8 *pucVnum)
{
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();
    HV_R32_DECL_VAR();

    *pucHnum = HV_R32_FIELD_EX(OSD_KV_WIN_P2_00_40, iAddrOff, reg_00_num_h_line01) + 1;
    *pucVnum = HV_R32_FIELD_EX(OSD_KV_WIN_P2_00_40, iAddrOff, reg_00_num_v_line01);
}

VOID Hv_Cal_OsdLine_SetLineSize(USHORT16 usWidth, USHORT16 usHeight)
{
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();

    /* IP restriction */
    usWidth = (usWidth > 0) ? (usWidth - 1) : 0;
    usHeight = (usHeight > 0) ? (usHeight - 1) : 0;

    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_48, iAddrOff, reg_00_size_x, usWidth);
    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_48, iAddrOff, reg_00_size_y, usHeight);
}

VOID Hv_Cal_OsdLine_GetLineSize(USHORT16 *pusWidth, USHORT16 *pusHeight)
{
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();
    HV_R32_DECL_VAR();

    *pusWidth = HV_R32_FIELD_EX(OSD_KV_WIN_P2_00_48, iAddrOff, reg_00_size_x) + 1;
    *pusHeight = HV_R32_FIELD_EX(OSD_KV_WIN_P2_00_48, iAddrOff, reg_00_size_y) + 1;
}

VOID Hv_Cal_OsdLine_SetSpace(UCHAR8 ucHSpace, UCHAR8 ucVSpace)
{
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();

    /* IP restriction */
    ucHSpace = (ucHSpace == 0xFF) ? 0xFF : (ucHSpace + 1);
    ucVSpace = (ucVSpace == 0xFF) ? 0xFF : (ucVSpace + 1);

    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_40, iAddrOff, reg_00_h_space_line01, ucHSpace);
    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_40, iAddrOff, reg_00_v_space_line01, ucVSpace);
}

VOID Hv_Cal_OsdLine_GetSpace(UCHAR8 *pucHSpace, UCHAR8 *pucVSpace)
{
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();
    HV_R32_DECL_VAR();

    *pucHSpace = HV_R32_FIELD_EX(OSD_KV_WIN_P2_00_40, iAddrOff, reg_00_h_space_line01);
    *pucHSpace = (*pucHSpace > 0) ? (*pucHSpace - 1) : 0;
    *pucVSpace = HV_R32_FIELD_EX(OSD_KV_WIN_P2_00_40, iAddrOff, reg_00_v_space_line01);
    *pucVSpace = (*pucVSpace > 0) ? (*pucVSpace - 1) : 0;
}

VOID Hv_Cal_OsdLine_SetLineBackgroundEnable(OsdRegionType enType, BOOL bEnable)
{
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();

    if (OSD_REGION_NO_HIGHLIGHT == enType)
    {
        HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_4C, iAddrOff, reg_00_fill_line0, bEnable);
    }
    else if (OSD_REGION_HIGHLIGHT == enType)
    {
        HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_54, iAddrOff, reg_00_fill_line1, bEnable);
    }
    else
    {
        return;
    }
}

VOID Hv_Cal_OsdLine_SetLineBackgroundColor(OsdRegionType enType, USHORT16 usBgColor)
{
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();

    if (OSD_REGION_NO_HIGHLIGHT == enType)
    {
        HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_50, iAddrOff, reg_00_color01_line0, usBgColor);
    }
    else if (OSD_REGION_HIGHLIGHT == enType)
    {
        HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_58, iAddrOff, reg_00_color11_line1, usBgColor);
    }
    else
    {
        return;
    }
}

VOID Hv_Cal_OsdLine_SetLineBorderColor(OsdRegionType enType, USHORT16 usBorderColor)
{
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();

    if (OSD_REGION_NO_HIGHLIGHT == enType)
    {
        HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_50, iAddrOff, reg_00_color00_line0, usBorderColor);
    }
    else if (OSD_REGION_HIGHLIGHT == enType)
    {
        HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_58, iAddrOff, reg_00_color10_line1, usBorderColor);
    }
    else
    {
        return;
    }
}

VOID Hv_Cal_OsdLine_SetHighlightHRange(UCHAR8 ucHStartNum, UCHAR8 ucHEndNum)
 {
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();

    /* IP restriction */
    ucHStartNum = (ucHStartNum > 0) ? (ucHStartNum - 1) : 0;
    ucHStartNum = (ucHStartNum > OSD_HL_HNUM_MAX) ? OSD_HL_HNUM_MAX : ucHStartNum;
    ucHEndNum = (ucHEndNum > 0) ? (ucHEndNum - 1) : 0;
    ucHEndNum = (ucHEndNum > OSD_HL_HNUM_MAX) ? OSD_HL_HNUM_MAX : ucHEndNum;
    
    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_40, iAddrOff, reg_00_hl_num_h_0_line01, ucHStartNum);
    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_4C, iAddrOff, reg_00_hl_num_h_1_line01, ucHEndNum);
 }

VOID Hv_Cal_OsdLine_SetHighlightVRange(UCHAR8 ucVStartNum, UCHAR8 ucVEndNum)
 {
    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();

    /* IP restriction */
    ucVStartNum = (ucVStartNum > 0) ? (ucVStartNum - 1) : 0;
    ucVStartNum = (ucVStartNum > OSD_HL_VNUM_MAX) ? OSD_HL_VNUM_MAX : ucVStartNum;
    ucVEndNum = (ucVEndNum > 0) ? (ucVEndNum - 1) : 0;
    ucVEndNum = (ucVEndNum > OSD_HL_VNUM_MAX) ? OSD_HL_VNUM_MAX : ucVEndNum;

    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_40, iAddrOff, reg_00_hl_num_v_0_line01, ucVStartNum);
    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_4C, iAddrOff, reg_00_hl_num_v_1_line01, ucVEndNum);
 }

/* need ip change xls */
VOID Hv_Cal_OsdLine_SetHighlightMode(OsdHighLightMode enMode)
{
    HV_ASSERT_TRUE_VOID(enMode < OSD_HIGHLIGHT_MAX);

    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();

    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_4C, iAddrOff, reg_00_hl_mode_select_line01, enMode);
}

VOID Hv_Cal_OsdLine_SetHighlightHMode(OsdHighLightAxisMode enMode)
{
    HV_ASSERT_TRUE_VOID(enMode < MATCH_MAX);

    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();

    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_4C, iAddrOff, reg_00_hl_mode_h_line01, enMode);
}

VOID Hv_Cal_OsdLine_SetHighlightVMode(OsdHighLightAxisMode enMode)
{
    HV_ASSERT_TRUE_VOID(enMode < MATCH_MAX);

    INT32 iAddrOff = Hv_Cal_OsdLine_GetAddrOffset();

    HV_W32_FIELD_EX(OSD_KV_WIN_P2_00_4C, iAddrOff, reg_00_hl_mode_v_line01, enMode);
}
