#pragma once
/*****************************************************************//**
 * \file   SatelliteOribtModel.h
 * \brief  轨道模型
 * 
 * \author 陈增辉
 * \date   October 2024
 *********************************************************************/
#include "LogInfoCls.h"
#include "BaseConstVariable.h"
#include "SARSatelliteSimulationAbstractCls.h"
#include <vector>
#include <memory>
#include <QFile>
#include <QXmlStreamWriter>


/// <summary>
/// 多项式轨道模型
/// </summary>
class PolyfitSatelliteOribtModel:public AbstractSatelliteOribtModel
{
public:
	PolyfitSatelliteOribtModel();
	~PolyfitSatelliteOribtModel() override;

	void saveToXml(const QString& filePath) ;
	bool loadFromXml(const QString& filePath);
	void readVector(QXmlStreamReader& xmlReader, const QString& name, std::vector<double>& vec);
	void writeVector(QXmlStreamWriter& xmlWriter, const QString& name, const std::vector<double>& vec);

public:
	QString getSatelliteOribtModelParamsString();

public: // 卫星轨道节点
	virtual SatelliteOribtNode getSatelliteOribtNode(double& timeFromStartTime, bool& antAzAngleFlag) override; // 获取轨道节点
	virtual ErrorCode getSatelliteOribtNode(double& timeFromStartTime, SatelliteOribtNode& node, bool& antAzAngleFlag) override; // 获取轨道节点
	virtual ErrorCode getSatelliteAntDirectNormal(SatelliteOribtNode& Rs, Vector3D& Rt, SatelliteAntDirect& antNode); // 计算目标在天线方向图中的位置
public: // 卫星轨道模型的参考时间节点
	virtual void setSatelliteOribtStartTime(long double oribtStartTime) override;// 设置卫星模型参考时间
	virtual long double  getSatelliteOribtStartTime() override;// 获取卫星模型参考时间
public: // 入射角相关参数
	virtual void setbeamAngle(double beamAngle, bool RightLook) override;// 设置波位角

public: // 天线摆动角相关参数
	virtual void setAzAngleRange(double cycletime, double minAzAngle, double maxAzAngle, double referenceAzAngle, double referenceTimeFromStartTime) override;//方位角变换循环时间 ;方位角变换范围； 特定时间的方位角，用于计算方位角变化情况
	
	virtual double getAzAngleInCurrentTimeFromStartTime(double& currentTime) override;// 获取当前时间的 天线摆动角
	virtual ErrorCode getAzAngleInCurrentTimeFromStartTime(double& currentTime, double& AzAngle);// 获取当前时间的 天线摆动角

public: // 定义在原始天线坐标下的天线坐标系的调整，其中仍然定义-Z 轴为 天线指向方向
	virtual void setAntnnaAxisX(double X, double Y, double Z) override; // 设置天线X轴指向
	virtual void setAntnnaAxisY(double X, double Y, double Z) override; // 设置天线X轴指向
	virtual void setAntnnaAxisZ(double X, double Y, double Z) override; // 设置天线X轴指向
	
	virtual ErrorCode getAntnnaDirection(SatelliteOribtNode& node) override; // 获取天线指向方向
	virtual ErrorCode getZeroDopplerAntDirect(SatelliteOribtNode& node) override;
private: // 变量
	
	double beamAngle; // 波位角
	bool RightLook; // 左右视
	double cycletime; // 方位角变换循环时间
	double minAzAngle; // 方位角变换范围
	double maxAzAngle; // 方位角变换范围
	double referenceAzAngle; // 特定时间的方位角，用于计算方位角变化情况
	double referenceTimeFromStartTime; // 特定时间的方位角，用于计算方位角变化情况

	Point3 AntnnaAxisX; // 天线X轴指向
	Point3 AntnnaAxisY; // 天线Y轴指向
	Point3 AntnnaAxisZ; // 天线Z轴指向

private: // 轨道模型
	std::vector<SatelliteOribtNode> oribtNodes;

	long double oribtStartTime; // 卫星模型参考时间
	std::vector<double> polyfitPx; // 空间坐标
	std::vector<double> polyfitPy;
	std::vector<double> polyfitPz;
	std::vector<double> polyfitVx; // 速度拟合参数
	std::vector<double> polyfitVy;
	std::vector<double> polyfitVz;

	double Pxchisq; // 拟合误差 X2
	double Pychisq;
	double Pzchisq;
	double Vxchisq;
	double Vychisq;
	double Vzchisq;
private:
	double Pt; // 发射电压
	double Gri;// 系统增益

public:
	long double			getOribtStartTime(); // 卫星模型参考时间
	std::vector<double> getPolyfitPx(); // 空间坐标
	std::vector<double> getPolyfitPy();
	std::vector<double> getPolyfitPz();
	std::vector<double> getPolyfitVx(); // 速度拟合参数
	std::vector<double> getPolyfitVy();
	std::vector<double> getPolyfitVz();



public: // 增加节点
	void addOribtNode(SatelliteOribtNode node);
	ErrorCode polyFit(int polynum = 3, bool input_timeFromReferenceTime = false);

 
public:
	virtual double getPt() override;
	virtual double getGri() override;
	virtual void setPt(double Pt) override;
	virtual void setGri(double gri) override;

	//virtual double getPt();
	//virtual double getGri();
	//virtual void setPt(double Pt);
	//virtual void setGri(double gri);





};

std::shared_ptr<AbstractSatelliteOribtModel>   CreataPolyfitSatelliteOribtModel(std::vector<SatelliteOribtNode> &nodes, long double startTime,int polynum=3);







