/*
 * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD
 * All rights reserved.
 *
 * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use
 * exclusively with CVA's microcontroller products. This file can be freely
 * distributed within development tools that are supporting such microcontroller
 * products.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
 * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
 * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 */

#ifndef _TABLE_H_
#define _TABLE_H_

/*! \brief Contains public interface to various functions related
 *         to the table template
 */

/*******************************************************************************
 * the includes
 ******************************************************************************/

#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/*******************************************************************************
 * the defines
 ******************************************************************************/

/*******************************************************************************
 * the typedefs
 ******************************************************************************/

/*! \brief Declaration of table prototype
 * The container should be an array in the form of buffer[rowNum][columnNum]
 */
typedef struct _TableType_
{
    void    *pContainer; /*!< The pointer to the container, which must be a 2-D array */
    uint16_t rowNum;     /*!< Total row number of the container */
    uint16_t columnNum;  /*!< Total column number of the container */
} TableType;

/*******************************************************************************
 * the globals
 ******************************************************************************/

/*******************************************************************************
 * the function prototypes
 ******************************************************************************/

/*! \brief  Initialize the TABLE object.
 *
 * This function initializes a 2-D table instance
 *
 * \note The container should be the 2-D array
 *
 * \param[in] obj : pointer to Table instance
 * \param[in] pContainer : the container (2-D array) for this table
 * \param[in] rowNum : the total row count of the table
 * \param[in] columnNum : the total column count of the table
 */
static inline void Table_Init(TableType *obj, void *pContainer, uint16_t rowNum, uint16_t columnNum)
{
    obj->pContainer = pContainer;
    obj->rowNum     = rowNum;
    obj->columnNum  = columnNum;
}

/*! \brief Get a certain element determined by row and column from the table
 *
 * This function gets a certain element determined by row and column from the table
 *
 * \param[in] obj : pointer to Table instance
 * \param[out] pElem : pointer to the element
 * \param[in] elemSize : the size of element in byte
 * \param[in] row : the row of the output element
 * \param[in] column : the column of the output element
 * \return the result of the get operation
 *         - true : succees
 *         - false : fail to get the element
 */
static inline bool Table_GetElement(const TableType *obj, void *pElem, uint16_t elemSize, uint16_t row, uint16_t column)
{
    if(row > obj->rowNum - 1 || column > obj->columnNum - 1)
    {
        return false;
    }

    int            i = 0;
    unsigned char *src;
    unsigned char *dest;

    dest = (unsigned char *)pElem;
    src  = (unsigned char *)(obj->pContainer) + elemSize * (row * obj->columnNum + column);

    for(i = 0; i < elemSize; i++)
    {
        *dest++ = *src++;
    }

    return true;
}

#ifdef __cplusplus
}
#endif /* extern "C" */

#endif /* _TABLE_H_ */
