/******************************************************************************
** 文件名:  ELMDataPrepare.h
** 描 述:   列车包络管理模块运行时需要的外部数据准备头文件定义，为了实现模块独立而新增
*******************************************************************************/

#ifndef ELM_DATA_PREPARE_H_
#define ELM_DATA_PREPARE_H_
#include "CommonConfig.h"

#if (kPLATFORM==kWINDOWS)
#include <windows.h>
#include <stdio.h>
#endif

  
#include "EnvelopeDefine.h"
#include "CutoffPointDataManage.h"
#include "AxisAssertManageAPI.h"

#define ELM_AC_OCC (0x55u)  /*计轴区段占用*/
#define ELM_AC_FREE (0xaau)  /*计轴区段空闲*/

#define LOC_BEFORE (0x01u)  /*位置在前方*/
#define LOC_SAME (0x02u)    /*位置重合*/
#define LOC_AFTER (0x03u)    /*位置在后方*/

#define ADJUST_UCT (0x02U)    /*处理UCT包络*/

#define ELM_LOG_FATAL (0u)   /** 维护日志--维护级别 */
#define ELM_LOG_ERROR (1u)  /*维护日志--错误级别*/
#define ELM_LOG_WARING (2u)  /*维护日志--警告级别*/
#define ELM_LOG_DEBUG (3u)   /*维护日志--调试级别*/
#define ELM_LOG_LEVEL ELM_LOG_DEBUG   /*维护日志--当前日志级别*/
#define ELM_PRINT_LEN (1280u) /* 维护日志打印打印长度 1024+256 */

#define ELM_BELONG_OWNER (0x55u)   /* 属于本OC管辖 */
#define ELM_BELONG_OTHER (0xaau)   /* 不属于本OC */

#define ELM_COM_STATUS_OK (0x55u)     /* 通信状态正确 */
#define ELM_COM_STATUS_ERROR (0xaau)  /* 通信状态错误 */ 

#define ELM_NO_CUT (0x00u)       /* 包络未进行截取 */
#define ELM_HEAD_CUT (0x55u)     /* 包络头进行截取 */
#define ELM_TAIL_CUT (0xaau)     /* 包络尾进行截取 */

#define  ELM_TRAIN_IN_WLS_AREA (0x55u)     /** 列车位置在免筛区域 */
#define  ELM_TRAIN_OUT_WLS_AREA (0xaau)     /** 列车位置不在免筛区域 */

/** 日志打印函数 */
#define ELM_LOG_LOC(level,fmt,...)  elm_PrintDebugInfo(level,fmt" line:%d fun:%s.\n",##__VA_ARGS__,__LINE__,__FUNCTION__);

#define ELM_LOG(level,fmt,...)  elm_PrintDebugInfo(level,fmt,##__VA_ARGS__);

#if (kPLATFORM==kWINDOWS) 
#define ELM_LOG_TIME(level,fmt,...)  { \
	SYSTEMTIME sys; \
	GetLocalTime(&sys); \
	elm_PrintDebugInfo(level,fmt" time:%02d:%02d:%02d.%03d.\n",##__VA_ARGS__,sys.wHour,sys.wMinute, sys.wSecond,sys.wMilliseconds); \
}
#else
#define ELM_LOG_TIME(level,fmt,...)  elm_PrintDebugInfo(level,fmt" time:%08d.\n",##__VA_ARGS__,TimeStamp); 
#endif

#if (kPLATFORM!=kWINDOWS)
extern unsigned long TimeStamp;
#endif

extern UINT16 OutEnvelopeStrLen;  /*需要打印的包络数据长度*/
extern UINT8 OutEnvelopeStr[MAX_ENVELOPE_LOG_NUM];  /*需要打印的包络数据*/

/** elm模块使用的安全位置接口体*/
typedef struct
{
	LOD_STRU startPos;         /*始端位置*/
	LOD_STRU endPos;           /*终端位置*/
}ELM_TrainSafeLocStruct;

/** elm模块使用的计轴区段位置接口体*/
typedef struct
{
	UINT8 dir;				/** 始端指向终端的方向*/
	LOD_STRU startPos;         /*始端位置*/
	LOD_STRU endPos;           /*终端位置*/
}ELM_AxisLocStruct;


/**
 * @brief 打印包络信息
 * @param[in] const EnvelopeStruct* PEnvelpe 包络指针
 * @return 无
 * @note 调用日志打印库函数进行日志打印
 */
void elm_PrintfEnvelope(const EnvelopeStruct* PEnvelpe);

/**
 * @brief 打印Debug信息
 * @param[in] UINT8 level 日志级别
 * @param[in] const char *fmt 打印信息
 * @return 无
 * @note 通过调用外部接口，实现本模块的打印
 */
void elm_PrintDebugInfo(UINT8 level, const char *fmt, ...);

/**
 * @brief 通过列车ID准备列车的安全包络信息
 * @param[in] UINT16 trainID 列车ID
 * @param[out] INOUT TrainSafeLocStruct* pTrainSafeLoc 列车安全包络
 * @return CI_SUCCESS 需要操作的内存区正确，返回成功
 *         CI_ERROR   需要操作的内存区错误，返回失败
 * @note 
 */
UINT8 elm_PrepareTrainSafeLoc(UINT16 trainID,INOUT ELM_TrainSafeLocStruct* pTrainSafeLoc);

/**
 * @brief 获取本OC范围有共管区内计轴区段的数组索引
 * @param[out] OUT UINT16** pACIdBuff 计轴区段ID数缓存
 * @return 0 查询错误
           1~AXIS_SECTION_SUM_MAX 查询正确
 * @note 由于OC支持计轴区段ID和索引的映射关系，故直接获取即可
 */
UINT16 elm_PrepareACBuffIndexs(OUT const UINT16** pACIdBuff);



/**
 * @brief 通过计轴区段的数组索引获取计轴区段ID
 * @param[in] UINT16 ACBuffIndex 计轴区段缓存索引
 * @return 计轴区段ID
 * @note 无
 */
UINT16 elm_PrepareACID(UINT16 ACBuffIndex);


/**
 * @brief 通过计轴区段ID获取计轴区段的数组索引
 * @param[in] UINT16 ACId 计轴区段ID
 * @return 计轴区段缓存索引
 * @note 无
 */
UINT16 elm_PrepareACIndex(UINT16 ACId);


/**
 * @brief 通过计轴ID获取计轴状态
 * @param[in] UINT16 ACID 计轴区段ID
 * @return ELM_AC_OCC 计轴占用
		   ELM_AC_FREE 计轴空闲
 * @note 
 */
UINT8 elm_PrepareACStatus(UINT16 ACID);

/**
* @brief 通过计轴ID查询当属于岔区不连通时，所处物理区段占用情况
* @param[in] UINT16 ACID 计轴区段ID
* @return SECTION_OCCUPY_YES 物理区段占用
		SECTION_OCCUPY_NO 物理区段空闲
*/
UINT8 elm_PrepareACofSwichPhyStatus(UINT16 ACID);

/**
 * @brief 通过计轴区段ID查找计轴区段位置
 * @param[in] UINT16 ACID 计轴区段ID
 * @param[in] UINT8 chDir 起点指向终点的方向
 * @param[out] ELM_AxisLocStruct* pACLoc 计轴区段位置
 * @return CI_SUCCESS 查询正确，返回成功
 *         CI_ERROR   查询错误，返回失败
 * @note 
 */
UINT8 elm_PrepareACLoc(UINT16 ACID, UINT8 chDir, ELM_AxisLocStruct* pACLoc);


/**
 * @brief 通过计轴区段ID和查询方向查询计轴包含的link
 * @param[in] UINT16 ACID 计轴ID
 * @param[out] UINT16 linkID[] 计轴包含的link
 * @return  0 非法
            非0 包含的link数量
 * @note link返回时按照查询方向顺序返回
 */
UINT8 elm_PrepareACrelLink(UINT16 ACID,UINT8 dir, INOUT UINT16 linkID[]);


/**
 * @brief 根据两点查询两点之间的link区段
 * @param[in] LOD_STRU pointA 位置点A
 * @param[in] LOD_STRU pointB 位置点B
 * @param[out] UINT16 linkID[] 两点之间包含的link
 * @return 两点之间的link数量
 * @note pointA位置点的方向为指向pointB的方向
 */
UINT16 elm_PrepareLinkBtwPoints(LOD_STRU pointA,LOD_STRU pointB,INOUT UINT16 linkID[]);


/**
 * @brief 根据两点查询两点之间的计轴区段
 * @param[in] LOD_STRU pointA 位置点A
 * @param[in] LOD_STRU pointB 位置点B
 * @param[out] UINT16 ACID[] 两点之间包含的计轴区段
 * @return 两点之间的计轴数量
 * @note pointA位置点的方向为指向pointB的方向
 */
UINT8 elm_PrepareACBtwPoints(LOD_STRU pointA,LOD_STRU pointB,INOUT UINT16 ACID[SECTION_IN_ENVELOPE_SUM_MAX]);


/**
 * @brief 获取当前OC所有的通信车列车ID
 * @param[out] UINT16 trainID[TRAIN_SUM_MAX_IN_OC] 列车ID缓存
 * @return OC范围内通信列车ID
 * @note 无
 */
UINT8 elm_PrepareCommTrainID(INOUT UINT16 trainID[TRAIN_SUM_MAX_IN_OC]);


/**
 * @brief 获取列车的通信状态
 * @param[in] UINT16 trainid
 * @param[out] 无
 * @return ELM_COM_STATUS_OK 通信正常
 *         ELM_COM_STATUS_ERROR 通信异常
 * @note 无
 */
UINT8 elm_PrepareTrainCommStatus(IN UINT16 trainID);

/**
 * @brief 获取通信正常的列车位置是否有效
 * @param[in] UINT16 trainid
 * @param[out] 无
 * @return CI_SUCCESS 位置有效
 *         CI_ERROR   位置无效
 * @note 无
 */
UINT8 elm_PrepareTrainPosValid(IN UINT16 trainID);


/**
 * @brief 获取两点的位置关系
 * @param[in] LOD_STRU pointA 位置A
 * @param[in] UINT8 dirAtoB 位置A指向位置B
 * @param[in] LOD_STRU pointB 位置B
 * @return LOC_BEFORE 位置B在位置A前
           LOC_SAME 位置A与位置B重合
           LOC_AFTER 位置A在位置B后
		   其他 非法
 * @note 
 */
UINT8 elm_PrepareRelationBtwPoint(LOD_STRU pointA,UINT8 dirAtoB, LOD_STRU pointB);


/**
 * @brief 查询计轴前/后方计轴
 * @param[in] UINT16 ACID 基准计轴ID
 * @param[in] UINT8 dir 查询方向
 * @param[out] UINT16 arACID[AC_MAXCNT_IN_SWITCH] 相邻计轴ID
 * param[out] UINT8* DirectionPointFlag  是否有方向变化点 DIRECTIONPOINT_FLAG_VALID
 * @return UINT8_MAX 查询失败
		   0~AC_MAXCNT_IN_SWITCH  查询成功
 */
UINT8 elm_PrepareAdjacentAC(UINT16 ACID, UINT8 dir, INOUT UINT16 arACID[AC_MAXCNT_IN_SWITCH], UINT8* DirectionPointFlag);


/**
 * @brief 合并UINT16数组
 * @param[in] UINT16 dstBuffSize 目的缓冲区大小
 * @param[in] UINT16 startIndex 目的缓冲区拷贝起始地址
 * @param[in] const UINT16 srcArray[] 源缓冲区地址
 * @param[in] UINT16 srcBuffSize 源缓冲区大小
 * @param[in] UINT16 mergeSize 合并大小
 * @param[out] UINT16 dstArray[] 目的缓冲区
 * @return 目的合并后的索引地址
 * @note 如果合并失败，返回目的缓冲区大小
 */
UINT16 elm_PrepareMergeUINT16Array(INOUT UINT16 dstArray[], UINT16 dstBuffSize, UINT16 startIndex, IN const UINT16 srcArray[], UINT16 srcBuffSize,UINT16 mergeSize);


/**
 * @brief 比较两个包络的前后关系
 * @param[in] const EnvelopeStruct pEnvelopeA 包络A
 * @param[in] LOD_STRU* strPointA 基准包络起点
 * @param[in] const EnvelopeStruct* pEnvelopeB 包络B
 * @return 0x01 包络A在包络B前
		   0x02 包络B在包络A前
		   0x03 包络A包含与包络B，包括如下关系：(()  )、(    ()) 和（  ()   ）
		   0x04 包络B包含与包络A，包括如下关系：(()  )、(    ()) 和（  ()   ）
		   0x00 无法比较位置关系
 * @note 无
 */
UINT8 elm_PrepareRelationBtwEnvelope(IN const EnvelopeStruct* pEnvelopeA, const LOD_STRU strPointBase, IN const EnvelopeStruct* pEnvelopeB);


/**
 * @brief 判断数值是否存在UINT16数值中 
 * @param[in] UINT16 targetValue 待查询的值
 * @param[in] const UINT16 arValue[] 冲突范围
 * @param[in] UINT16 buffsize冲突范围大小
 * @return CI_SUCCESS 指定值在冲突范围内
 *         CI_ERROR   指定值不在冲突范围内
 * @note 无
 */
UINT8 elm_PrepareInUINT16Array(UINT16 targetValue,const UINT16 arValue[],UINT16 buffsize);


/**
 * @brief 通过两点获取两点之间的距离
 * @param[in] LOD_STRU pointA 位置A
 * @param[in] LOD_STRU pointB 位置B
 * @return 两点之间的距离（cm）
 * @note  pointA为起点 pointB为终点
 */
 UINT32 elm_PrepareDistanceBtwPoints(LOD_STRU pointA, LOD_STRU pointB);

 /**
  * @brief 通过列车ID获取列车车长
  * @param[in] 
  * @param[out]
  * @return 列车车长（cm）
  * @note 1、如果查询成功，返回列车车长，否则返回线路上最短车长
  */
 UINT32 elm_PrepareTrainLength(UINT16 trainid);


 /** 
  * @brief 获取列车运行方向
  * @param[in] UINT16 trainid 列车ID
  * @param[out] 无
  * @return ELM_DIR_SAME 处理成功
  *         ELM_DIR_CONVERT 处理失败
            其他，非法
  * @note 
  */
  UINT8 elm_PrepareTrainDir(UINT16 trainid);


 /**
  * @brief 查询列车最小安全前前方计轴
  * @param[in] UINT16 trainid 列车ID
  * @param[out] UINT16 acID[AC_MAXCNT_IN_SWITCH] 计轴数量
  * @return 查找成功的计轴数量
  * @note 
  */
 UINT8 elm_PrepareNextAcMinSafeHeadLoc(UINT16 trainid, OUT UINT16 acID[AC_MAXCNT_IN_SWITCH]);

  /**
  * @brief 获取列车最大安全前位置
  * @param[in] UINT16 trainid 列车ID
  * @param[out] LOD_STRU *pLoc 列车位置
  * @return CI_SUCCESS 查询成功
  *         CI_ERROR   查询失败
  * @note 无
  */
 UINT8 elm_PrepareMaxSafeHeadLoc(UINT16 trainid, OUT LOD_STRU *pLoc);

 /**
  * @brief 获取列车最小安全前位置
  * @param[in] UINT16 trainid 列车ID
  * @param[out] LOD_STRU *pLoc 列车位置
  * @return CI_SUCCESS 查询成功
  *         CI_ERROR   查询失败
  * @note 无
  */
 UINT8 elm_PrepareMinSafeHeadLoc(UINT16 trainid, OUT LOD_STRU *pLoc);

  /**
  * @brief 获取列车最大安全前所属计轴
  * @param[in] UINT16 trainid 列车ID
  * @return 计轴ID
  * @note 无
  */
 UINT16 elm_PrepareACOfMaxSafeHeadLoc(UINT16 trainid);

 /**
  * @brief 获取列车最小安全前所属计轴
  * @param[in] UINT16 trainid 列车ID
  * @return 计轴ID
  * @note 无
  */
 UINT16 elm_PrepareACOfMinSafeHeadLoc(UINT16 trainid);


 /**
  * @brief 查询列车最大安全后后方计轴
  * @param[in] UINT16 trainid 列车ID
  * @param[out] UINT16 acID[AC_MAXCNT_IN_SWITCH] 计轴数量
  * @return 查找成功的计轴数量
  * @note 
  */
 UINT8 elm_PrepareNextAcMaxSafeTailLoc(UINT16 trainid, OUT UINT16 acID[AC_MAXCNT_IN_SWITCH]);


 /**
  * @brief 获取列车最大安全后位置
  * @param[in] UINT16 trainid 列车ID
  * @param[out] LOD_STRU *pLoc 列车位置
  * @return CI_SUCCESS 查询成功
  *         CI_ERROR   查询失败
  * @note 无
  */
 UINT8 elm_PrepareMaxSafeTailLoc(UINT16 trainid, OUT LOD_STRU *pLoc);

  /**
  * @brief 获取列车最小安全后位置
  * @param[in] UINT16 trainid 列车ID
  * @param[out] LOD_STRU *pLoc 列车位置
  * @return CI_SUCCESS 查询成功
  *         CI_ERROR   查询失败
  * @note 无
  */
 UINT8 elm_PrepareMinSafeTailLoc(UINT16 trainid, OUT LOD_STRU *pLoc);

 /**
  * @brief 获取列车最大安全后所属计轴
  * @param[in] UINT16 trainid 列车ID
  * @return 计轴ID
  * @note 无
  */
 UINT16 elm_PrepareACOfMaxSafeTailLoc(UINT16 trainid);

  /**
  * @brief 获取列车最小安全后所属计轴
  * @param[in] UINT16 trainid 列车ID
  * @return 计轴ID
  * @note 无
  */
 UINT16 elm_PrepareACOfMinSafeTailLoc(UINT16 trainid);


  /**
  * @brief 获取列车的休眠状态 
  * @param[in] UINT16 trainid 列车ID
  * @param[out] 无
  * @return  TRAIN_SLEEP_YES 处于休眠状态
             TRAIN_SLEEP_NO 未处于休眠状态
			 其他非法
  * @note  
  */
 UINT8 elm_PrepareTrainSleepStatus(UINT16 trainid);

 /**
  * @brief 获取计轴区段是否属于本OC 
  * @param[in] UINT16 acID 计轴区段ID
  * @param[out] UINT8 *pOCId 所属OCid
  * @return ELM_BELONG_OTHER 属于相邻OC
            ELM_BELONG_OWNER 属于本OC
			其他，非法
  * @note 无
  */
 UINT8 elm_PrepareACIsSelf(UINT16 acID,UINT8 *pOCId);
 

/**
  * @brief 获取包络是否完全属于本OC
  * @param[in] const EnvelopeStruct* Ptemp 
  * @param[out] 无
  * @return ELM_BELONG_OTHER 属于相邻OC
            ELM_BELONG_OWNER 属于本OC
			其他，非法
  * @note 无
  */
 UINT8 elm_PrepareEnvelopeIsSelf(IN const EnvelopeStruct* ptemp);


/**
  * @brief 获取[A,B]范围内完全属于本OC的范围[A',B']
  * @param[in] 无
  * @param[out] LOD_STRU *pointA 截取到分界点
  * @param[out] LOD_STRU *pointB 截取到分界点
  * @param[out] UINT8* cutFlag 截取标志
  * @return ELM_BELONG_OTHER 属于相邻OC
            ELM_BELONG_OWNER 属于本OC
			其他，非法
  * @note 无
  */
 UINT8 elm_PrepareCutZoneInSelf(INOUT LOD_STRU *pointA,INOUT LOD_STRU *pointB, INOUT UINT8* cutFlag);


 /**
  * @brief 获取本OC通信的OCid
  * @param[in] UINT8 **pOCIDbuff OCid缓存
  * @return 本OC通信数量
  * @note 无
  */
 UINT8 elm_PrepareComOCID(IN const UINT8 **pOCIDbuff);


 /**
  * @brief 获取OC的通信状态
  * @param[in] UINT8 OCID
  * @return ELM_COM_STATUS_ERROR 通信状态错误
            ELM_COM_STATUS_OK 通信状态正确
  * @note 
  */
 UINT8 elm_PrepareOCCommStatus(UINT8 OCID);


 /**
  * @brief 获取位置点所属OC
  * @param[in] const LOD_STRU *pointA 点A的位置
  * @param[out] UINT8 *pOCId 所属OC
  * @return ELM_BELONG_OTHER 属于相邻OC
            ELM_BELONG_OWNER 属于本OC
            其他，非法
  * @note 
  */
  UINT8 elm_PreparePointIsSelf(IN const LOD_STRU *pointA,UINT8 *pOCId);

  /**
   * @brief 获取相邻OC发送的包络信息
   * @param[in] UINT8 OCid OCid
   * @param[out] CfpEnvelopeStruct *pInfEnvelope 接口包络信息
   * @return 
   * @note 
   */
  UINT8 elm_PrepareNextOcInfEnvelope(UINT8 OCid,CfpEnvelopeStruct *pInfEnvelope);

  /**
 * @brief 获取计轴对应的诊断信息地址
 * @param[in] 
 * @param[out]
 * @return 
 * @note 
 */
const AxisAsserStruct* elm_PrepareAxisAssertInfoPtr(UINT16 ACID);

/**
 * @brief 获取安全位置的道岔位置是否不符合拓扑关系且占用标志
 * @param[in] 列车ID
 * @param[out]
 * @return CI_SUCCESS 符合拓扑关系或不占用
 *         CI_ERROR   不符合拓扑关系且占用
 * @note 
 */
UINT8 elm_PrepareTrainSafeHeadFlag(UINT16 trainId);



/**
 * @brief 获取计轴关联的物理区段ID
 * @param[in] UINT16 ACID 计轴区段Id
 * @param[out] 无
 * @return 0 查询失败
           >0 查询成功
 * @note 
 */
UINT16 elm_PrepareACRelPhyId(UINT16 ACID);


/**
 * @brief 获取计轴故障诊断状态
 * @param[in] 计轴ID
 * @param[out] 无
 * @return AAM_API_AC_ARB 计轴ARB
           AAM_API_AC_REDUNARB 计轴ARB冗余
		   AAM_API_AC_UT 计轴UT
		   AAM_API_AC_REDUNUT 计轴UT冗余
 * @note 
 */
UINT8 elm_PrepareACAssertStatus(UINT16 ACID);


/**
 * @brief 获取计轴故障诊断状态
 * @param[in] UINT16 ACID 计轴ID
 * @param[out] 无
 * @return AAM_UT_PASS 坏车通过
           AAM_CT_PASS 好车通过
 * @note 
 */
UINT8 elm_PrepareACPassTrainFlag(UINT16 ACID);


 /**
 * @brief 判断计轴是否为岔区
 * @param[in] UINT16 ACID 计轴ID
 * @param[out]
 * @return CI_SUCCESS 为岔区
 *         CI_ERROR   不为岔区
 * @note 
 */
UINT8 elm_PrepareACIsSwitchZone(UINT16 ACID);

/**
 * @brief 判断计轴所属岔区是否符合拓扑关系 
 * @param[in] UINT16 ACID 计轴ID
 * @param[out] 无
 * @return CI_SUCCESS 计轴所属岔区符合拓扑关系
 *         CI_ERROR   计轴所属岔区不符合拓扑关系
 * @note 注，如果传入计轴不属于岔区，则返回符合拓扑关系
 */
UINT8 elm_PrepareCheckACofSwichPos(UINT16 ACID);

/**
 * @brief 清除岔区的好车通过标志位
 * @param[in] UINT16 ACID 计轴ID
 * @param[out] 无
 * @return 无
 * @note 无
 */
void elm_PrepareClearSwPassTrainFlag(UINT16 ACID);


/**
 * @brief 获取计轴所属物理区段的占用状态
 * @param[in] UINT16 ACID 计轴ID
 * @param[out] 无
 * @return SECTION_OCCUPY_YES 物理区段占用
		   SECTION_OCCUPY_NO 物理区段空闲
 * @note 
 */
UINT8 elm_PrepareACRelPhyStatus(UINT16 ACID);


/**
 * @brief 获取飞车宕机冗余宕机时间
 * @param[in] 无
 * @param[out] 无
 * @return 冗余时间
 * @note 
 */
UINT8 elm_PrepareCTFlyingRedunTime(void);

/**
* @brief 对外接口：获取计轴关联的物理区段是否存在好车通过计轴区段
* @param[in] UINT16 acID
* @param[out] 无
* @return AAM_CT_PASS 物理区段好车通过
AAM_UT_PASS 物理区段坏车通过
*/
UINT8 elm_PreparACRelPhyPasTrainFlag(UINT16 acID);

/**
* @brief 根据两点与道岔状态查询两点之间的计轴区段
* @param[in] LOD_STRU pointA 位置点A
* @param[in] LOD_STRU pointB 位置点B
* @param[out] UINT16 ACID[] 两点之间包含的计轴区段
* @return 两点之间的计轴数量
* @note pointA位置点的方向为指向pointB的方向
* creat by lxc 2022/6/17
*/
UINT8 elm_PrepACBtwPointsBySwitchSta(LOD_STRU pointA, LOD_STRU pointB, INOUT UINT16 ACID[MAX_AC_IN_TRAIN]);

/**
* @brief 判断UINT16数组是否存在UINT16数值中
* @param[in] const UINT16 szSrcArray[] 源数数组
* @param[in] const UINT16 wSrcArrayLen 长度
* @param[in] const UINT16 szDstArray[] 待判断的数组
* @param[in] const UINT16 wDstArrayLen 长度
* @return CI_SUCCESS 指定值在冲突范围内
*         CI_ERROR   指定值不在冲突范围内
* @note 无
*/
UINT8 elm_PrepareUINT16ArrayInArray(const UINT16 szSrcArray[], const UINT16 wSrcArrayLen, const UINT16 szDstArray[], const UINT16 wDstArrayLen);


/**
* @brief 获取UCT功能开关
* @param[in] 无
* @param[out] 无
* @return CI_SUCCESS 功能打开
*         CI_ERROR 功能关闭
* @note 无
*/
UINT8 elm_PrepareUCTSwitch(void);

/**
 * @brief 获取本控区分界点计轴区段
 * @param[out] UINT16 szAcId[CUTOFF_POINT_SUM_MAX]
 * @return 0~CUTOFF_POINT_SUM_MAX-1 分界点计轴区段数量
           CUTOFF_POINT_SUM_MAX 失败
 * @note 无
 */
UINT8 elm_PrepareCfpAc(UINT16 szAcId[CUTOFF_POINT_SUM_MAX]);


/**
* @brief 获取计轴区段相邻控区的相邻计轴区段,并返回相邻控区驶向本控区的方向
* @param[in] const UINT16 wBaseAc 基准计轴区段
* @param[out] UINT8 * pDir 进入到本方区域的方向
* @param[out] pFindAc[AC_MAXCNT_IN_SWITCH] 相邻计轴区段
*             pDirChangePointFlag 方向变化点标志
* @return UINT8_MAX 查询失败
		  0~AC_MAXCNT_IN_SWITCH  查询成功
* @note 无
*/
UINT8 elm_PrepareCfpOtherTiocAc(const UINT16 wBaseAc, UINT8* pDir, UINT16 pFindAc[AC_MAXCNT_IN_SWITCH], UINT8* pDirChangePointFlag);


 /**
  * @brief 获取列车位置位置所在区域是否具备免筛属性
  * @param[in] UINT16 trainID 列车ID
  * @param[out] 无
  * @return ELM_TRAIN_IN_WLS_AREA 列车在免筛区域；ELM_TRAIN_OUT_WLS_AREA 列车不在免筛区域
  * @note 无
  */
 UINT8 elm_PrePareTrainLOCAreaType(UINT16 trainID);

 /**
 * @brief 获取列车包络是否可以转为UCT包络
 * @param[in] UINT16 trainID 列车ID
 * @param[out] 无
 * @return 0x55:列车包络不可转为UCT包络；0xaa:列车包络可转为UCT包络
 * @note 无
 */
 UINT8 elm_PrePareTrainCanUct(UINT16 trainID);

 /**
  * @brief 获取列车激活端
  * @param[in] UINT16 trainID 列车ID
  * @param[out] 无
  * @return UINT8 激活端
  * @note 无
  */
 UINT8 elm_PrepareTrainACT(UINT16 trainID);

 /**
 * @brief 判断两点是否同向
 * @param[in] LOD_STRU strPointA
 * @param[in] LOD_STRU strPointB
 * @return CI_ERROR:比较失败；FLAG_SET:同向；FLAG_UNSET:不同向
 * @note 无
 */
 UINT8 elm_PrepareTwoPointsSameDir(const LOD_STRU strPointA, const LOD_STRU strPointB);

 /**
 * @brief 获取列车最小安全前方向
 * @param[in] UINT16 wTrainId 列车编号
 * @return 最小安全前方向
 * @note 无
 */
 UINT8 elm_PrepareTrainMinHeadDir(const UINT16 wTrainId);

 /**
 * @brief 获取列车最大安全后方向
 * @param[in] UINT16 wTrainId 列车编号
 * @return 最大安全后方向
 * @note 无
 */
 UINT8 elm_PrepareTrainMaxTailDir(const UINT16 wTrainId);

 /**
 * @brief 获取两点间方向变化点数量
 * @param[in] LOD_STRU* pLODAStru
 * @param[in] LOD_STRU* pLODBStru
 * @return 方向变化点数量
 * @note 无
 */
 UINT8 elm_PrepareDirChangNum(const LOD_STRU* pLODAStru, const LOD_STRU* pLODBStru);

 /**
 * @brief 根据方向变化点数量转换方向
 * @param[in] UINT8 Dir 方向
 * @param[in] UINT8 wChangeNum 方向变化点数量
 * @return 转换后的方向
 * @note 无
 */
 UINT8 elm_PrepareDirByChangeNum(UINT8 Dir, UINT8 wChangeNum);

 /**
 * @brief 通过计轴区段ID查找前方对应计轴器：
 * @param[in] UINT16 ACID 计轴区段ID
 * @param[in] UINT8 chDir 起点指向终点的方向
 * @param[out] UINT16* AxisId 前方查询计轴器Id
 * @return CI_SUCCESS 查询正确，返回成功
 *         CI_ERROR   查询错误，返回失败
 * Create: fan 2024 3.2
 */
 UINT8 elm_PrepareACHeadAxisId(UINT16 ACID, UINT8 chDir, UINT16* AxisId);

 /**
 * @brief 通过计轴区段ID查找后方对应计轴器：
 * @param[in] UINT16 ACID 计轴区段ID
 * @param[in] UINT8 chDir 起点指向终点的方向
 * @param[out] UINT16* AxisId 后方查询计轴器Id
 * @return CI_SUCCESS 查询正确，返回成功
 *         CI_ERROR   查询错误，返回失败
 * Create: fan 2024 3.2
 */
 UINT8 elm_PrepareACTailAxisId(UINT16 ACID, UINT8 chDir, UINT16* AxisId);

 /**
 * @brief  判断是否满足前筛通过条件(降低复杂度)
 * @param[in]UINT16 wTrainId 列车ID
 * @param[in]const LOD_STRU trainPos 列车安全端位置
 * @param[in]const LOD_STRU ACpos 计轴对应端点位置
 * @param[out] UINT32* errorCode 故障记录
 * @return CI_SUCCESS 满足前筛条件	CI_ERROR不满足
 *			ADJUST_UCT  不满足筛选但需要处理UCT包络
 * Create: fan 2024 4.1
 */
 UINT8 elm_PrepareHeadScreenCheck(UINT16 wTrainId, const LOD_STRU trainPos, const LOD_STRU ACpos, UINT32* errorCode);

 /**
 * @brief 判断是否满足后筛通过条件(降低复杂度)
 * @param[in]UINT16 wTrainId 列车ID
 * @param[in]const LOD_STRU trainPos 列车安全端位置
 * @param[in]const LOD_STRU ACpos 计轴对应端点位置
 * @param[out] UINT32* errorCode 故障记录
 * @return CI_SUCCESS 满足筛选条件	CI_ERROR不满足
 *			ADJUST_UCT  不满足筛选但需要处理UCT包络
 * Create: fan 2024 4.1
 */
 UINT8 elm_PrepareTailScreenCheck(UINT16 wTrainId, const LOD_STRU trainPos, const LOD_STRU ACpos, UINT32* errorCode);
#endif /*ELM_DATA_PREPARE_H_*/