/******************************************************************************
** 文件名:  EnvelopeManage.h
** 描 述:   列车包络管理模块功能处理头文件，该头文件定义的函数仅该模块使用，不对外提供
*******************************************************************************/

#ifndef ENVELOPE_MANAGE_H_
#define ENVELOPE_MANAGE_H_

#include "EnvelopeDefine.h"
#include "ELMDataPrepare.h"


/*区段映射到包络的映射表*/
typedef struct {
	UINT8 envelopeCnt;   /*包络个数*/
	UINT16 envelopeId[SECTION_REL_ENVELOPE_SUM_MAX];   /*包络ID*/
}EnvelopeMapStruct; 


/* 列车映射到包络的映射表 */
typedef struct {
	UINT8 envelopeCnt;   /*包络个数*/
	UINT16 envelopeId[TRAIN_REL_ENVELOPE_SUM_MAX];   /*包络ID*/
}TrainMapStruct; 

/*内存区,左闭右开区间约定内存操作可用范围*/
typedef struct{
	const void * pStartVaild;
	const void * pEndVaild;
}MemAreaStruct;


/**
* @brief  检测需要操作的目标内存区是否在可用内存区内
* @param[in] MemAreaStruct targetArea  需要操作的目标内存区
* @param[in] MemAreaStruct valiArea  可用内存区
* @return CI_SUCCESS 需要操作的内存区正确，返回成功
*         CI_ERROR   需要操作的内存区错误，返回失败
* @note 需要操作的目标内存区完全包含于可用内存区时，则认为合法；
可用内存区采用是一个左闭右开区间
目标内存区采用的是一个左闭右开区间
*/
UINT8 elm_IsMemAreaOK(MemAreaStruct targetArea, MemAreaStruct valiArea);

/**
* @brief 检测包络内存区操作是否正确
* @param[in] EnvelopeStruct *pEnvelope 需要操作的内存区起始地址
* @param[in] UINT16 size 需要操作的内存区个数
* @return CI_SUCCESS 需要操作的内存区正确，返回成功
*         CI_ERROR   需要操作的内存区错误，返回失败
* @note 通过指针地址及大小计算需要操作的包络内存区是否在可用的地址空间
*/
UINT8 elm_IsEnvelopeMemOK(IN EnvelopeStruct *pEnvelope, UINT16 size);

/**
* @brief 检测计轴关联的包络映射表内存区操作是否正确
* @param[in] EnvelopeMapStruct *pRelEnvelope 需要操作的内存区起始地址
* @param[in] UINT16 size 需要操作的内存区个数
* @return CI_SUCCESS 需要操作的内存区正确，返回成功
*         CI_ERROR   需要操作的内存区错误，返回失败
* @note 通过指针地址及大小计算需要操作的包络内存区是否在可用的地址空间
*/
UINT8 elm_IsACRelEnvelopeMapMemOK(IN EnvelopeMapStruct *pRelEnvelope, UINT16 size);


/**
* @brief 检测计轴关联的包络映射表内存区操作是否正确
* @param[in] TrainMapStruct *pRelEnvelope 需要操作的内存区起始地址
* @param[in] UINT16 size 需要操作的内存区个数
* @return CI_SUCCESS 需要操作的内存区正确，返回成功
*         CI_ERROR   需要操作的内存区错误，返回失败
* @note 通过指针地址及大小计算需要操作的包络内存区是否在可用的地址空间
*/
UINT8 elm_IsTrainRelEnvelopeMapMemOK(IN TrainMapStruct *pRelEnvelope, UINT16 size);

/**
* @brief 判断索引是否正确
* @param[in] UINT16 EnvelopeID 包络索引ID
* @param[in] UINT16 size 需要操作的内存区个数
* @return CI_SUCCESS 包络ID合法，返回成功
*         CI_ERROR   包络ID非法，返回失败
* @note 无
*/
UINT8 elm_IsEnvelopeIDOK(UINT16 EnvelopeID);


/**
* @brief 判断包络信息是否正确
* @param[in] const EnvelopeMapStruct *pRelEnvelope 包络信息
* @param[in] UINT16 EnvelopeID 包络ID
* @return CI_SUCCESS 包络ID合法，返回成功
*         CI_ERROR   包络ID非法，返回失败
* @note 无
*/
UINT8 elm_IsEnvelopeInfoOk(IN const EnvelopeStruct *pEnvelope, UINT16 EnvelopeID);


/**
* @brief 重置包络存储空间
* @param[in] EnvelopeStruct *pEnvelope 需要操作的内存区起始地址
* @param[in] UINT16 size 需要操作的内存区个数
* @return CI_SUCCESS 需要操作的内存区正确，返回成功
*         CI_ERROR   需要操作的内存区错误，返回失败
* @note 将指定的包络空间初始化成0
*/
UINT8 elm_ResetEnvelope(INOUT EnvelopeStruct *pEnvelope, UINT16 size);

/**
* @brief 重置计轴关联的包络映射表
* @param[in] EnvelopeMapStruct *pEnvelope 需要操作的内存区起始地址
* @param[in] UINT16 size 需要操作的内存区个数
* @return CI_SUCCESS 需要操作的内存区正确，返回成功
*         CI_ERROR   需要操作的内存区错误，返回失败
* @note 将指定的包络空间初始化成0
*/
UINT8 elm_ResetACRelEnvelopeMap(INOUT EnvelopeMapStruct *pRelEnvelopeMap, UINT16 size);

/**
* @brief 重置列车关联的包络映射表
* @param[in] UINT16 *pEnvelope 需要操作的内存区起始地址
* @param[in] UINT16 size 需要操作的内存区个数
* @return CI_SUCCESS 需要操作的内存区正确，返回成功
*         CI_ERROR   需要操作的内存区错误，返回失败
* @note 将指定的包络空间初始化成0
*/
UINT8 elm_ResetTrainRelEnvelopeMap(INOUT TrainMapStruct *pRelEnvelopeMap, UINT16 size);

/**
 * @brief 初始化包络存储空间
 * @param[in] EnvelopeStruct *pEnvelope 需要操作的内存区起始地址
 * @param[in] UINT16 size 需要操作的内存区个数
 * @return CI_SUCCESS 需要操作的内存区正确，返回成功
 *         CI_ERROR   需要操作的内存区错误，返回失败
 * @note 将指定的包络空间初始化成0
 */
UINT8 elm_InitEnvelope(void);

/**
 * @brief 初始化计轴关联的包络映射表
 * @param[in] EnvelopeMapStruct *pEnvelope 需要操作的内存区起始地址
 * @param[in] UINT16 size 需要操作的内存区个数
 * @return CI_SUCCESS 需要操作的内存区正确，返回成功
 *         CI_ERROR   需要操作的内存区错误，返回失败
 * @note 将指定的包络空间初始化成0
 */
UINT8 elm_InitACRelEnvelopeMap(void);

/**
 * @brief 初始化列车关联的包络映射表
 * @param[in] EnvelopeMapStruct *pEnvelope 需要操作的内存区起始地址
 * @param[in] UINT16 size 需要操作的内存区个数
 * @return CI_SUCCESS 需要操作的内存区正确，返回成功
 *         CI_ERROR   需要操作的内存区错误，返回失败
 * @note 将指定的包络空间初始化成0
 */
UINT8 elm_InitTrainRelEnvelopeMap(void);


/**
 * @brief 判断包络是否存在
 * @param[in] UINT16 EnvelopeID 包络ID
 * @return ENVELOPE_UNEXIT 包络不存在
 *         ENVELOPE_EXIT   包络存在
 * @note 通过判断包络存储空间是否被占用，判断包络是否存在
 */
UINT8 elm_IsEnvelopeExit(UINT16 EnvelopeID);


/**
 * @brief 在指定空间上存储包络
 * @param[in] const EnvelopeStruct *pSrcEnnelope 需要存储的包络地址
 * @param[in] UINT16 index 需要存储到目标内存区域索引
 * @return CI_SUCCESS 设置成功，返回成功
 *         CI_ERROR   设置错误，返回失败
 * @note 无
 */
UINT8 elm_SetEnvelopeByIndex(IN const EnvelopeStruct *pSrcEnnelope,UINT16 index);


/**
 * @brief 更新计轴区段关联的包络
 * @param[in] UINT8 flag 操作标识
 * @param[in] UINT16 ACIndex 计轴数组索引
 * @param[in] UINT16 envelopeID 包络ID
 * @return 
 * @note 包络的ID和存储空间数组索引保持一致
         计轴区段映射到存储空间，使用计轴区段的索引
 */
UINT8 elm_SetACRelEnvelopeMap(UINT8 flag,UINT16 ACIndex,UINT16 envelopeID);


/**
 * @brief 更新列车关联的包络
 * @param[in] UINT8 flag 操作标识
 * @param[in] UINT16 trainID 列车ID
 * @param[in] UINT16 envelopeID 包络ID
 * @return CI_SUCCESS 删除成功，返回成功
 *         CI_ERROR   删除错误，返回失败
 * @note 注：只有本TIOC控区内的包络才有列车到包络之间的映射关系
 */
UINT8 elm_SetTrainRelEnvelopeMap(UINT8 flag,UINT16 trainID,UINT16 envelopeID);

/**
 * @brief 设置包络存储空间可用标识
 * @param[in] UINT16 index 数组下标
 * @param[in] UINT8 value 需要设置的值
 * @return CI_SUCCESS 设置成功，返回成功
 *         CI_ERROR   设置错误，返回失败
 * @note 无
 */
UINT8 elm_SetEnvelopeValidFlag(UINT16 index,UINT8 value);


/**
 * @brief 设置包络的起点和终点位置
 * @param[in] UINT16 envelopid 包络ID
 * @param[in] LOD_STRU startPoint 起点位置
 * @param[in] LOD_STRU endPoint 终点位置
 * @return CI_SUCCESS 设置成功，返回成功
 *         CI_ERROR   设置错误，返回失败
 * @note 无
 */
UINT8 elm_SetEnvelopeLoc(UINT16 envelopid,LOD_STRU startPoint,LOD_STRU endPoint);

/**
 * @brief 设置包络的起点方向
 * @param[in] UINT16 envelopid 包络ID
 * @param[in] UINT8 cStartDir 起点方向
 * @return CI_SUCCESS 设置成功，返回成功
 *         CI_ERROR   设置错误，返回失败
 */
UINT8 elm_SetEnvelopeStartDir(UINT16 envelopid, UINT8 cStartDir);

/**
 * @brief 设置包络的终点方向
 * @param[in] UINT16 envelopid 包络ID
 * @param[in] UINT8 cEndDir 终点方向
 * @return CI_SUCCESS 设置成功，返回成功
 *         CI_ERROR   设置错误，返回失败
 */
UINT8 elm_SetEnvelopeEndDir(UINT16 envelopid, UINT8 cEndDir);

/**
 * @brief 设置包络的计轴区段信息
 * @param[in] UINT16 envelopid 包络ID
 * @param[in] LOD_STRU startPoint 起点位置
 * @param[in] LOD_STRU endPoint 终点位置
 * @return CI_SUCCESS 设置成功，返回成功
 *         CI_ERROR   设置错误，返回失败
 * @note 无
 */
UINT8 elm_SetEnvelopeACInfo(UINT16 envelopid,UINT8 acCnt,IN const UINT16 acID[SECTION_IN_ENVELOPE_SUM_MAX]);


/**
 * @brief 设置包络前方列车
 * @param[in] INT16 envelopid 包络id
 * @param[in] UINT16 tainid 列车id
 * @return CI_SUCCESS 设置成功，返回成功
 *         CI_ERROR   设置错误，返回失败
 * @note 无
 */
UINT8 elm_SetEnvelopeHeadTrainID(UINT16 envelopid,UINT16 tainid);

/**
 * @brief 设置包络后方列车
 * @param[in] UINT16 envelopid 包络id
 * @param[in] UINT16 tainid 列车id
 * @return CI_SUCCESS 设置成功，返回成功
 *         CI_ERROR   设置错误，返回失败
 * @note 无
 */
UINT8 elm_SetEnvelopeTailTrainID(UINT16 envelopid,UINT16 tainid);

/**
 * @brief 设置包络类型 
 * @param[in] UINT16 envelopid 包络id 
 * @param[in] UINT8 envelopType 包络类型
 * @param[out] 无
 * @return CI_SUCCESS 设置成功，返回成功
 *         CI_ERROR   设置错误，返回失败
 * @note 无
 */
UINT8 elm_SetEnvelopeType(UINT16 envelopeId,UINT8 envelopType);

/**
 * @brief 设置包络管理模块是否可正常处理
 * @param[in] UINT8 workFlag
 * @note 无
 */
void elm_SetELMWorkFlag(UINT8 workFlag);

/**
 * @brief 设置包络管理模块是否可正常处理
 * @return ELM_WORK_ERROR 不可正常工作
           ELM_WORK_OK 可正常工作
 * @note 无
 */
UINT8 elm_GetELMWorkFlag(void);



/**
 * @brief 获取可用的存储空间索引下标
 * @param[in] 
 * @param[out]
 * @return ENVELOPE_UNVAILD_INDEX  无可用的存储空间下标
		   非ENVELOPE_UNVAILD_INDEX  合法的可用的 存储空间下标
 * @note 无
 */
UINT16 elm_GetEnvelopeValidIndex(void);

/**
 * @brief 拷贝列车ID关联的包络信息映射表地址
 * @param[in] UINT16 trainID 列车ID
 * @return 关联的包络地址
 * @note 如果处理错误，返回NULL
 */
const TrainMapStruct * elm_GetTrainRelEnvelopeMapPtr(UINT16 trainID);

/**
 * @brief 获取列车ID关联的包络信息
 * @param[in] UINT16 trainID 列车ID
 * @param[out] UINT16 envelopeID[TRAIN_REL_ENVELOPE_SUM_MAX] 关联的包络ID
 * @return 关联的包络数量
 * @note 如果处理错误，返回TRAIN_REL_ENVELOPE_SUM_MAX
 */
UINT8 elm_GetRelELIdByTrainID(UINT16 trainID, UINT16 envelopeID[TRAIN_REL_ENVELOPE_SUM_MAX]);

/**
 * @brief 通过列车ID获取包络存储地址索引
 * @param[in] UINT8 envelopeType 包络类型
 * @param[in] UINT16 trainID 列车ID
 * @param[out] UINT16 envelopeID[TRAIN_REL_ENVELOPE_SUM_MAX] 关联的包络ID
 * @return 关联的包络数量
 * @note 如果处理错误，返回TRAIN_REL_ENVELOPE_ERROR_CNT
 */
UINT8 elm_GetRelELIdByTrainIDAndType(UINT8 envelopeType, UINT16 trainID, UINT16 envelopeID[TRAIN_REL_ENVELOPE_SUM_MAX]);


/**
 * @brief 获取计轴数组索引关联的包络个数和包络ID
 * @param[in] UINT16 ACIndex 计轴数组索引
 * @param[out] UINT16 envelopeId[SECTION_REL_ENVELOPE_SUM_MAX] 关联的包络ID
 * @return 关联的包络数量
 * @note 如果处理错误，返回SECTION_REL_ENVELOPE_SUM_MAX
 */
UINT8 elm_GetACRelEnvelopeCnt(UINT16 ACIndex,INOUT UINT16 envelopeId[SECTION_REL_ENVELOPE_SUM_MAX]);


/**
 * @brief 通过包络ID获取包络的信息
 * @param[in] UINT16 envelopeId 包络ID
 * @return 包络信息存储地址
 * @note 包络ID和包络索引一回事，包络指针只能使用，不能通过指针修改对应的值
 */
const EnvelopeStruct* elm_GetEnvelopeInfoPtr(UINT16 envelopeId);


/**
 * @brief 清空指定包络
 * @param[in] UINT16 envelopeId 包络ID
 * @return CI_SUCCESS 处理成功
 *         CI_ERROR   处理错误
 * @note 无
 */
UINT8 elm_ClearEnvelope(UINT16 envelopeId);


/**
 * @brief 将列车ID加入到包络包含的列车序列中
 *  @param[in] UINT8 flag 栈头还是栈尾
 * @param[in] UINT8 trainId 列车ID
 * @param[in] UINT16 envelopeID 包络ID
 * @param[out] 无
 * @return 
 * @note 
 */
UINT8 elm_PushToTrainSeq(UINT8 flag,UINT16 envelopeID,UINT16 trainId);

/**
 * @brief 在列车序列中删除列车ID
 * @param[in] UINT16 envelopeID 包络ID
 * @param[in] UINT8 trainId 列车ID
 * @param[out] 无
 * @return 
 * @note 
 */
UINT8 elm_DeleteTrainFromSeq(UINT16 envelopeID,UINT16 trainId);


/**
 * @brief 包络包含的计轴栈中进行头部弹出或者尾部弹出
 * @param[in] UINT8 flag 栈头或者栈尾进行弹出
 * @param[in] UINT16 envelopeID 包络ID
 * @param[out] 无
 * @return CI_SUCCESS 处理成功
 *         CI_ERROR   处理错误
 * @note 无
 */
UINT8 elm_PopEnvelopACSeq(UINT8 flag, UINT16 envelopeID);

/**
 * @brief 包络包含的计轴栈中进行头部压出或者尾部压出
 * @param[in] UINT8 flag 栈头或者栈尾进行弹出
 * @param[in] UINT16 envelopeID 包络ID
 * @param[in] UINT16 ACID 计轴ID
 * @param[out] 无
 * @return CI_SUCCESS 处理成功
 *         CI_ERROR   处理错误
 * @note 无
 */
UINT8 elm_PushEnvelopeACSeq(UINT8 flag, UINT16 envelopeID,UINT16 ACID);


/**
 * @brief 设置包络中列车的激活端
 * @param[in] UINT16 envelopeID 包络ID
 * @param[in] UINT8 trainId 列车ID
 * @param[in] UINT8 ACTPort 列车激活端
 * @param[out] 无
 * @return 无
 * @note 无
 */
void elm_SetTrainACTPortInELM(UINT16 envelopeID,UINT16 trainId,UINT8 ACTPort);

/**
 * @brief 获取包络中列车的激活端
 * @param[in] UINT16 envelopeID 包络ID
 * @param[in] UINT8 trainId 列车ID
 * @param[out] 无
 * @return UINT8 列车激活端
 * @note 无
 */
UINT8 elm_GetTrainACTPortInELM(UINT16 envelopeID,UINT16 trainId);

/**
 * @brief 设置UCT包络转UKT包络起始时间
 * @param[in] UINT16 wEnvelopid 包络ID
 * @param[in] UINT8 dwCycNum 周期号
 * @return CI_SUCCESS 1 设置成功
 *         CI_ERROR 0 设置失败
 * note Created By LQ 2024.07.14
 */
UINT8 elm_SetUCTToUKTStartCycNum(UINT16 wEnvelopid, UINT32 dwCycNum);

#endif /*ENVELOPE_MANAGE_H_*/
