/******************************************************************************
** 文件名:  EnvelopeLogicProcess.h
** 描 述:   实现包络逻辑处理（主要实现包络管理函数的声明）
*******************************************************************************/

#ifndef ENVELOPE_LOGIC_PROCESS_H_
#define ENVELOPE_LOGIC_PROCESS_H_

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

/**
 * @brief 获取指定计轴范围范围内的包络信息
 * @param[in] const UINT16 acID[] 计轴区段数组
 * @param[in] UINT8 acCnt 计轴区段数量
 * @param[out] UINT16 envelopeID[TRAIN_SUM_MAX_IN_OC] 包络ID存储区
 * @return TRAIN_SUM_MAX_IN_OC 执行错误
		   0 ~ TRAIN_SUM_MAX_IN_OC 执行成功
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_MergeEnvelope(IN const UINT16 acID[], UINT8 acCnt, INOUT UINT16 envelopeID[TRAIN_SUM_MAX_IN_OC]);

/**
 * @brief 获取包络相邻的包络
 * @param[in] UINT16 envelopeId
 * @param[out] UINT16 *preEnvelope 包络前方id
 * @param[out] UINT16 *backEnvelope 包络后方id
 * @return CI_ERROR 查询失败
           CI_SUCCESS 查询成功
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_GetNearestEnvelope(UINT16 envelopeId,OUT UINT16 *preEnvelope,OUT UINT16 *backEnvelope);

/**
 * @brief 增加UKT包络
 * @param[in] UINT16 ACIndex 计轴区段索引
 * @param[in] LOD_STRU startPoint 起点位置
 * @param[in] LOD_STRU endPoint 终点位置
 * @return CI_SUCCESS 需要操作的内存区正确，返回成功
 *         CI_ERROR   需要操作的内存区错误，返回失败
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_AddUKTEnvelope(UINT16 ACIndex, LOD_STRU startPoint, LOD_STRU endPoint);


/**
 * @brief 删除指定UKT包络
 * @param[in] const EnvelopeStruct* pEnvelope 待删除的包络
 * @return CI_SUCCESS 需要操作的内存区正确，返回成功
 *         CI_ERROR   需要操作的内存区错误，返回失败
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_DeleteUKTEnvelope(IN const EnvelopeStruct* pEnvelope);

/**
 * @brief 删除计轴上关联的包络
 * @param[in] UINT8 acBelongFlag 计轴所属OC标志
 * @param[in] UINT16 AcID 计轴ID
 * @return CI_ERROR 处理错误
           CI_SUCCESS 处理正确
 * @note 
 *   1、此函数只能接受删除非本OC范围的计轴区段，否则返回失败
 *   2、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_DeleteACRelEnvelope(UINT8 acBelongFlag,UINT16 AcID);

/**
 * @brief 计轴上添加故障包络
 * @param[in] UINT16 acID
 * @param[out]
 * @return CI_ERROR 处理失败
           CI_SUCCESS 处理成功
 * @note 
 *   1、此函数实现在占用且无包络的计轴上添加故障包络
 *   2、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_AddUKTEnvelopeInAC(UINT16 acID);

/**
 * @brief 清除UCT或者CT包络
 * @param[in] UINT8 Flag 是否添加故障 0xff：清除包络时无需添加故障包络；其他，清除包络时需添加故障包络
 * @param[in] UINT16 envelopeID 包络ID
 * @param[out]
 * @return 
 * @note 
 *   1、只有在列车不属于本OC控制时才处理，清除时不会对前后端进行操作，只清除相关内存
 *   2、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_ClearCTOrUCTEnvelope(UINT8 Flag,UINT16 envelopeID);

/**
 * @brief 删除UCT或者CT包络
 * @param[in] UINT16 envelopeID 包络ID
 * @param[out] 无
 * @return CI_ERROR 处理失败
           CI_SUCCESS 处理成功
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_DeleteCTOrUCTEnvelope(UINT16 envelopeID);

/**
 * @brief 将相邻OC发送的包络信息加入到内存中
 * @param[in] UINT8 OCid 相邻OC id
 * @param[out] 无
 * @return 无
 * @note 
 *   1、此函数只能接受删除非本OC范围的计轴区段，否则返回失败
 */
void elm_AddNextOCEnvelopetoBuff(UINT8 OCid);

/**
 * @brief 刷新相邻OC范围内的包络信息
 * @param[in] 
 * @param[out]
 * @return 
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
void elm_RefreshNextOCEnvelope(void);


/**
 * @brief 隐藏车包络跟踪管理
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
void elm_UKTEnvelopeTrack(void);

/**
 * @brief CT车包络跟踪处理
 * @note 安全前提：一个CT包络不可能跳过另一个CT包络；一个CT包络不可能越过一个UCT包络；存在UKT包络的计轴不可能存在CT包络或者UCT包络
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
void elm_CTEnvelopeTrack(void);

/**
 * @brief 静态函数：UT车包络跟踪处理
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
void elm_UCTEnvelopeTrack(void);

/**
 * @brief UCT包络恢复
 * @param[in] UINT16 trainid 列车ID
 * @param[out] 无
 * @return 无
 * @note 无
 */
void elm_UCTEnvelopeRecover(UINT16 trainid);


/**
 * @brief 列车筛选
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
void elm_TrainScreen(void);

/**
 * @brief 全线免筛处理
 * @param[in] 无
 * @param[out] 无
 * @return 无
 * @note 无
 */
void elm_WLScreenProcess(void);


/**
 * @brief 根据计轴占用空闲状态清UKT包络
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
void elm_ProcessFreeAC(void);

/**
 * @brief 维护信息打印
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
void elm_MaintenanceInfo(void);


/**
 * @brief 根据已知条件创建包络
 * @param[in] UINT8 envelopeType 包络类型
 * @param[in] UINT16 TrainID 包络ID
 * @param[in] LOD_STRU startPoint 包络起始位置
 * @param[in] LOD_STRU endPoint 包络终止位置
 * @param[in] UINT16 headTrainID 包络前端列车ID
 * @param[in] UINT16 tailTrainID 包络后端列车ID
 * @param[out] EnvelopeStruct *pEnvelope 包络
 * @return CI_SUCCESS 包络创建正确，返回成功
 *         CI_ERROR   包络创建失败，返回失败
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_CreateEnveLope(UINT8 envelopeType,UINT16 TrainID, LOD_STRU startPoint,LOD_STRU endPoint,UINT16 headTrainID,UINT16 tailTrainID, \
	INOUT EnvelopeStruct *pEnvelope);

/**
 * @brief 查询基准包络前方最近的包络
 * @param[in] const EnvelopeStruct* pEnvelop 基准包络
 * @param[in] const UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC] 待比较的包络
 * @param[in] UINT8 envelopeCnt 待比较的包络数量
 * @param[out] UINT16 *preEnvelope 包络前方id
 * @param[out] UINT16 *backEnvelope 包络后方id
 * @param[out] UINT8 *includeCnt 包含的包络数量
 * @param[out] UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC] 包含的包络ID
 * @return CI_ERROR 查询失败
           CI_SUCCESS 查询成功
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_SearchNearestEnvelope(IN const EnvelopeStruct* pEnvelop, IN const UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC], UINT8 envelopeCnt, OUT UINT16 *preEnvelope, OUT UINT16 *backEnvelope, OUT UINT8 *includeCnt, OUT UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC]);


/**
 * @brief 拷贝计轴区段上的包络信息
 * @param[in] UINT16 acID
 * @param[out] EnvelopeStruct envelopeInfo[] 计轴区段上的包络信息
 * @return 0 计轴区段上不存在包络
           非0且小于SECTION_REL_ENVELOPE_SUM_MAX 计轴区段上包络数量
		   SECTION_REL_ENVELOPE_SUM_MAX，函数执行错误
 * @note 新增
 */
UINT8 elm_CopyEnvelopeInAC(UINT16 acID,INOUT EnvelopeStruct envelopeInfo[SECTION_REL_ENVELOPE_SUM_MAX]);


/**
 * @brief 获取计轴区段属于包络的位置
 * @param[in] UINT16 ACid 待判计轴（待判计轴必须为包络范围内的计轴区段）
 * @param[in] const UINT16 newACID[SECTION_IN_ENVELOPE_SUM_MAX]   本周期占用的包络计轴序列（序列从包络尾指向包络头）
 * @param[in] UINT8 newACCnt  本周期占用的包络计轴数量 
 * @param[out] 无
 * @return UINT8_MAX 处理错误
           ELM_HEAD_AND_TAIL   属于包络头且属于包络尾
           ELM_HEAD 属于包络头
		   ELM_TAIL 属于包络尾
		   ELM_BODY 属于包络体
 * @note 
 *     1、新建，2022年4月21日
 */
UINT8 elm_GetACOfEnvelopePos(UINT16 ACid, IN const UINT16 newACID[SECTION_IN_ENVELOPE_SUM_MAX],UINT8 newACCnt);


/**
 * @brief 删除切换完成的包络信息
 * @param[in] const EnvelopeStruct* pEnvelop 包络
 * @param[in] UINT16 trainid 列车ID
 * @param[out] 无
 * @return CI_ERROR 查询失败
 *         CI_SUCCESS 查询成功
 * @note 
 */
UINT8 elm_ClearHanderOverEnvelope(IN const EnvelopeStruct* pEnvelop,UINT16 trainid);


/**
 * @brief 包络管理安全防护
 * @param[in] 无
 * @param[out] 无
 * @return  
 * @note 
 */
void elm_SafeProtectProcess(void);


/**
 * @brief 检查计轴区段是否UT占用（冗余期间不算UT占用）
 * @param[in] UINT16 ACID 计轴ID
 * @param[out] 无
 * @return CI_ERROR UT占用
           CI_SUCCESS 非UT占用
 * @note 
 */
UINT8 elm_CheckACIsUTOcc(UINT16 ACID);


/**
 * @brief 处理故障包络的前后包络
 * @param[in] UINT16 envelopeID 包络ID
 * @param[out] 无
 * @return CI_SUCCESS 处理成功
 *         CI_ERROR 处理失败
 * @note 无
 */
UINT8 elm_ProcessFaultElmNear(UINT16 envelopeID);


/**
 * @brief 判断包络A的运行方向是否与包络B的运行方向相同
 * @param[in] const EnvelopeStruct* pEnvelopA  包络A
 * @param[in] const EnvelopeStruct* pEnvelopB  包络B
 * @param[out] 无
 * @return ELM_DIR_SAME 方向相同
 *         ELM_DIR_CONVERT 方向相反
           其他，非法
 * @note 无，目前该函数未考虑方向变化点
 */
UINT8 elm_DirIsSameELMWithELM(const EnvelopeStruct* pEnvelopA, const EnvelopeStruct* pEnvelopB);


/**
 * @brief 更新计轴上的CT包络进入信息
 * @param[in] IN const EnvelopeStruct* pEnvelop 包络信息    
 * @param[in] const UINT16 newACID[SECTION_IN_ENVELOPE_SUM_MAX]   本周期占用的包络计轴序列（序列从包络尾指向包络头）
 * @param[in] UINT8 newACCnt  本周期占用的包络计轴数量      
 * @param[in] UINT8 cutFlag  截取标志位  
 * @return CI_SUCCESS 处理正确，返回成功
 *         CI_ERROR   处理错误，返回失败
 * @note 
 *   1、新建，2022年4月21日,只能给CT包络使用
 */
UINT8 elm_RefreshACseqInfoForCT(IN const EnvelopeStruct* pEnvelop,IN const UINT16 newACID[SECTION_IN_ENVELOPE_SUM_MAX],UINT8 newACCnt,UINT8 cutFlag);


/**
 * @brief 更新计轴上的UCT包络进入信息
 * @param[in] IN const EnvelopeStruct* pEnvelop 包络信息     
 * @return CI_SUCCESS 处理正确，返回成功
 *         CI_ERROR   处理错误，返回失败
 * @note 无
 */
UINT8 elm_RefreshACseqInfoForUCT(IN const EnvelopeStruct* pEnvelop);

/**
 * @brief UCT包络出清计轴处理 
 * @param[in] UINT8 flag 出清方式
 * @param[in] const EnvelopeStruct* pEnvelope 包络信息
 * @param[in] UINT16 acID 计轴区段Id
 * @param[out]
 * @return CI_SUCCESS 处理正确，返回成功
 *         CI_ERROR   处理错误，返回失败
 * @note 无na
 */
UINT8 elm_UCTEnvelopeLeaveAC(UINT8 flag,IN const EnvelopeStruct* pEnvelope,UINT16 acID);

/**
 * @brief 设置UCT包络端点为计轴的端点
 * @param[in] UINT8 headorTail 包络头还是包络尾
 * @param[in] UINT16 acId 计轴ID
 * @param[out] EnvelopeStruct* ptemp 包络地址指针
 * @return CI_ERROR 处理错误
 *         CI_SUCCESS 处理正确
 * @note 无
 */
UINT8 elm_SetUCTEnvelopeDot(UINT8 headorTail,UINT16 acId,IN const EnvelopeStruct* ptemp);

/**
 * @brief 查询包络内包含的包络离指定端点最近的包络
 * @param[in] UINT8 flag，包络头还是包络尾
 * @param[in] const EnvelopeStruct* pBase 基准包络
 * @param[in] UINT8 includeCnt 包络内包含的包络数量
 * @param[in] UINT16 includeELM[TRAIN_SUM_MAX_IN_OC] 包络内包含的包络id
 * @param[out] UINT16 *pEnvelopeid,找到的包络ID
 * @return CI_ERROR 查询失败
           CI_SUCCESS，查询正确
 * @note 无
 */
 UINT8 elm_SearchNearstEnvInInclude(UINT8 flag,IN const EnvelopeStruct* pBase,UINT8 includeCnt,UINT16 includeELM[TRAIN_SUM_MAX_IN_OC],OUT UINT16 *pEnvelopeid);

 /**
 * @brief 刷新所有的列车 
 * @param[in] 无
 * @param[out] 无
 * @return 无
 * @note 无
 */
 void elm_RefreshTrainConstrolStatus(void);

  /**
  * @brief 判断列车是否为下线车
  * @param[in] UINT16 trainID,列车ID
  * @param[in] UINT8 headNeedScreen, 需要前筛标志
  * @param[in] UINT8 tailNeedScreen, 需要尾筛标志
  * @param[out] 无
  * @return 无
  * @note 当最大安全前和最小安全后所属OC都不属于全线免筛区域，则认为是下线车
  */
 void elm_JudgeTrainOffline(UINT16 trainID, UINT8 headNeedScreen,UINT8 tailNeedScreen);

 /**
 * @brief 删除UCT或者CT包络不额外处理前后车前/后端
 * @param[in] UINT16 envelopeID 包络ID
 * @param[out] 无
 * @return CI_ERROR 处理失败
 CI_SUCCESS 处理成功
 * @note
 */
 UINT8 elm_DeleteCTOrUCTUndoSuspic(UINT16 envelopeID);

 /**
 * @brief 获取包络相邻的本列车的其它包络
 * @param[in] UINT16 envelopeId
 * @param[out] UINT16 *preEnvelope 包络前方id
 * @param[out] UINT16 *backEnvelope 包络后方id
 * @return CI_ERROR 查询失败
		   CI_SUCCESS 查询成功
 * @note
 *  by cgh 20240514 目前只用于RRM
 */
 UINT8 elm_GetNearEnvelopRelSameTra(UINT16 envelopeId, OUT UINT16* preEnvelope, OUT UINT16* backEnvelope);

 /**
 * @brief 查询基准包络前方最近的本车包络
 * @param[in] const EnvelopeStruct* pEnvelop 基准包络
 * @param[in] const UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC] 待比较的包络
 * @param[in] UINT8 envelopeCnt 待比较的包络数量
 * @param[out] UINT16 *preEnvelope 包络前方id
 * @param[out] UINT16 *backEnvelope 包络后方id
 * @param[out] UINT8 *includeCnt 包含的包络数量
 * @param[out] UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC] 包含的包络ID
 * @return CI_ERROR 查询失败
		   CI_SUCCESS 查询成功
		   0xffu 包络存在重合包络

 * @note
 *  by cgh 20240514 目前只用于RRM
 */
 UINT8 elm_FindNearSameTrainEnvelop(IN const EnvelopeStruct* pEnvelop, IN const UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC], UINT8 envelopeCnt, OUT UINT16* preEnvelope, OUT UINT16* backEnvelope, OUT UINT8* includeCnt, OUT UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC]);

 /**
 * @brief 处理无C轨可追踪B轨UT
 * @param[in] UINT16 envelopeID 列车包络
 * @param[in] UINT16 wTrainId 列车ID
 * @return 无
 * @note by cgh 20240815
 */
 void elm_DealNoCGFollowUt(UINT16 wEnvelopeID, UINT16 wTrainId);

 /**
* @brief 清除虚拟筛选通过标志
* @param[in] UINT16 wTrainId 列车ID
* @return 无
* @note by cgh 20240815
*/
 void elm_ClearVirScreenPassFlag(UINT16 wTrainId);

 /**
* @brief 虚拟筛选通过标志监督
* @param[in] UINT16 wTrainId 列车ID
* @return 无
* @note by cgh 20240822
*/
 void elm_VirScreenPassMonitor(void);

 /**
 * @brief 筛选删除UCT在筛选计轴部分后，UCT处理
 * @param[in] const EnvelopeStruct* ptemp 包络信息指针
 * @param[out] 无
 * @return CI_ERROR 0 条件不满足
 *         CI_SUCCESS 1 条件满足
 * @note Created By LQ 2024.07.14
 */
UINT8 elm_ScreenUctCfpFreeProc(const EnvelopeStruct* ptemp);

/**
* 功能描述： CT包络飞车检查
* 参数说明：无
* 返回值  ： CI_ERROR 存在飞车 CI_SUCCESS  不存在
* BY fan 20241017 (elm_FlyingProtect拆开降复杂度)
*/
UINT8 elm_FlyingProtect_CT(void);

/**
* 功能描述： UCT包络飞车检查
* 参数说明：无
* 返回值  ：无
* edit cgh 20241028
*/
void elm_FlyingProtect_UCT(void);

/**
* 功能描述： 删除UCT好车通过标志
* 参数说明：UINT16 envelopeId 包络id
* 返回值  ： 无
* by cgh 20241028
*/
void elm_DeleteUctPassFlag(UINT16 envelopeId);

/**
* @brief 处理AG虚拟筛选标志
* @param[in] UINT16 envelopeID 列车包络
* @param[in] UINT16 wTrainId 列车ID
* @return 无
* @note by cgh 20250805
*/
void elm_DealAgVirScreenFlag(UINT16 wEnvelopeID, UINT16 wTrainId);

/**
* @brief 处理BG虚拟筛选标志
* @param[in] UINT16 envelopeID 列车包络
* @param[in] UINT16 wTrainId 列车ID
* @return 无
* @note by cgh 20250805
*/
void elm_DealBgVirScreenFlag(UINT16 wEnvelopeID, UINT16 wTrainId);

#endif