#include "API_UnderStitch.h"
#include "opencv2/opencv.hpp"
#include "Arith_GeoSolver.h"
#include "Arith_FeaMatch.h"
#include "StitchStruct.h"
#include "Arith_BATask.h"
#include "FileCache.h"
#include "GoogleTile.h"
#include "Arith_BlendMap.h"
#include <map>
#include "utils/Arith_ThreadPool.h"
#include "Logger.h"

class UnderStitch :public API_UnderStitch
{
public:
    UnderStitch(std::string cachedir = "./cache");

    ~UnderStitch();

    UPanInfo Init(FrameInfo info);

    void SetOutput(std::string filename, std::string outdir);

    void SetConfig(UPanConfig config);

    SINT32 Run(GD_VIDEO_FRAME_S img, FrameInfo para);

    void Stop();

    SINT32 OptAndOutCurrPan();

    GD_VIDEO_FRAME_S     ExportPanAddr();

    cv::Mat ExportPanMat();

    // 全景图地理信息计算
    PointBLH getBLHFromPan(cv::Point2f ptInPan, cv::Mat _H_panPara);

	cv::Point2f getPanXYFromBLH(PointBLH ptInBLH, cv::Mat _H_panPara);

private:
    // 判断帧是否在全景图视场内
    bool isFrameInPanView(const cv::Size& frameSize, const cv::Mat& H, const cv::Size& panSize);

    // 视频帧筛选
    bool FilterFrame(FrameInfo para);

    // 触发BA优化时机
    bool TriggerBA(FrameInfo para);

    // 实时裁切瓦片
    void CutTileRealTime();

    // 接收帧
    SINT32 ReceiveFrame(GD_VIDEO_FRAME_S img, FrameInfo para);

    // 输出地理产品:kml png全景
    bool ExportGeoPng();

    // 正射校正
    cv::Mat getOrthImage(cv::Mat src, FrameInfo para, TileInfo& tile);

    cv::Mat getAffineFromGeo2Pan(UPanInfo _pan);//计算全景图投影，从地理系到全景地图，统一计算

    // 初始化全景图配置
    UPanInfo     InitMap(FrameInfo info);
    
    // 重新定位全景图配置，用于帧超出全景图视场时平移调整
    UPanInfo     ReLocateMap(FrameInfo info);

private:

    vector<KeyType> _recvFrameKey;// 接收帧总表
    vector<KeyType> _baWindowKey;// BA滑动窗口
    std::map<KeyType, int> _recvFrameOptFlag;//接收帧的优化标记

    FileCache<FrameCache>* _cache;//文件缓存，存储外部传入的原始帧信息以及预处理结果

    // 保存上一帧信息
    KeyType _lastFrameKey;  // 上一帧的ID
    FrameInfo _lastFrameInfo;  // 上一帧的信息

private:
    googleTile _googleProduct;

	GeoSolver* _GeoSolver;//外参计算

    FeatureMatcher* _FeaMatcher;//特征匹配

    BA_Task* _BATask;//BA

    MapBlend* _BlendTask;// 融合模块

private:
    UPanInfo _panPara;//全景图配置

    TileInfo _panTile;//全景图瓦片配置

	cv::Mat _H_pan;//全景图投影矩阵：从地理系到全景地图

    vector<TileInfo> _taskTilesVec;//划分的小瓦片方案

    cv::Mat _panImage;

    cv::Mat _panMask; //覆盖区域遮罩

    int _totalFrameCnt;//处理帧计数

    UPanConfig _config;

private:

    string _kmlPath;
    string _filename;//输出文件标识
    string _outDir;//输出拼接成果路径
    string _cacheDir;//缓存路径，优先使用SSD

    std::threadpool _threadPool;  // 线程池

};