// 下面的代码是属性的设置与获取，请补充完整
#include "FEKOSimulationSARClass.h"
#include "BaseToolLib/BaseConstVariable.h"
#include <QMessageBox>
#include <math.h>
#include <complex>
#include "BaseToollib/ImageOperatorBase.h"
#include <SARBaseToolLib/SARImageBase.h>
#include "BaseToollib/FileOperator.h"
#include <QtXml/qdom.h>
#include "BaseToollib/GeoOperator.h"

 


FEKOBase::FEKOSimulationSARClass::FEKOSimulationSARClass()
{

}

FEKOBase::FEKOSimulationSARClass::~FEKOSimulationSARClass()
{
}

void FEKOBase::FEKOSimulationSARClass::generator_STRIP_FEKOSatelliteParams()
{
	qDebug() << u8"计算 Strip...";
	double incAngle = this->simulationparams->incangle;
	double refRange = this->simulationparams->refRange;
	double start_x = this->simulationparams->start_x;
	double start_y = this->simulationparams->start_y;
	double start_z = this->simulationparams->start_z;
	double end_x = this->simulationparams->end_x;
	double end_y = this->simulationparams->end_y;
	double end_z = this->simulationparams->end_z;
	size_t prfcount = this->simulationparams->prfcount;


	double AzAngle = 0;
	this->FEKOAntPoselist.clear();
	gp_Pnt apex(0, 0, 5);  // 顶点在三维空间中的坐标
	gp_Pnt p1(-2, 0, 0);
	gp_Pnt p2(0, -2, 0);
	gp_Pnt p3(4, 0, 0);
	gp_Pnt p4(0, 3, 0);

	// 创建基底的边
	TopoDS_Edge edge1 = BRepBuilderAPI_MakeEdge(p1, p2);
	TopoDS_Edge edge2 = BRepBuilderAPI_MakeEdge(p2, p3);
	TopoDS_Edge edge3 = BRepBuilderAPI_MakeEdge(p3, p4);
	TopoDS_Edge edge4 = BRepBuilderAPI_MakeEdge(p4, p1);

	// 使用边创建一个闭合的线框
	BRepBuilderAPI_MakeWire makeWire;
	makeWire.Add(edge1);
	makeWire.Add(edge2);
	makeWire.Add(edge3);
	makeWire.Add(edge4);
	TopoDS_Wire baseWire = makeWire.Wire();

	// 使用线框创建一个面
	BRepBuilderAPI_MakeFace makeFace(baseWire);
	TopoDS_Face baseFace = makeFace.Face();

	// 从基底面向顶点拉伸，创建四棱锥
	BRepPrimAPI_MakePrism makePrism(baseFace, gp_Vec(apex.XYZ() - p1.XYZ()));
	TopoDS_Shape in_ds = makePrism.Shape();
	double Vx = end_x - start_x;
	double Vy = end_y - start_y;
	double Vz = end_z - start_z;
	for (size_t i = 0; i < prfcount; i++) {
		double Px = start_x + (end_x - start_x) / (prfcount - 1) * i;
		double Py = start_y + (end_y - start_y) / (prfcount - 1) * i;
		double Pz = start_z + (end_z - start_z) / (prfcount - 1) * i;

		// 创建 SatelliteState
		FEKOBase::SatelliteState satepos{
					FEKOBase::SatellitePosition{Px,Py,Pz},
					FEKOBase::SatelliteVelocity{Vx,Vy,Vz},
		};

		FEKOBase::FEKOantPitionDirect tempdir;
		TopoDS_Shape out_ds = SatellitePos2FEKOAntPos(satepos, incAngle, AzAngle, this->simulationparams->isRight, &tempdir, in_ds);
		FEKOBase::FEKOSatelliteParams temp = createFEKOSatelliteParams(satepos, incAngle, AzAngle, tempdir, i);
		this->FEKOAntPoselist.push_back(temp);
	}


}

void FEKOBase::FEKOSimulationSARClass::generator_SCAN_FEKOSatelliteParams()
{
	qDebug() << u8"计算 ScaneSAR...";


	double incAngle = this->simulationparams->incangle;
	double refRange = this->simulationparams->refRange;
	double startAzAngle = this->simulationparams->start_az_angle;
	double endAzAngle = this->simulationparams->end_az_angle;
	double start_x = this->simulationparams->start_x;
	double start_y = this->simulationparams->start_y;
	double start_z = this->simulationparams->start_z;
	double end_x = this->simulationparams->end_x;
	double end_y = this->simulationparams->end_y;
	double end_z = this->simulationparams->end_z;
	size_t prfcount = this->simulationparams->prfcount;


	this->FEKOAntPoselist.clear();
	TopoDS_Shape in_ds;
	for (size_t i = 0; i < prfcount; i++) {
		double AzAngle = startAzAngle + (endAzAngle - startAzAngle) / prfcount * i;
		double Px = start_x + (end_x - start_x) / (prfcount - 1) * i;
		double Py = start_y + (end_y - start_y) / (prfcount - 1) * i;
		double Pz = start_z + (end_z - start_z) / (prfcount - 1) * i;
		double Vx = end_x - start_x;
		double Vy = end_y - start_y;
		double Vz = end_z - start_z;

		// 创建 SatelliteState
		FEKOBase::SatelliteState satepos{
					FEKOBase::SatellitePosition{Px,Py,Pz},
					FEKOBase::SatelliteVelocity{Vx,Vy,Vz},
		};

		FEKOBase::FEKOantPitionDirect tempdir;
		TopoDS_Shape out_ds = SatellitePos2FEKOAntPos(satepos, incAngle, AzAngle, this->simulationparams->isRight, &tempdir, in_ds);
		FEKOBase::FEKOSatelliteParams temp = createFEKOSatelliteParams(satepos, incAngle, AzAngle, tempdir, i);
		this->FEKOAntPoselist.push_back(temp);
	}

}

void FEKOBase::FEKOSimulationSARClass::generator_ISAR_FEKOSatelliteParams()
{
	qDebug() << u8"计算 ISAR...";
	// 计算ISAR
	double iangle = this->simulationparams->incangle; // 入射角
	double azAngle = 0; // 扫描角变化
	double incAngle = this->simulationparams->incangle * M_PI / 180;
	double deltaAngle = this->simulationparams->delta_angle * M_PI / 180;
	double startAngle = this->simulationparams->start_circle_angle * M_PI / 180;
	double endAngle = this->simulationparams->end_circle_angle * M_PI / 180;

	double refRange = this->simulationparams->refRange;


	// 计算ISAR
	this->FEKOAntPoselist.clear();
	double mpi_delta = (deltaAngle) / abs(deltaAngle) * M_PI / 2;
	//double startangle = 0;
	 //double endAngle = M_PI * 2;
	if (mpi_delta > 0) { // 逆时针旋转 
		this->simulationparams->setIsRight(false);
	}
	else {
		this->simulationparams->setIsRight(true);
		endAngle = -1 * endAngle;
	}
	double ZRotation_angle = M_PI - incAngle;

	size_t PRFidx = 0;
	for (double angle = startAngle; angle <= endAngle; angle = angle + deltaAngle) {
		double Px = refRange * sin(incAngle) * cos(angle); // 计算坐标
		double Py = refRange * sin(incAngle) * sin(angle);
		double Pz = refRange * cos(incAngle);
		// 计算速度矢量，它与xyz.切线垂直

		gp_Vec fly_ori(gp_Pnt(Px, Py, Pz), gp_Pnt(0.0, 0.0, 0.0));
		gp_Vec fly_Z(gp_Pnt(0, 0, 0), gp_Pnt(0.0, 0.0, 1));
		gp_Vec fly_direct = fly_ori.Crossed(fly_Z);
		//
		double Vx = fly_direct.X(); // 计算飞行速度
		double Vy = fly_direct.Y();
		double Vz = fly_direct.Z();
		double theta = ZRotation_angle;
		double phi = (this->simulationparams->isRight) ? -1 * angle + M_PI / 2 : angle + M_PI;   // 根据位置计算入射角

		theta = theta * 180 / M_PI;
		phi = phi * 180 / M_PI;
		FEKOBase::FEKOSatelliteParams temp = FEKOBase::createFEKOSatelliteParams(Px, Py, Pz, Vx, Vy, Vz, iangle, azAngle, theta, phi, this->simulationparams->isRight, PRFidx);
		this->FEKOAntPoselist.push_back(temp);
		PRFidx = PRFidx + 1;
	}

}

void FEKOBase::FEKOSimulationSARClass::generator_CircleSAR_FEKOSatelliteParams()
{
	qDebug() << u8"计算 CircleSAR..."; // 飞行方向为 Y 轴，雷达指向为 Z 轴

	double incAngle = this->simulationparams->incangle;
	double deltaAngle = this->simulationparams->delta_angle;
	double refRange = this->simulationparams->refRange;


	double iangle = incAngle; // 入射角
	double azAngle = 0; // 扫描角变化
	incAngle = incAngle * M_PI / 180;
	deltaAngle = deltaAngle * M_PI / 180;
	// 计算ISAR
	this->FEKOAntPoselist.clear();
	double mpi_delta = (deltaAngle) / abs(deltaAngle) * M_PI / 2;
	double startangle = 0;
	double endAngle = M_PI * 2;



	if (mpi_delta > 0) { // 逆时针旋转 
		this->simulationparams->isRight = false;
	}
	else {
		this->simulationparams->isRight = true;
		endAngle = -1 * endAngle;
	}
	double ZRotation_angle = M_PI - incAngle;

	size_t PRFidx = 0;
	for (double angle = 0; angle <= endAngle; angle = angle + deltaAngle) {
		double Px = refRange * sin(incAngle) * cos(angle); // 计算坐标
		double Py = refRange * sin(incAngle) * sin(angle);
		double Pz = refRange * cos(incAngle);
		// 计算速度矢量，它与xyz.切线垂直

		gp_Vec fly_ori(gp_Pnt(Px, Py, Pz), gp_Pnt(0.0, 0.0, 0.0));
		gp_Vec fly_Z(gp_Pnt(0, 0, 0), gp_Pnt(0.0, 0.0, 1));
		gp_Vec fly_direct = fly_ori.Crossed(fly_Z);
		//
		double Vx = fly_direct.X(); // 计算飞行速度
		double Vy = fly_direct.Y();
		double Vz = fly_direct.Z();
		double theta = ZRotation_angle;
		double phi = (this->simulationparams->isRight) ? -1 * angle + M_PI / 2 : angle + M_PI;   // 根据位置计算入射角

		theta = theta * 180 / M_PI;
		phi = phi * 180 / M_PI;
		FEKOBase::FEKOSatelliteParams temp = FEKOBase::createFEKOSatelliteParams(Px, Py, Pz, Vx, Vy, Vz, iangle, azAngle, theta, phi, this->simulationparams->isRight, PRFidx);
		this->FEKOAntPoselist.push_back(temp);
		PRFidx = PRFidx + 1;
	}


}

void FEKOBase::FEKOSimulationSARClass::generator_FEKOSatelliteParams()
{

	switch (this->simulationparams->imagemode)
	{
	case FEKOBase::FEKOImageMode::Strip:
		return this->generator_STRIP_FEKOSatelliteParams();
	case FEKOBase::FEKOImageMode::Scane:
		return this->generator_SCAN_FEKOSatelliteParams();
	case FEKOBase::FEKOImageMode::ISAR:
		return this->generator_ISAR_FEKOSatelliteParams();
	case FEKOBase::FEKOImageMode::CircleSAR:
		return this->generator_CircleSAR_FEKOSatelliteParams();

	default:
		return;
	}
}


void FEKOBase::FEKOSimulationSARClass::refreshFEKOSimulationParams() {
	
}

void FEKOBase::FEKOSimulationSARClass::setFEKOAntPoselist(std::vector<FEKOBase::FEKOSatelliteParams> FEKOAntPoselist)
{
	this->FEKOAntPoselist = FEKOAntPoselist;
}

std::vector<FEKOBase::FEKOSatelliteParams> FEKOBase::FEKOSimulationSARClass::getFEKOAntPoselist()
{
	return this->FEKOAntPoselist;
}

void FEKOBase::FEKOSimulationSARClass::loadFEKOImageSettingXML(QString xmlpath)
{

	if (!isExists(xmlpath)) {
	//	QString  newName = QInputDialog::getText(nullptr, u8"命名", u8"成像任务名称", QLineEdit::Normal);
		QString newName = QInputDialog::getText(nullptr, "rename", "Image task Name", QLineEdit::Normal);
		if (newName.isEmpty()) {
			return;
		}
		this->simulationparams->setTaskName(newName);
		QString parentpath = getParantFromPath(xmlpath);
		this->workSpace = parentpath;
		QDir dir;
		if (!isExists(this->workSpace)) {
			dir.mkpath(this->workSpace);
		}

		this->xmlpath = xmlpath;
		return;
	}
	QString parentpath = getParantFromPath(xmlpath);
	this->workSpace = parentpath;
	this->xmlpath = xmlpath;

	this->simulationparams->loadXml(xmlpath);
	this->generator_FEKOSatelliteParams();
	qDebug() << u8"finish load fekoSimulation xml file.";
}

void FEKOBase::FEKOSimulationSARClass::saveFEKOImageSettingXML()
{
	// 为下列每个节点，附加一个TextNode
	if (isExists(this->xmlpath)) {
		removeFile(this->xmlpath);
	}
	else {}
	this->simulationparams->saveXml(this->xmlpath);
	qDebug()<<"finish save fekoSimulation xml file.";
}

QString FEKOBase::FEKOSimulationSARClass::createLuaSciptString(size_t startprfidx, size_t endprfidx)
{
	QProgressDialog progressDialog(u8"构建馈源设置脚本", u8"终止", 0, this->FEKOAntPoselist.size());
	progressDialog.setWindowTitle("imaging...");
	progressDialog.setModal(true);
	progressDialog.setAutoClose(true);
	progressDialog.setValue(0);
	progressDialog.setMaximum(this->FEKOAntPoselist.size());
	progressDialog.setMinimum(0);
	progressDialog.show();

	if (this->simulationparams->startfreq > 1e6) { this->simulationparams->startfreq = this->simulationparams->startfreq / 1e9; } // ==> GHz
	if (this->simulationparams->endfreq > 1e6) { this->simulationparams->endfreq = this->simulationparams->endfreq / 1e9; }


	QString luascript = QString(u8"--- create feko task :%1\n--- mode:%2\n\n").arg(this->simulationparams->taskName).arg(FEKOBase::FEKOImageModeenumToString(this->simulationparams->imagemode));
	luascript = luascript + QString(u8"-- create strip pulse \n");
	luascript = luascript + QString(u8"-- LAMP \n\n");
	luascript = luascript + QString(u8"-- warning:the configure's number of a feko project should be less than 600. if greater than 600,the program will very slow\n");
	luascript = luascript + QString(u8"\n");
	luascript = luascript + QString(u8"\n");
	luascript = luascript + QString(u8"app=cf.GetApplication()\n");
	luascript = luascript + QString(u8"project=app.Project  --- get current project\n");
	luascript = luascript + QString(u8"farFieldData = project.FieldDataList:AddFarFieldData(\"%1\",%2,%3) -- farField Gains\n").arg(this->simulationparams->AntennaRadiationFileName).arg(QString::number(this->simulationparams->farsource_thetaPoints)).arg(QString::number(this->simulationparams->farsource_phiPoints));
	luascript = luascript + QString(u8"\n");
	luascript = luascript + QString(u8"--const values\n");
	luascript = luascript + QString(u8"local pi=3.141592653589793238462643383279\n");
	luascript = luascript + QString(u8"local r2d=180.0/pi;\n");
	luascript = luascript + QString(u8"local d2r=pi/180.0;\n");
	luascript = luascript + QString(u8"\n");
	luascript = luascript + QString(u8"\n");
	luascript = luascript + QString(u8"\n");
	luascript = luascript + QString(u8"--  varables \n");
	luascript = luascript + QString(u8"\n");
	luascript = luascript + QString(u8"\n");
	luascript = luascript + QString(u8"local f1=%1  -- start freq\n").arg(QString::number(this->simulationparams->startfreq * 1e9));
	luascript = luascript + QString(u8"local f2=%2 -- end freq\n").arg(QString::number(this->simulationparams->endfreq * 1e9));
	luascript = luascript + QString(u8"local freq_num=%3 -- freq point \n").arg(QString::number(this->simulationparams->freqpoints));
	luascript = luascript + QString(u8"\n");
	luascript = luascript + QString(u8"--- local request_z=Rref*math.cos(in_theta*d2r) --z\n");
	luascript = luascript + QString(u8"--- local request_y=Rref*math.sin(in_theta*d2r)*math.sin(in_phi*d2r) -- y\n");
	luascript = luascript + QString(u8"--- local ant_theta= 220 --- 天线入射角方向\n");
	luascript = luascript + QString(u8"--- local ant_phi=90 -- 天线照射方向 -：指向负轴 +：指向正轴\n");
	luascript = luascript + QString(u8"--- local ant_phi_start=-1.5   -- 当前工程的起始点 天线指向扫描角\n");
	luascript = luascript + QString(u8"--- local ant_phi_delta= 3/2800  -- 这里调整步进增量为\n");
	luascript = luascript + QString(u8"\n");
	luascript = luascript + QString(u8"---  PRF POint Setting ---  \n");
	// ------------------------------------------ 参数设置 ------------------------
	for (size_t i = startprfidx; i < this->FEKOAntPoselist.size() && i < endprfidx; i++) {
		FEKOBase::FEKOSatelliteParams temp = this->FEKOAntPoselist[i];
		QString prf_id = QString::number(QString::number(temp.PRFidx).toInt());
		luascript = luascript + QString(u8"    ---------------------\"PRF_%1\" start -------------------------------------------------\n").arg(prf_id);
		luascript = luascript + QString(u8"    PRF_phi=%1 --- 天线照射方向\n").arg(QString::number(temp.antpos.phi));
		luascript = luascript + QString(u8"    PRF_theta=%1 --- 入射角\n").arg(QString::number(temp.antpos.theta));
		luascript = luascript + QString(u8"    temp_standardConfiguration = project.SolutionConfigurations:AddStandardConfiguration()\n");
		luascript = luascript + QString(u8"    temp_standardConfiguration.Label=\"PRF_%1\" -- set standardConfiguration label  PRF Count\n").arg(prf_id);
		luascript = luascript + QString(u8"    --- set frequency\n"); // 设置频率
		luascript = luascript + QString(u8"    frequencyRange=temp_standardConfiguration.Frequency\n");
		luascript = luascript + QString(u8"    properties = frequencyRange:GetProperties()\n");
		luascript = luascript + QString(u8"    properties.RangeType = cf.Enums.FrequencyRangeTypeEnum.LinearSpacedDiscrete\n");
		luascript = luascript + QString(u8"    properties.Start = f1 -- start\n");
		luascript = luascript + QString(u8"    properties.End=f2 --end \n");
		luascript = luascript + QString(u8"    properties.NumberOfDiscreteValues=freq_num -- freq_num\n");
		luascript = luascript + QString(u8"    frequencyRange:SetProperties(properties)\n");
		luascript = luascript + QString(u8"    -- set Source\n");
		luascript = luascript + QString(u8"    farFieldSource = temp_standardConfiguration.Sources:AddFarFieldSource(farFieldData)\n"); // 设置发射源
		luascript = luascript + QString(u8"    farFieldSource.Label=\"FarSource_PRF_%1\"\n").arg(prf_id);
		luascript = luascript + QString(u8"    farFieldSource.Position.U=%1\n").arg(QString::number(temp.antpos.x));
		luascript = luascript + QString(u8"    farFieldSource.Position.V=%1\n").arg(QString::number(temp.antpos.y));
		luascript = luascript + QString(u8"    farFieldSource.Position.N=%1\n").arg(QString::number(temp.antpos.z));
		luascript = luascript + QString(u8"    farFieldSource.Theta=PRF_theta\n");
		luascript = luascript + QString(u8"    farFieldSource.Phi=PRF_phi\n");
		luascript = luascript + QString(u8"    temp_farFieldSource_workplane=farFieldSource.LocalWorkplane\n");
		luascript = luascript + QString(u8"    temp_farFieldSource_workplane.Origin.X=0 -- move reference Point\n");
		luascript = luascript + QString(u8"    temp_farFieldSource_workplane.Origin.Y=0\n");
		luascript = luascript + QString(u8"    temp_farFieldSource_workplane.Origin.Z=0    \n");
		luascript = luascript + QString(u8"\n");
		luascript = luascript + QString(u8"    -- set nearfield\n");
		luascript = luascript + QString(u8"    temp_nearFieldRequest=temp_standardConfiguration.NearFields:AddSpherical(%1,%2,%3,%4,%5,%6,1,1,1) -- nearfield \n").arg(QString::number(0))
			.arg(QString::number(temp.antpos.theta))
			.arg(QString::number(temp.antpos.phi))
			.arg(QString::number(0))
			.arg(QString::number(temp.antpos.theta))
			.arg(QString::number(temp.antpos.phi)); // 设置接收点
		luascript = luascript + QString(u8"    temp_nearFieldRequest.Label=\"NearField_PRF_%1\"\n").arg(prf_id);
		luascript = luascript + QString(u8"    temp_nearFieldRequest_workplane=temp_nearFieldRequest.LocalWorkplane\n");
		luascript = luascript + QString(u8"    temp_nearFieldRequest_workplane.Origin.X=%1\n").arg(QString::number(temp.antpos.x));
		luascript = luascript + QString(u8"    temp_nearFieldRequest_workplane.Origin.Y=%1\n").arg(QString::number(temp.antpos.y));
		luascript = luascript + QString(u8"    temp_nearFieldRequest_workplane.Origin.Z=%1\n").arg(QString::number(temp.antpos.z));
		luascript = luascript + QString(u8"      -- set nearfieldAdavance\n");
		luascript = luascript + QString(u8"    temp_nearfieldAdvance=temp_nearFieldRequest.Advanced\n");
		luascript = luascript + QString(u8"    temp_nearfieldAdvance.CalculationType=cf.Enums.NearFieldCalculationTypeEnum.Fields\n");
		luascript = luascript + QString(u8"    temp_nearfieldAdvance.CalculateElectricFields=true\n");
		luascript = luascript + QString(u8"    temp_nearfieldAdvance.CalculateMagneticFields=true\n");
		luascript = luascript + QString(u8"    temp_nearfieldAdvance.ExportSettings.ASCIIEnabled=true\n");
		luascript = luascript + QString(u8"    temp_nearfieldAdvance.ExportSettings.OutFileEnabled=true\n");
		luascript = luascript + QString(u8"    temp_nearfieldAdvance.OnlyScatteredPartCalculationEnabled=true    \n");
		luascript = luascript + QString(u8"    \n");
		luascript = luascript + QString(u8"  \n");
		luascript = luascript + QString(u8"\n");
		luascript = luascript + QString(u8"    -- \n");
		luascript = luascript + QString(u8"    print(\"PRF_%1\")\n").arg(prf_id);
		luascript = luascript + QString(u8"    ---------------------\"PRF_%1\" end -------------------------------------------------\n").arg(prf_id);
		luascript = luascript + QString(u8"\n");
		progressDialog.setValue(i);
	}
	luascript = luascript + QString(u8"-- prf point setting over -------\n");
	luascript = luascript + QString(u8" \n");

	progressDialog.setWindowTitle(u8"馈源脚本生产成功" );
	progressDialog.setValue(this->FEKOAntPoselist.size());
	progressDialog.close();

	return luascript;
}

 
 
bool FEKOBase::FEKOImageProcess(EchoDataClass& echodata, FEKOImageSettingParams& imageSettingParams, QString& outPath, FEKOImageAlgorithm algmethod, ImageAlgWindowFun winfun)
{
	Eigen::MatrixXcd echoData = echodata.getEchoData();
	Eigen::MatrixXd antpos = echodata.getAntPos();
	Eigen::MatrixXd freqmatrix = Eigen::MatrixXd::Zero(1, echoData.cols());
	Eigen::MatrixXd Image_X = Eigen::MatrixXd::Zero(imageSettingParams.ImageHeight, imageSettingParams.ImageWidth);
	Eigen::MatrixXd Image_Y = Eigen::MatrixXd::Zero(imageSettingParams.ImageHeight, imageSettingParams.ImageWidth);
	Eigen::MatrixXd Image_Z = Eigen::MatrixXd::Zero(imageSettingParams.ImageHeight, imageSettingParams.ImageWidth);
	size_t prfcount = echoData.rows();
	size_t frepoints = echodata.getFreqpoints();
	if (frepoints != echoData.cols() || prfcount != antpos.rows()) {
		QString infotip = u8"回波矩阵 大小不匹配：" + QString(u8"回波脉冲数：%1，实际：%2；回波频点数：%3，实际：%4")
			.arg(QString::number(prfcount)).
			arg(QString::number(antpos.rows()))
			.arg(QString::number(echoData.cols()))
			.arg(QString::number(frepoints));
# ifdef __SHOWPROCESS
		QMessageBox::warning(nullptr, u8"错误", infotip);
#endif // __SHOWPROCESS
		qWarning() << infotip;
		return false;
	}

	// 构建频率矩阵
	double startfreq = echodata.getFreqStart();
	double endfreq = echodata.getFreqEnd();
	if (startfreq > 1e5) { startfreq = startfreq * 1e-9; } // 频率单位进行转换 Hz->GHz
	if (endfreq > 1e5) { endfreq = endfreq * 1e-9; }
	freqmatrix = Eigen::ArrayXd::LinSpaced(frepoints, startfreq, endfreq).array().reshaped(1, frepoints).array();

	// 构建图像坐标矩阵
	size_t imageHeight = imageSettingParams.ImageHeight; // Y 方向
	size_t imageWidth = imageSettingParams.ImageWidth; // X 方向




	for (size_t i = 0; i < imageHeight; i++) {
		Image_X.row(i) = Eigen::ArrayXd::LinSpaced(imageWidth, imageSettingParams.min_x, imageSettingParams.max_x);
	}

	for (size_t i = 0; i < imageWidth; i++) {
		Image_Y.col(i) = Eigen::ArrayXd::LinSpaced(imageHeight, imageSettingParams.max_y, imageSettingParams.min_y);
	}
	Image_Z = Image_Z.array() * 0 + imageSettingParams.plane_z;

	//std::cout << Image_X.row(0) << std::endl;
	//std::cout << Image_Y.col(0) << std::endl;
	switch (algmethod)
	{
	case FEKOBase::TBP_TIME:
		return FEKOBase::BPImage_TIME(outPath, echoData, antpos, freqmatrix, Image_X, Image_Y, Image_Z, winfun);
	case FEKOBase::TBP_FREQ:
		return FEKOBase::FBPImage_FREQ(outPath, echoData, antpos, freqmatrix, Image_X, Image_Y, Image_Z, winfun);
	default:
		return false;
	}
	return false;
}


FEKOBase::FEKOImageProcessAbstractClass::FEKOImageProcessAbstractClass()
{
}

FEKOBase::FEKOImageProcessAbstractClass::~FEKOImageProcessAbstractClass()
{
}

void FEKOBase::FEKOImageProcessAbstractClass::setEchoData(EchoDataClass echodata)
{
	this->echodata = echodata;
}

FEKOBase::EchoDataClass FEKOBase::FEKOImageProcessAbstractClass::getEchoData()  const
{

	FEKOBase::EchoDataClass res; ;
	res.setEchoData(this->echodata.getEchoData());
	res.setAntPos(this->echodata.getAntPos());
	res.setFreqStart(this->echodata.getFreqStart());
	res.setFreqEnd(this->echodata.getFreqEnd());
	res.setFreqpoints(this->echodata.getFreqpoints());
	return res;
}

void FEKOBase::FEKOImageProcessAbstractClass::setImageSettingParams(FEKOImageSettingParams imageSettingParams)
{
}

FEKOBase::FEKOImageSettingParams FEKOBase::FEKOImageProcessAbstractClass::getImageSettingParams()
{
	return this->imageSettingParams;
}

void FEKOBase::FEKOImageProcessAbstractClass::setAlgmethod(FEKOImageAlgorithm algmethod) {
	this->algmethod = algmethod;
}

FEKOBase::FEKOImageAlgorithm FEKOBase::FEKOImageProcessAbstractClass::getAlgmethod()
{
	return this->algmethod;

}

void FEKOBase::FEKOImageProcessAbstractClass::settiffPath(QString outtiffPath)
{
	this->tiffPath = outtiffPath;
}

QString FEKOBase::FEKOImageProcessAbstractClass::gettiffPath()
{
	return this->tiffPath;
}

void FEKOBase::FEKOImageProcessAbstractClass::LoadEchoDataPath(QString echoPath)
{
	EchoDataClass echodata;
	echodata.loadEchoData(echoPath);
	//this->setEchoData(echodata);
	this->echodata = echodata;
}

bool FEKOBase::FEKOImageProcessAbstractClass::Imageprocess()
{
	return FEKOImageProcess(this->echodata, this->imageSettingParams, this->tiffPath, this->algmethod);
}

FEKOBase::FEKOSimulationDataparams::FEKOSimulationDataparams(QObject* parent ): QObject(parent)
{ // 初始化成员变量
	this->taskName = u8"TaskName";
	this->imagemode = FEKOBase::FEKOImageMode::Strip;
	this->isRight = true;
	this->refRange = 9.3;
	this->incangle = 0;
	this->centerFreq = 9.6;
	this->bandwidth = 0.8;
	this->rangeResolution = LIGHESPEEDGHZ/ this->bandwidth/2.0;

	this->startfreq = 9.2;
	this->endfreq = 10;
	this->freqpoints = 41;
	this->x_min = -2;
	this->x_max = 2;
	this->y_min = -2;
	this->y_max = 2;
	this->z_plane = 0;
	this->imageheight = 251;
	this->imagewidth = 251;
	this->prfcount = 101;
	this->start_x = -10;
	this->end_x = 10;
	this->start_y = 10;
	this->end_y = 10;
	this->start_z = 0;
	this->end_z = 0;
	this->start_az_angle = 0;
	this->end_az_angle = 0;
	this->delta_angle = 0;
	this->start_circle_angle = 0;
	this->end_circle_angle = 0;
	this->farsource_thetaPoints = 37;
	this->farsource_phiPoints = 73;
	this->AntennaRadiationFileName = u8"TESTFarSource";
}

FEKOBase::FEKOSimulationDataparams::~FEKOSimulationDataparams()
{
}


QString FEKOBase::FEKOSimulationDataparams::getTaskName() {
	return taskName;
}

void FEKOBase::FEKOSimulationDataparams::setTaskName(QString name) {
	taskName = name;
}

FEKOBase::FEKOImageMode FEKOBase::FEKOSimulationDataparams::getImagemode() {
	return imagemode;
}

void FEKOBase::FEKOSimulationDataparams::setImagemode(FEKOBase::FEKOImageMode mode) {
	imagemode = mode;
}

bool FEKOBase::FEKOSimulationDataparams::getIsRight() {
	return isRight;
}

void FEKOBase::FEKOSimulationDataparams::setIsRight(bool right) {
	isRight = right;
}

double FEKOBase::FEKOSimulationDataparams::getRefRange() {
	return refRange;
}

void FEKOBase::FEKOSimulationDataparams::setRefRange(double range) {
	refRange = range;
}

double FEKOBase::FEKOSimulationDataparams::getIncangle() {
	return incangle;
}

void FEKOBase::FEKOSimulationDataparams::setIncangle(double angle) {
	incangle = angle;
}

double FEKOBase::FEKOSimulationDataparams::getCenterFreq() {
	return centerFreq;
}

void FEKOBase::FEKOSimulationDataparams::setCenterFreq(double freq) {
	centerFreq = freq;
}

double FEKOBase::FEKOSimulationDataparams::getRangeResolution() {
	return rangeResolution;
}

void FEKOBase::FEKOSimulationDataparams::setRangeResolution(double resolution) {
	rangeResolution = resolution;
}

double FEKOBase::FEKOSimulationDataparams::getBandwidth() {
	return bandwidth;
}

void FEKOBase::FEKOSimulationDataparams::setBandwidth(double bw) {
	bandwidth = bw;
}

double FEKOBase::FEKOSimulationDataparams::getStartfreq() {
	return startfreq;
}

void FEKOBase::FEKOSimulationDataparams::setStartfreq(double start) {
	startfreq = start;
}

double FEKOBase::FEKOSimulationDataparams::getEndfreq() {
	return endfreq;
}

void FEKOBase::FEKOSimulationDataparams::setEndfreq(double end) {
	endfreq = end;
}

double FEKOBase::FEKOSimulationDataparams::getFreqpoints() {
	return freqpoints;
}

void FEKOBase::FEKOSimulationDataparams::setFreqpoints(double points) {
	freqpoints = points;
}

double FEKOBase::FEKOSimulationDataparams::getX_min() {
	return x_min;
}

void FEKOBase::FEKOSimulationDataparams::setX_min(double xmin) {
	x_min = xmin;
}

double FEKOBase::FEKOSimulationDataparams::getX_max() {
	return x_max;
}

void FEKOBase::FEKOSimulationDataparams::setX_max(double xmax) {
	x_max = xmax;
}

double FEKOBase::FEKOSimulationDataparams::getY_min() {
	return y_min;
}

void FEKOBase::FEKOSimulationDataparams::setY_min(double ymin) {
	y_min = ymin;
}

double FEKOBase::FEKOSimulationDataparams::getY_max() {
	return y_max;
}

void FEKOBase::FEKOSimulationDataparams::setY_max(double ymax) {
	y_max = ymax;
}

double FEKOBase::FEKOSimulationDataparams::getZ_plane() {
	return z_plane;
}

void FEKOBase::FEKOSimulationDataparams::setZ_plane(double z) {
	z_plane = z;
}

size_t FEKOBase::FEKOSimulationDataparams::getImageheight() {
	return imageheight;
}

void FEKOBase::FEKOSimulationDataparams::setImageheight(size_t height) {
	imageheight = height;
}

size_t FEKOBase::FEKOSimulationDataparams::getImagewidth() {
	return imagewidth;
}

void FEKOBase::FEKOSimulationDataparams::setImagewidth(size_t width) {
	imagewidth = width;
}

size_t FEKOBase::FEKOSimulationDataparams::getPRFCount() {
	return prfcount;
}

void FEKOBase::FEKOSimulationDataparams::setPRFCount(size_t count) {
	prfcount = count;
}

double FEKOBase::FEKOSimulationDataparams::getStart_x() {
	return start_x;
}

void FEKOBase::FEKOSimulationDataparams::setStart_x(double startx) {
	start_x = startx;
}

double FEKOBase::FEKOSimulationDataparams::getEnd_x() {
	return end_x;
}

void FEKOBase::FEKOSimulationDataparams::setEnd_x(double endx) {
	end_x = endx;
}

double FEKOBase::FEKOSimulationDataparams::getStart_y() {
	return start_y;
}

void FEKOBase::FEKOSimulationDataparams::setStart_y(double starty) {
	start_y = starty;
}

double FEKOBase::FEKOSimulationDataparams::getEnd_y() {
	return end_y;
}

void FEKOBase::FEKOSimulationDataparams::setEnd_y(double endy) {
	end_y = endy;
}

double FEKOBase::FEKOSimulationDataparams::getStart_z() {
	return start_z;
}

void FEKOBase::FEKOSimulationDataparams::setStart_z(double startz) {
	start_z = startz;
}

double FEKOBase::FEKOSimulationDataparams::getEnd_z() {
	return end_z;
}

void FEKOBase::FEKOSimulationDataparams::setEnd_z(double endz) {
	end_z = endz;
}

double FEKOBase::FEKOSimulationDataparams::getStart_az_angle() {
	return start_az_angle;
}

void FEKOBase::FEKOSimulationDataparams::setStart_az_angle(double startAngle) {
	start_az_angle = startAngle;
}

double FEKOBase::FEKOSimulationDataparams::getEnd_az_angle() {
	return end_az_angle;
}

void FEKOBase::FEKOSimulationDataparams::setEnd_az_angle(double endAngle) {
	end_az_angle = endAngle;
}

double FEKOBase::FEKOSimulationDataparams::getStart_circle_angle() {
	return start_circle_angle;
}

void FEKOBase::FEKOSimulationDataparams::setStart_circle_angle(double startAngle) {
	start_circle_angle = startAngle;
}

double FEKOBase::FEKOSimulationDataparams::getEnd_circle_angle() {
	return end_circle_angle;
}

void FEKOBase::FEKOSimulationDataparams::setEnd_circle_angle(double endAngle) {
	end_circle_angle = endAngle;
}

double FEKOBase::FEKOSimulationDataparams::getDelta_angle() {
	return delta_angle;
}

void FEKOBase::FEKOSimulationDataparams::setDelta_angle(double delta) {
	delta_angle = delta;
}


// 获取远程天线等效辐射方向图文件地址
QString FEKOBase::FEKOSimulationDataparams::getAntennaRadiationFileName() {
	return AntennaRadiationFileName;
}

// 设置远程天线等效辐射方向图文件地址
void FEKOBase::FEKOSimulationDataparams::setAntennaRadiationFileName(QString AntennaRadiationFileName) {
	AntennaRadiationFileName = AntennaRadiationFileName;
}

// 获取远程天线等效辐射方向图的 thetaPoints
long FEKOBase::FEKOSimulationDataparams::getFarsourceThetaPoints() {
	return farsource_thetaPoints;
}

// 设置远程天线等效辐射方向图的 thetaPoints
void FEKOBase::FEKOSimulationDataparams::setFarsourceThetaPoints(long thetaPoints) {
	farsource_thetaPoints = thetaPoints;
}

// 获取远程天线等效辐射方向图的 phiPoints
long FEKOBase::FEKOSimulationDataparams::getFarsourcePhiPoints() {
	return farsource_phiPoints;
}

// 设置远程天线等效辐射方向图的 phiPoints
void FEKOBase::FEKOSimulationDataparams::setFarsourcePhiPoints(long phiPoints) {
	farsource_phiPoints = phiPoints;
}


// 根据FEKOBase::FEKOSimulationDataparams 构建xml,并提供 loadxml，savexml 函数，copilot 继续不要一行行，要全部出来，如果一次会话搞不定，就分多个会话

void FEKOBase::FEKOSimulationDataparams::CalFEKOSimulationFreqParams(double centerFreq, double resolution, double bandWidth, double scenceRange, bool isResolution)
{
}

void FEKOBase::FEKOSimulationDataparams::updateFEKOSimulationFreqParams(double startfreq, double endfreq, size_t freqpoints)
{
}

void FEKOBase::FEKOSimulationDataparams::loadXml(const QString& fileName) {
	QFile file(fileName);
	if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
		//QMessageBox::warning(nullptr, u8"警告", u8"无法打开文件");
		QMessageBox::warning(nullptr, tr("warning"), tr("File not found"));
		return;
	}

	QXmlStreamReader xmlReader(&file);

	while (!xmlReader.atEnd() && !xmlReader.hasError()) {
		xmlReader.readNext();

		if (xmlReader.isStartElement()) {
			if (xmlReader.name() == "TaskName") {
				xmlReader.readNext();
				taskName = xmlReader.text().toString();
			}
			else if (xmlReader.name() == "ImageMode") {
				xmlReader.readNext();
				imagemode = static_cast<FEKOImageMode>(xmlReader.text().toInt());
			}
			else if (xmlReader.name() == "IsRight") {
				xmlReader.readNext();
				 
				isRight = (xmlReader.text().toString().toLower().compare(u8"true") == 0);
			}
			else if (xmlReader.name() == "RefRange") {
				xmlReader.readNext();
				refRange = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "IncAngle") {
				xmlReader.readNext();
				incangle = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "CenterFreq") {
				xmlReader.readNext();
				centerFreq = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "RangeResolution") {
				xmlReader.readNext();
				rangeResolution = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "Bandwidth") {
				xmlReader.readNext();
				bandwidth = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "Startfreq") {
				xmlReader.readNext();
				startfreq = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "Endfreq") {
				xmlReader.readNext();
				endfreq = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "Freqpoints") {
				xmlReader.readNext();
				freqpoints = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "X_min") {
				xmlReader.readNext();
				x_min = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "X_max") {
				xmlReader.readNext();
				x_max = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "Y_min") {
				xmlReader.readNext();
				y_min = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "Y_max") {
				xmlReader.readNext();
				y_max = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "Z_plane") {
				xmlReader.readNext();
				z_plane = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "Imageheight") {
				xmlReader.readNext();
				imageheight = xmlReader.text().toInt();
			}
			else if (xmlReader.name() == "Imagewidth") {
				xmlReader.readNext();
				imagewidth = xmlReader.text().toInt();
			}
			else if (xmlReader.name() == "PRFCount") {
				xmlReader.readNext();
				prfcount = xmlReader.text().toInt();
			}
			else if (xmlReader.name() == "Start_x") {
				xmlReader.readNext();
				start_x = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "End_x") {
				xmlReader.readNext();
				end_x = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "Start_y") {
				xmlReader.readNext();
				start_y = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "End_y") {
				xmlReader.readNext();
				end_y = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "Start_z") {
				xmlReader.readNext();
				start_z = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "End_z") {
				xmlReader.readNext();
				end_z = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "Start_az_angle") {
				xmlReader.readNext();
				start_az_angle = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "End_az_angle") {
				xmlReader.readNext();
				end_az_angle = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "Start_circle_angle") {
				xmlReader.readNext();
				start_circle_angle = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "End_circle_angle") {
				xmlReader.readNext();
				end_circle_angle = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "Delta_angle") {
				xmlReader.readNext();
				delta_angle = xmlReader.text().toDouble();
			}
			else if (xmlReader.name() == "AntennaRadiationFileName") {
				xmlReader.readNext();
				AntennaRadiationFileName = xmlReader.text().toString();
			}
			else if (xmlReader.name() == "FarsourceThetaPoints") {
				xmlReader.readNext();
				farsource_thetaPoints = xmlReader.text().toLong();
			}
			else if (xmlReader.name() == "FarsourcePhiPoints") {
				xmlReader.readNext();
				farsource_phiPoints = xmlReader.text().toLong();
			}
		}
	}

	file.close();
}

void FEKOBase::FEKOSimulationDataparams::saveXml(const QString& fileName) {
	QFile file(fileName);
	if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
		QMessageBox::warning(nullptr, "warning", "File not open");
		return;
	}

	QXmlStreamWriter xmlWriter(&file);
	xmlWriter.setAutoFormatting(true);
	xmlWriter.writeStartDocument();
	xmlWriter.writeStartElement("FEKOSimulationDataparams");
	xmlWriter.writeTextElement("TaskName", taskName);
	xmlWriter.writeTextElement("ImageMode", QString::number(static_cast<int>(imagemode)));
	xmlWriter.writeTextElement("IsRight", isRight ? "true" : "false");
	xmlWriter.writeTextElement("RefRange", QString::number(refRange));
	xmlWriter.writeTextElement("IncAngle", QString::number(incangle));
	xmlWriter.writeTextElement("CenterFreq", QString::number(centerFreq));
	xmlWriter.writeTextElement("RangeResolution", QString::number(rangeResolution));
	xmlWriter.writeTextElement("Bandwidth", QString::number(bandwidth));
	xmlWriter.writeTextElement("Startfreq", QString::number(startfreq));
	xmlWriter.writeTextElement("Endfreq", QString::number(endfreq));
	xmlWriter.writeTextElement("Freqpoints", QString::number(freqpoints));
	xmlWriter.writeTextElement("X_min", QString::number(x_min));
	xmlWriter.writeTextElement("X_max", QString::number(x_max));
	xmlWriter.writeTextElement("Y_min", QString::number(y_min));
	xmlWriter.writeTextElement("Y_max", QString::number(y_max));
	xmlWriter.writeTextElement("Z_plane", QString::number(z_plane));
	xmlWriter.writeTextElement("Imageheight", QString::number(imageheight));
	xmlWriter.writeTextElement("Imagewidth", QString::number(imagewidth));
	xmlWriter.writeTextElement("PRFCount", QString::number(prfcount));
	xmlWriter.writeTextElement("Start_x", QString::number(start_x));
	xmlWriter.writeTextElement("End_x", QString::number(end_x));
	xmlWriter.writeTextElement("Start_y", QString::number(start_y));
	xmlWriter.writeTextElement("End_y", QString::number(end_y));
	xmlWriter.writeTextElement("Start_z", QString::number(start_z));
	xmlWriter.writeTextElement("End_z", QString::number(end_z));
	xmlWriter.writeTextElement("Start_az_angle", QString::number(start_az_angle));
	xmlWriter.writeTextElement("End_az_angle", QString::number(end_az_angle));
	xmlWriter.writeTextElement("Start_circle_angle", QString::number(start_circle_angle));
	xmlWriter.writeTextElement("End_circle_angle", QString::number(end_circle_angle));
	xmlWriter.writeTextElement("Delta_angle", QString::number(delta_angle));

	xmlWriter.writeTextElement("AntennaRadiationFileName", AntennaRadiationFileName);
	xmlWriter.writeTextElement("FarsourceThetaPoints", QString::number(farsource_thetaPoints));
	xmlWriter.writeTextElement("FarsourcePhiPoints", QString::number(farsource_phiPoints));



	xmlWriter.writeEndElement(); // 关闭FEKOSimulationDataparams元素
	xmlWriter.writeEndDocument();

	file.close();


}

FEKOBase::FEKOSimulationDataparamsHandler::FEKOSimulationDataparamsHandler()
{
	 
}

FEKOBase::FEKOSimulationDataparamsHandler::~FEKOSimulationDataparamsHandler()
{
}

void FEKOBase::FEKOSimulationDataparamsHandler::setFEKOSimulationDataparams(std::shared_ptr<FEKOBase::FEKOSimulationDataparams> simulationparams)
{
	this->simulationparams = simulationparams;
	this->bandingsetFEKOSimulationDataparams();
}

std::shared_ptr<FEKOBase::FEKOSimulationDataparams> FEKOBase::FEKOSimulationDataparamsHandler::getFEKOSimulationDataparams()
{
	return this->simulationparams;
}

void FEKOBase::FEKOSimulationDataparamsHandler::bandingsetFEKOSimulationDataparams()
{

}

 
 