#pragma once
#ifndef BASETOOL_H
#define BASETOOL_H
#include "BaseConstVariable.h"

///
/// 基本类、基本函数
///


// //#include <mkl.h>
#include <complex>
#include <iostream>
#include <Eigen/Core>
#include <Eigen/Dense>
#include <time.h>
#include <string>
#include <omp.h>
#include <gdal.h>
#include <gdal_priv.h>
#include <gdalwarper.h>
#include <ogrsf_frmts.h>
#include <fstream>
#include "GeoOperator.h"
#include <vector>
#include <string>
#include <QString>
#include <QStringList>
#include "LogInfoCls.h"
#include <QString>
#include <QDebug>
#include <iomanip>
#include <sstream>


///////////////////////////////////// 基础数学函数 /////////////////////////////////////////////////////////////


QString longDoubleToQStringScientific(long double value);

///////////////////////////////////// 运行时间打印 /////////////////////////////////////////////////////////////


QString BASECONSTVARIABLEAPI			 getCurrentTimeString();
QString BASECONSTVARIABLEAPI			 getCurrentShortTimeString();

std::vector<QString>   BASECONSTVARIABLEAPI	splitString(const QString& str, char delimiter);
std::vector<QString>   BASECONSTVARIABLEAPI	 convertQStringListToStdVector(const QStringList& qStringList);
///////////////////////////////  基本图像类 结束
/////////////////////////////////////////////////////////////

std::string 		 BASECONSTVARIABLEAPI		 Convert(float Num);
QString 			  BASECONSTVARIABLEAPI	JoinPath(const QString& path, const QString& filename);

////////////////////////////// 坐标部分基本方法 //////////////////////////////////////////

////////////////////////////// 坐标部分基本方法 //////////////////////////////////////////

//////////////////////////////  插值   ////////////////////////////////////////////

std::complex<double>  BASECONSTVARIABLEAPI		 Cubic_Convolution_interpolation(double u, double v,
															 Eigen::MatrixX<std::complex<double>> img);

std::complex<double>  BASECONSTVARIABLEAPI		 Cubic_kernel_weight(double s);

double  BASECONSTVARIABLEAPI	 Bilinear_interpolation(Landpoint p0, Landpoint p11, Landpoint p21, Landpoint p12,Landpoint p22);

bool  BASECONSTVARIABLEAPI	 onSegment(Point3 Pi, Point3 Pj, Point3 Q);

Point3  BASECONSTVARIABLEAPI	 invBilinear(Point3 p, Point3 a, Point3 b, Point3 c, Point3 d);

//
// WGS84 到J2000 坐标系的变换
// 参考网址：https://blog.csdn.net/hit5067/article/details/116894616
// 资料网址：http://celestrak.org/spacedata/
// 参数文件：
//		 a. Earth Orientation Parameter 文件： http://celestrak.org/spacedata/EOP-Last5Years.csv
//       b. Space Weather Data  文件： http://celestrak.org/spacedata/SW-Last5Years.csv
// 备注：上述文件是自2017年-五年内
/**
在wgs84 坐标系转到J2000 坐标系 主要 涉及到坐标的相互转换。一般给定的WGS坐标为 给定时刻的 t ,BLH
转换步骤：
step 1: WGS 84 转换到协议地球坐标系
step 2: 协议地球坐标系 转换为瞬时地球坐标系
step 3: 瞬时地球坐标系 转换为 瞬时真天球坐标系
step 4: 瞬时真天球坐标系 转到瞬时平天球 坐标系
step 5: 瞬时平天球坐标系转换为协议天球坐标系（J2000）
**/

double  BASECONSTVARIABLEAPI	 sind(double degree);

double  BASECONSTVARIABLEAPI	 cosd(double d);

// 插值
ErrorCode  BASECONSTVARIABLEAPI	polyfit(const double* x, const double* y, int xyLength, int poly_n, std::vector<double>& out_factor, double& out_chisq);

// 叉乘
Point3  BASECONSTVARIABLEAPI	crossProduct(const Point3& a, const Point3& b);

Eigen::Matrix3d BASECONSTVARIABLEAPI	 rotationMatrix(const Eigen::Vector3d& axis, double angle);
 
long double  BASECONSTVARIABLEAPI	convertToMilliseconds(const std::string& dateTimeStr);


/// <summary>
/// list 应该是按照从小到大的顺序排好
/// </summary>
/// <param name="list"></param>
/// <param name="findv"></param>
/// <returns></returns>
long  BASECONSTVARIABLEAPI	FindValueInStdVector(std::vector<double>& list,double& findv);

long  BASECONSTVARIABLEAPI	InsertValueInStdVector(std::vector<double>& list, double insertValue, bool repeatValueInsert = false);

long  BASECONSTVARIABLEAPI	FindValueInStdVectorLast(std::vector<double>& list, double& findv);

ErrorCode  BASECONSTVARIABLEAPI	polynomial_fit(const std::vector<double>& x, const std::vector<double>& y, int degree, std::vector<double>& out_factor, double& out_chisq);

QVector<SatelliteAntPos>  BASECONSTVARIABLEAPI	SatellitePos2SatelliteAntPos(QVector<SatellitePos> poses);

QVector<SatellitePos> BASECONSTVARIABLEAPI	 SatelliteAntPos2SatellitePos(QVector<SatelliteAntPos> poses);

QString  BASECONSTVARIABLEAPI	getDebugDataPath(QString filename);
std::vector<std::string>  BASECONSTVARIABLEAPI	split(const std::string& str, char delimiter);
Eigen::VectorXd BASECONSTVARIABLEAPI	 linspace(double start, double stop, int num);


/** 内存赋值 ***********************************************************************************************************/
void initializeMatrixWithSSE2(Eigen::MatrixXd& mat, const double* data, long rowcount, long colcount);
void initializeMatrixWithSSE2(Eigen::MatrixXf& mat, const float* data, long rowcount, long colcount);


/** 模板函数类 ***********************************************************************************************************/
template<typename T>
inline void BASECONSTVARIABLEAPI memsetInitArray(std::shared_ptr<T> ptr, long arrcount,T ti) {
	for (long i = 0; i < arrcount; i++) {
		ptr.get()[i] = ti;
	}
}

template<typename T>
inline void BASECONSTVARIABLEAPI memcpyArray(std::shared_ptr<T> srct, std::shared_ptr<T> dest, long arrcount) {
	for (long i = 0; i < arrcount; i++) {
		dest.get()[i] = srct.get()[i];
	}
}






#endif