/**
 *******************************************************************************
 * @file  menu_page.c
 * @brief This file provides firmware functions to manage the menu page.
 @verbatim
   Change Logs:
   Date             Author          Notes
   2022-06-30       CDT             First version
 @endverbatim
 *******************************************************************************
 * Copyright (C) 2022-2023, Xiaohua Semiconductor Co., Ltd. All rights reserved.
 *
 * This software component is licensed by XHSC under BSD 3-Clause license
 * (the "License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                    opensource.org/licenses/BSD-3-Clause
 *
 *******************************************************************************
 */

/*******************************************************************************
 * Include files
 ******************************************************************************/
#include "menu_page.h"

/**
 * @addtogroup Serial_Port_Console
 * @{
 */

/**
 * @defgroup Menu_Page Menu Page
 * @{
 */

/*******************************************************************************
 * Local type definitions ('typedef')
 ******************************************************************************/

/*******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/

/*******************************************************************************
 * Global variable definitions (declared in header file with 'extern')
 ******************************************************************************/

/*******************************************************************************
 * Local function prototypes ('static')
 ******************************************************************************/

/*******************************************************************************
 * Local variable definitions ('static')
 ******************************************************************************/

/*******************************************************************************
 * Function implementation - global ('extern') and local ('static')
 ******************************************************************************/
/**
 * @defgroup Menu_Page_Global_Functions Menu Page Global Functions
 * @{
 */

/**
 * @brief  Create page.
 * @param  [in] pstcPageAttr        Pointer to a @ref stc_menu_page_attr_t structure.
 * @retval Pointer to a @ref stc_menu_page_t structure
 */
stc_menu_page_t *Menu_Page_Create(const stc_menu_page_attr_t *pstcPageAttr)
{
    stc_menu_page_t *pstcPage = NULL;

    if (NULL != pstcPageAttr) {
        pstcPage = (stc_menu_page_t *)malloc(sizeof(stc_menu_page_t));
        if (pstcPage != NULL) {
            pstcPage->pstcPageAttr = pstcPageAttr;
            INIT_SLIST_HEAD(&pstcPage->stcPageNode);
            INIT_SLIST_HEAD(&pstcPage->stcListRoot);
        }
    }

    return pstcPage;
}

/**
 * @brief  Destroy page.
 * @param  [in] pstcPage            Pointer to a @ref stc_menu_page_t structure.
 * @retval Pointer to a @ref stc_menu_page_t structure
 */
void Menu_Page_Destroy(stc_menu_page_t *pstcPage)
{
    if (pstcPage != NULL) {
        free(pstcPage);
    }
}

/**
 * @brief  Find list.
 * @param  [in] pstcPage            Pointer to a @ref stc_menu_page_t structure.
 * @param  [in] pcListName          Pointer to title characters
 * @retval Pointer to a @ref stc_menu_list_t structure.
 */
stc_menu_list_t *Menu_Page_FindList(stc_menu_page_t *pstcPage, const char *pcListName)
{
    stc_slist_t *pstcPos;
    stc_menu_list_t *pstcListTmp;
    stc_menu_list_t *pstcList = NULL;

    if ((pstcPage != NULL) && (pcListName != NULL)) {
        slist_for_each(pstcPos, &pstcPage->stcListRoot) {
            pstcListTmp = ((stc_menu_list_t *)pstcPos);
            if (0 == strcmp(pstcListTmp->pstcListAttr->pcName, pcListName)) {
                pstcList = pstcListTmp;
                break;
            }
        }
    }

    return pstcList;
}

/**
 * @brief  Page insert list.
 * @param  [in] pstcPage            Pointer to a @ref stc_menu_page_t structure.
 * @param  [in] pstcList            Pointer to a @ref stc_menu_list_t structure.
 * @retval int32_t:
 *           - OPCODE_OK:           Insert successfully.
 *           - OPCODE_ERR:          If one of following cases matches:
 *                                  - The pointer pstcPage is NULL.
 *                                  - The pointer pstcList is NULL.
 *                                  - The list have been inserted.
 */
int32_t Menu_Page_InsertList(stc_menu_page_t *pstcPage, stc_menu_list_t *pstcList)
{
    int32_t i32Ret = OPCODE_ERR;

    if ((pstcPage != NULL) && (pstcList != NULL) && \
        (pstcList->pstcListAttr != NULL) && (pstcList->pstcListAttr->pcName != NULL)) {
        if (Menu_Page_FindList(pstcPage, pstcList->pstcListAttr->pcName) == NULL) {
            INIT_SLIST_HEAD(&pstcList->stcListNode);
            slist_add_tail(&pstcPage->stcListRoot, &pstcList->stcListNode);
            i32Ret = OPCODE_OK;
        }
    }

    return i32Ret;
}

/**
 * @brief  Show page attribute(including page, list and item).
 * @param  [in] pstcPage            Pointer to a @ref stc_menu_page_t structure
 * @param  [in] pfnItemShow         The callback function of show
 * @retval None
 */
void Menu_Page_ShowAttr(stc_menu_page_t *pstcPage, int32_t (*pfnItemShow)(stc_menu_item_t *))
{
    stc_slist_t *pstcPos;

    if ((pstcPage != NULL) && (pstcPage->pstcPageAttr != NULL) && (pfnItemShow != NULL)) {
        if (pstcPage->pstcPageAttr->pcBorderTop != NULL) {
            printf(pstcPage->pstcPageAttr->pcDisplayFormatBorderTop, pstcPage->pstcPageAttr->pcBorderTop);
        }

        if (pstcPage->pstcPageAttr->pcTitle != NULL) {
            printf(pstcPage->pstcPageAttr->pcDisplayFormatTitle, pstcPage->pstcPageAttr->pcTitle);
        }

        slist_for_each(pstcPos, &pstcPage->stcListRoot) {
            Menu_List_ShowAttr((stc_menu_list_t *)pstcPos, pfnItemShow);
            if (pstcPage->pstcPageAttr->pcListSeparatorLine != NULL) {
                printf(pstcPage->pstcPageAttr->pcDisplayFormatListSeparatorLine, pstcPage->pstcPageAttr->pcListSeparatorLine);
            }
        }

        if (pstcPage->pstcPageAttr->pcBorderBottom != NULL) {
            printf("%s ", pstcPage->pstcPageAttr->pcBorderBottom);
        }
    }
}

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

/*******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/
