#ifndef jfxmap_laneplan_h
#define jfxmap_laneplan_h

#include <vector>
#include "Route.h"

namespace jf {
    class LanePlan {
    public:
        LanePlan(const std::string &cstrProjectPath, const std::string &cstrMapConfigPath);

        std::vector<LaneEndpoint> &GetRoute() { return m_vctleRoute; }

        /**
         * @brief 设置路径
         * @param cvctptWayNode：起点，途径点（如果有），终点的顺序保存的点坐标
         * @param vctleOutWayPoint：寻路时使用的lane
         * @param bRenowResult：是否更新现有结果
         * @return 寻路是否成功
         */
        bool SetPath(const std::vector<Point> &cvctptWayNode, std::vector<LaneEndpoint> &vctleOutWayPoint,
                     bool bRenowResult = true);

        /**
         * @brief 指定不可通行车道的ID
         * @param cvctlUnpassableLane：不可通行车道的集合
         * @return 无
         */
        void SetUnpassableLane(const std::vector<HdLaneId> &cvctlUnpassableLane);

        /**
         * @brief 获取寻路结果中，车道的总数
         * @param 无
         * @return 车道总数
         */
        int GetLaneCnt();


        /**
         * @brief 获取指定的车道信息
         * @param nIndex：在寻路结果中，车道的索引
         * @param leOutEndpoint：指定的车道端点的信息
         * @return 指定车道所在link的指针
         */
        bool GetLaneEndpoint(int nIndex, LaneEndpoint &leOutEndpoint);

        /**
         * @brief 获取以该点为中心，指定范围内能找到的车道的集合
         * @param cptInPoint：所给的点
         * @param fLonIntervalHalfMetre：横向寻找范围
         * @param fLatIntervalHalfMetre：纵向寻找范围
         * @param vctptOutPoint：每个lane距离该点最近的车道上的轨迹点的集合（每个车道都有一个点，和后面的两个输出一一对应）
         * @param vctleOutLaneEp：以该点为中心，指定范围内能找到的车道的集合
         * @param vctdOutDistance：找到的车道距离该点的距离
         * @return 是否成功获取
         */
        bool GetNearEndpoints(const Point &cptInPoint, std::vector<Point> &vctptOutPoint,
                              std::vector<LaneEndpoint> &vctleOutLaneEp, std::vector<double> &vctdOutDistance);


        /**
         * @brief 获取指定的车道集合（一般是某个点所属与的车道集合）在寻路结果内的索引
         * @param cvctleEndpoint：车道集和
         * @param nOutIndex：索引
         * @param nPastIndex：开始计算的索引
         * @param nFindCnt：总计寻找的个数
         * @return 是否成功获取
         */
        bool GetIndex(const std::vector<LaneEndpoint> &cvctleEndpoint, int &nOutIndex, int nPastIndex = 0,
                      int nFindCnt = 65536);

        /**
         * @brief 获取指定的车道
         * @param cleEndpoint：车道
         * @param nOutIndex：索引
         * @param nPastIndex：开始计算的索引
         * @param nFindCnt：总计寻找的个数
         * @return 是否成功获取
         */
        bool GetIndex(const LaneEndpoint &cleEndpoint, int &nOutIndex, int nPastIndex = 0, int nFindCnt = 65536);

        /**
         * @brief 获取指定的点，在指定的车道轨迹点上的索引（取该点距离轨迹点上、距离最近点的索引）
         * @param cptInPoint：指定点
         * @param nIndex：在寻路结果内的索引
         * @return 索引值
         */
        int GetPosIdxInLane(const Point &cptInPoint, int nIndex);


    private:
        // 生成轨迹点
        void GenInterpGeometry(const std::vector<Point> &cvctptWayNode, std::vector<LaneEndpoint> &vctleOutWayPoint,
                               std::vector<LaneEndpoint> &vctleInOutLanePath);

        // 平滑
        bool
        SmoothChangeRoad(const HdLinkId &clLinkId, int nFromLaneNum, int nToLaneNum, std::vector<Point> &vctptOutCurve);

        // 打印轨迹点
        void PrintQGIS(const std::string &cstrFileName, const std::vector<LaneEndpoint> &cvctleClosedList);

    private:
        Route<LaneEndpoint> m_rtleRoute;
        std::vector<HdLaneId> m_vctlRouteEndLaneId;
        std::vector<HdLaneId> m_vctlUnpassableLane;

    public:
        std::vector<LaneEndpoint> m_vctleRoute;  //路径规划输出的结果
    };
}  // namespace jf

#endif
