#pragma once
/**
* 适用于FEKO的近场结果的 BP 成像算法
* 
**/
#include <complex>
#include <stdlib.h>
#include <stdio.h>
#include <Eigen/Core>
#include <Eigen/Dense>
#include <memory>
#include <vector>
#include "referenceHeader.h"



// FEKO 几何关系处理

/// <summary>
/// 笛卡尔坐标系，转换为 极坐标系
/// </summary>
/// <param name="CartesianPoint">[X,Y,Z;X1,Y1,Z1]</param>
/// <returns></returns>
Eigen::MatrixXd Cartesian2Spherical(Eigen::MatrixXd CartesianPoint);

/// <summary>
/// 时域BP
/// </summary>
class BP2DProcessClass {
public:
	size_t height;
	size_t width;
	Eigen::MatrixXcd echo;
	Eigen::MatrixXd AntPosition;
	Eigen::VectorXd Frequencylist;
	size_t freqnum;
	double f1;
	double fc;
	double Rref; // 成像中心的参考距离
	double minX;
	double maxX;
	double minY;
	double maxY;
	double centerX;
	double centerY;
	double Zplane;
	size_t ImageHeight;
	size_t ImageWidth;
	QString out_path;
public:
	virtual int initProcess(QString in_path, QString out_path, double Rref, double minX, double maxX, double minY, double maxY, double PlaneZ, int ImageHeight, int ImageWidth);
	virtual int readEchoFile(QString in_path);
	virtual int saveTiFF(Eigen::MatrixXcd m);
	virtual int start();
	virtual int logFUN(int percent, QString logtext);
};


int BP2DProcess(QString in_path, QString out_path, double Rref, double minX, double maxX, double minY, double maxY, double PlaneZ,int ImageHeight,int ImageWidth);
// BP 成像时，逐像素点计算，计算速度慢，回波（PRFNUM,freqNUM)
template<typename T>
Eigen::MatrixXcd BP2DImageByPixel(Eigen::MatrixXcd timeEcho,Eigen::MatrixXd AntPosition,double minX,double maxX,double minY,double maxY,double PlaneZ ,double Rref,size_t ImageWidth,size_t ImageHeight,double startfreq,size_t timefreqnum,double timeFreqBandWidth, T* logclss=nullptr);

/// <summary>
/// 时域BP --- FBP
/// </summary>
class FBP2DProcessClass:public BP2DProcessClass {
public:
	size_t height;
	size_t width;
	Eigen::MatrixXcd echo;
	Eigen::MatrixXd AntPosition;
	Eigen::VectorXd Frequencylist;
	size_t freqnum;
	double f1;
	double fc;
	double Rref; // 成像中心的参考距离
	double minX;
	double maxX;
	double minY;
	double maxY;
	double centerX;
	double centerY;
	double Zplane;
	size_t ImageHeight;
	size_t ImageWidth;
	QString out_path;
public:
	virtual int initProcess(QString in_path, QString out_path, double Rref, double minX, double maxX, double minY, double maxY, double PlaneZ, int ImageHeight, int ImageWidth);
	virtual int readEchoFile(QString in_path);
	virtual int saveTiFF(Eigen::MatrixXcd m);
	virtual int start();
	virtual int logFUN(int percent, QString logtext);
};

// BP 成像时，逐脉冲计算，回波（PRFNUM,freqNUM)
template<typename T>
Eigen::MatrixXcd BP2DImageByPluse(Eigen::MatrixXcd timeEcho, Eigen::MatrixXd AntPosition, double minX, double maxX, double minY, double maxY, double PlaneZ, double Rref, size_t ImageWidth, size_t ImageHeight, double startfreq, size_t timefreqnum, double timeFreqBandWidth, T* logclss = nullptr);

int FBP2DProcess(QString in_path, QString out_path, double Rref, double minX, double maxX, double minY, double maxY, double PlaneZ, int ImageHeight, int ImageWidth);

// 生成成像的数据文件
int build2Bin(QString path,int width,int height,std::vector<double> &freqs,Eigen::MatrixXd AntPositions,Eigen::MatrixXcd echo);


// 定义插值函数，以处理复数值
std::complex<double> InterpolateComplex(Eigen::MatrixXd& xi, Eigen::MatrixXd& yi, Eigen::MatrixXcd& data, double x, double y);



/// <summary>
/// 远场成像
/// </summary>
class FEKOFarFieldProcessClass :public BP2DProcessClass {
public:
	size_t height;
	size_t width;
	Eigen::MatrixXcd echo;
	Eigen::MatrixXd AntPosition; // theta phi 0
	Eigen::VectorXd Frequencylist;
	size_t freqnum;
	double f1;
	double fc;
	double Rref; // 成像中心的参考距离
	double minX;
	double maxX;
	double minY;
	double maxY;
	double centerX;
	double centerY;
	double Zplane;
	size_t ImageHeight;
	size_t ImageWidth;
	QString out_path;
public:
	virtual int initProcess(QString in_path, QString out_path, double Rref, double minX, double maxX, double minY, double maxY, double PlaneZ, int ImageHeight, int ImageWidth);
	virtual int readEchoFile(QString in_path);
	virtual int saveTiFF(Eigen::MatrixXcd m);
	virtual int start();
	virtual int logFUN(int percent, QString logtext);

	// 平均频率间隔
	double get_df() { return (this->Frequencylist(this->get_Nf() - 1) - this->Frequencylist(0)) / (this->get_Nf() - 1); };
	// 脉冲数
	size_t get_Nxa() { return this->AntPosition.rows(); };
	// 频率点数
	size_t get_Nf() { return this->Frequencylist.rows(); };
	double get_minFreq() { this->Frequencylist(this->get_Nf() - 1) > this->Frequencylist(0) ? this->Frequencylist(0) : this->Frequencylist(this->get_Nf() - 1); };

};







