#include "CutoffPointConfigDataManage.h"

CfpConfigStru g_szCfpConfig[CUTOFF_POINT_SUM_MAX] = { 0u };	/* 分界点配置数据存放数组 */
UINT16 gszCfpId[CUTOFF_POINT_SUM_MAX] = {0U};
UINT16 gCfpConfigSum = 0u;									/* 分界点配置个数 */

/**
* @brief 获取本TIOC分界点总数
* @param 无
* @return 本TIOC分界点总数
*/
UINT16 GetCfpSum(void)
{
	UINT16 wRetVal = 0u;
	if (CUTOFF_POINT_SUM_MAX <= gCfpConfigSum)
	{
		wRetVal = CUTOFF_POINT_SUM_MAX;
	}
	else
	{
		wRetVal = gCfpConfigSum;
	}
	return wRetVal;
}

/**
* @brief 获取分界点ID
* @param bufIndex ID下标
* @return 分界点ID
*/
UINT16 GetCfpId(const UINT16 bufIndex)
{
	UINT16 wRetVal = CI_ERROR;
	UINT16 wCfpSum = GetCfpSum();
	if (bufIndex < wCfpSum)
	{
		wRetVal = gszCfpId[bufIndex];
	}
	else
	{
		wRetVal = CI_ERROR;
	}
	return wRetVal;
}

/**
* @brief 获取分界点存储指针
* @param 无
* @return 分界点存储指针
*/
CfpConfigStru * GetCfpConfigData(void)
{
	return (CfpConfigStru *)g_szCfpConfig;
}

/**
* @brief 获取分界点存储索引
* @param wCfpId 分界点ID
* @return 分界点存储索引
* @note 内部优化 20220418 wqm 增加入参大于0的检查
*/
UINT16 GetCfpBufIndex(const UINT16 wCfpId)
{
	UINT16 wRetVal = CUTOFF_POINT_SUM_MAX;
	if ((CUTOFF_POINT_SUM_MAX > wCfpId) && ( 0u < wCfpId))
	{
		wRetVal = wCfpId;
	}
	else
	{
		;
	}
	return wRetVal;
}

/**
* @brief 获取分界点所处link
* @param wCfpId 分界点ID
* @return 分界点所处link
*/
UINT16 GetCfpLink(const UINT16 wCfpId)
{
	UINT16 wRetVal = 0u;
	UINT16 wIndex = 0u;
	wIndex = GetCfpBufIndex(wCfpId);
	if (CUTOFF_POINT_SUM_MAX > wIndex)
	{
		wRetVal = g_szCfpConfig[wIndex].wLinkId;
	}
	else
	{
		;
	}
	return wRetVal;
}

/**
* @brief 获取分界点所处link偏移量
* @param wCfpId 分界点ID
* @return 分界点存储所处link偏移量
* @note 20220418 wqm 修改默认值为UINT32_MAX
*/
UINT32 GetCfpOffset(const UINT16 wCfpId)
{
	UINT32 dwRetVal = UINT32_MAX;
	UINT16 wIndex = 0u;
	wIndex = GetCfpBufIndex(wCfpId);
	if (CUTOFF_POINT_SUM_MAX > wIndex)
	{
		dwRetVal = g_szCfpConfig[wIndex].dwOffset;
	}
	else
	{
		;
	}
	return dwRetVal;
}

/**
* @brief 获取分界点相邻TIOC编号
* @param wCfpId 分界点ID
* @return 分界点相邻TIOC编号
*/
UINT16 GetCfpOtherTioc(const UINT16 wCfpId)
{
	UINT16 wRetVal = 0u;
	UINT16 wIndex = 0u;
	wIndex = GetCfpBufIndex(wCfpId);
	if (CUTOFF_POINT_SUM_MAX > wIndex)
	{
		wRetVal = g_szCfpConfig[wIndex].wOtherTiocId;
	}
	else
	{
		;
	}
	return wRetVal;
}

/**
* @brief 获取本TIOC处于分界点方向
* @param wCfpId 分界点ID
* @return 本TIOC处于分界点方向
*/
UINT8 GetCfpLocDir(const UINT16 wCfpId)
{
	UINT8 chRetVal = 0u;
	UINT16 wIndex = 0u;
	wIndex = GetCfpBufIndex(wCfpId);
	if (CUTOFF_POINT_SUM_MAX > wIndex)
	{
		chRetVal = g_szCfpConfig[wIndex].chLocDir;
	}
	else
	{
		;
	}
	return chRetVal;
}

/**
* @brief 获取分界点内方第一link
* @param wCfpId 分界点ID
* @return 分界点内方第一link
*/
UINT16 GetCfpInFirstLink(const UINT16 wCfpId)
{
	UINT16 wRetVal = 0u;
	UINT16 wIndex = 0u;
	wIndex = GetCfpBufIndex(wCfpId);
	if (CUTOFF_POINT_SUM_MAX > wIndex)
	{
		wRetVal = g_szCfpConfig[wIndex].wInFirstLink;
	}
	else
	{
		;
	}
	return wRetVal;
}

/**
* @brief 根据link和偏移量获取分界点ID
* @param wLink
* @param dwOffset
* @return 0：查询失败  其他：分界点ID
*/
UINT16 GetCfpIdByPoint(UINT16 wLink, UINT32 dwOffset)
{
	UINT16 wIndex = 0u;
	UINT16 wCfpSum = GetCfpSum();
	UINT16 wCfpId = 0u;
	UINT16 wCfpLink = 0u;
	UINT32 dwCfpOffset = UINT32_MAX;
	UINT16 wRetVal = 0u;
	UINT8 chFunRet = CI_ERROR;
	UINT16 wSameLink = 0u;
	UINT32 dwSameOffset = UINT32_MAX;
	chFunRet = CheckLinkValid(wLink, dwOffset);
	if (CI_SUCCESS == chFunRet)
	{
		for (wIndex = 0u; wIndex < wCfpSum; wIndex++)
		{/* 遍历分界点 */
			wCfpId = GetCfpId(wIndex);
			wCfpLink = GetCfpLink(wCfpId);
			dwCfpOffset = GetCfpOffset(wCfpId);
			(void)dsuCheckSameLoc(wCfpLink, dwCfpOffset, &wSameLink, &dwSameOffset);
			if ((wCfpLink == wLink) && (dwCfpOffset == dwOffset))
			{
				wRetVal = wCfpId;/* 边界点所处位置与输入一致，找到此边界点 */
			}
			else if(((wSameLink == wLink) && (dwSameOffset == dwOffset)))
			{
				wRetVal = wCfpId;/* 边界点同位置点与输入一致，找到此边界点 */
			}
			else
			{
				; /*无操作*/
			}

			if (0u != wRetVal)
			{
				break;/* 找到对应边界点，跳出循环 */
			}
			else
			{
				;
			}
		}
	}
	else
	{
		;
	}
	return wRetVal;
}

/*
* 功能描述：	整理读入的分界点配置数据
* 参数说明：	无
* 返回值  ：	CI_SUCCESS,整理成功
*				CI_ERROR,整理失败
*/
UINT8 CutoffPointConfigDataManage(void)
{
	UINT16 ii = 0u;      /*游标*/
	UINT16 jj = 0u;      /*游标*/
	UINT16 wCutoffDataSum = 0u;      /*信号机设备配置数据总数*/
	UINT8 ret = CI_ERROR;
	UINT8 localCiId = GetSystemParaLocalCiId();

	/*保存信号机ID索引数组*/
	wCutoffDataSum =GetCfpSum ();
	if (wCutoffDataSum < CUTOFF_POINT_SUM_MAX)
	{/*配置数据总数错误*/

		for (ii = 0u; ii < CUTOFF_POINT_SUM_MAX; ii++)
		{
			if (jj == wCutoffDataSum)
			{/*遍历有效数据完毕*/

				break;
			}
			else
			{
				;
			}
			if (localCiId == g_szCfpConfig[ii].wLocalTiocId)
			{/*该部分为有效数据*/

				gszCfpId[jj] = g_szCfpConfig[ii].wPointId;
				jj++;
			}
			else
			{
				;
			}
		}
		ret = CI_SUCCESS;
	}
	else
	{
		;
	}

	return ret;

}

/**
* @brief 获取两点之间属于本控区的分界点
* @param struct_PathPoint strPointA
* @param struct_PathPoint strPointB
* @param struct_PathPoint *pPoint
* @return CI_SUCCESS:获取成功  CI_ERROR:获取失败
*/
UINT8 GetCfpLocByTwoPoints(struct_PathPoint strPointA, struct_PathPoint strPointB, struct_PathPoint* pPoint)
{
	UINT16 wIndex = 0u;
	UINT16 wCfpSum = GetCfpSum();
	UINT16 wCfpId = 0u;
	UINT16 wCfpLink = 0u;
	UINT32 dwCfpOffset = UINT32_MAX;
	UINT8 chFunRet = CI_ERROR;
	UINT16 wSameLink = 0u;
	UINT32 dwSameOffset = UINT32_MAX;
	UINT8 chDirA = 0u;
	UINT8 chDirB = 0u;
	struct_PathPoint strPointCfp = { 0u };
	UINT8 chRtn = CI_ERROR;
	UINT16 wLinkTioc = 0u;
	UINT8 chLocTioc = 0u;
	LOD_STRU lodStrPointA = { 0U };
	LOD_STRU lodStrPointB = { 0U };
	str_Zone strZone = { 0u };
	UINT32 dwLen = UINT32_MAX;
	UINT16 wLinkNum = 0U;
	UINT8 chFunRtn = CI_ERROR;

	/* 入参检测，判断是否为合法位置 */
	chFunRet = CheckLinkValid(strPointA.wLinkId, strPointA.dwOffset);
	chFunRet &= CheckLinkValid(strPointB.wLinkId, strPointB.dwOffset);
	if (CI_SUCCESS == chFunRet)
	{
		chLocTioc = GetSystemParaLocalCiId();
		for (wIndex = 0u; wIndex < wCfpSum; wIndex++)
		{
			wCfpId = GetCfpId(wIndex);
			wCfpLink = GetCfpLink(wCfpId);
			dwCfpOffset = GetCfpOffset(wCfpId);
			strPointCfp.wLinkId = wCfpLink;
			strPointCfp.dwOffset = dwCfpOffset;

			/* 遍历边界点，获取边界点处于输入两点位置 */
			lodStrPointA.Lnk = strPointA.wLinkId;
			lodStrPointA.Off = strPointA.dwOffset;
			lodStrPointB.Lnk = strPointB.wLinkId;
			lodStrPointB.Off = strPointB.dwOffset;

			dwLen = dsuLenByPoint(&lodStrPointA, &lodStrPointB, &wLinkNum, strZone.pLinkSeq.szLinkId, &strZone.Dir);

			if (UINT32_MAX != dwLen)
			{
				strZone.pLinkSeq.cLinkCnt = (UINT8)wLinkNum;
				strZone.pStart.wLinkId = lodStrPointA.Lnk;
				strZone.pStart.dwOffset = lodStrPointA.Off;
				strZone.pEnd.wLinkId = lodStrPointB.Lnk;
				strZone.pEnd.dwOffset = lodStrPointB.Off;

				chFunRtn = IsPointInPath(strPointCfp, strZone);  /*判断分界点是否处于两点间*/

				if (CI_ERROR == chFunRtn)
				{
					chRtn = CI_SUCCESS;  /*在两点形成的区域之间*/
				}
				else
				{

				}
			}
			else
			{
				chRtn = CI_ERROR;  /*返回失败*/
			}

			if (CI_SUCCESS == chRtn)
			{
				wLinkTioc = GetLinkManageTiocById(wCfpLink);
				if (wLinkTioc == chLocTioc)
				{
					pPoint->wLinkId = wCfpLink;
					pPoint->dwOffset = dwCfpOffset;
				}
				else
				{
					/* 需要返回边界点所在本控区位置，所以边界点所处link不为本TIOC，获取同位置点 */
					chFunRet = dsuCheckSameLoc(wCfpLink, dwCfpOffset, &wSameLink, &dwSameOffset);
					if (CI_SUCCESS == chFunRet)
					{
						pPoint->wLinkId = wSameLink;
						pPoint->dwOffset = dwSameOffset;
					}
					else
					{
						chRtn = CI_ERROR;
					}
				}
				break;
			}
		}
	}
	else
	{
		;
	}
	return chRtn;
}

/**
* @brief 获取两点之间属于本控区的分界点
* @param struct_PathPoint strPointA
* @param struct_PathPoint strPointB
* @param struct_PathPoint *pPoint
* @return CI_SUCCESS:获取成功  CI_ERROR:获取失败
*/
UINT8 GetCfpLocByTwoPointsEx(LOD_STRU strPointA, LOD_STRU strPointB, LOD_STRU *pPoint)
{
	UINT8 chRtn = CI_ERROR;
	struct_PathPoint strTmpA = { 0u };
	struct_PathPoint strTmpB = { 0u };
	struct_PathPoint strTmpC = { 0u };
	LOD_STRU strTmpD = { 0u };
	UINT8 chDirChangeNum = 0u;
	if (NULL == pPoint)
	{
		;
	}
	else
	{
		chRtn = CheckLinkValid(strPointA.Lnk, strPointA.Off);
		chRtn &= CheckLinkValid(strPointB.Lnk, strPointB.Off);
	}

	/* 如参检测通过 */
	if (CI_SUCCESS == chRtn)
	{
		strTmpA.wLinkId = strPointA.Lnk;
		strTmpA.dwOffset = strPointA.Off;
		strTmpB.wLinkId = strPointB.Lnk;
		strTmpB.dwOffset = strPointB.Off;
		chRtn = GetCfpLocByTwoPoints(strTmpA, strTmpB, &strTmpC);
	}
	else
	{
		;
	}

	if (CI_SUCCESS == chRtn)
	{
		strTmpD.Lnk = strTmpC.wLinkId;
		strTmpD.Off = strTmpC.dwOffset;
		strTmpD.Dir = EMAP_SAME_DIR;/*方向不使用，仅赋值*/

		chDirChangeNum = GetDirChangeNumBtwPoints(&(strPointA), &(strTmpD));
		pPoint->Lnk = strTmpC.wLinkId;
		pPoint->Off = strTmpC.dwOffset;
		pPoint->Dir = TransDirByChangeNum(strPointA.Dir, chDirChangeNum);
	}
	else
	{
		;
	}

	return chRtn;
}

/**
* @brief 获取分界点本方TIOC编号
* @param wCfpId 分界点ID
* @return 分界点相邻TIOC编号
* by cgh 20240221
*/
UINT16 GetCfpwLocalTiocId(const UINT16 wCfpId)
{
	UINT16 wRetVal = 0U;
	UINT16 wIndex = 0u;
	wIndex = GetCfpBufIndex(wCfpId);

	if (CUTOFF_POINT_SUM_MAX > wIndex)
	{
		wRetVal = g_szCfpConfig[wIndex].wLocalTiocId;
	}
	else
	{
		;
	}
	return wRetVal;
}

/*
* @brief 获取分界点关联的相邻RC的信号机ID
* @param const UINT16 wCfpId 分界点ID
* @return 分界点关联的相邻RC的信号机ID
* Created By LQ 2024.09.03
*/
UINT16 GetCfpRelAdjacentRcSignalId(const UINT16 wCfpId)
{
	UINT16 wRetVal = 0U;
	UINT16 wIndex = 0U;

	wIndex = GetCfpBufIndex(wCfpId);

	if (CUTOFF_POINT_SUM_MAX > wIndex)
	{
		wRetVal = g_szCfpConfig[wIndex].wRelAdjacentRcSignalId;
	}
	else
	{
		/*入参检查失败，返回0*/
	}

	return wRetVal;
}