#include "OCCTBase.h"
#include "referenceHeader.h"
#include <opencascade\BRepPrimAPI_MakeBox.hxx>


// ===================================================================
// 常用函数方法
// ===================================================================


OCCTShapeType str2OCCTShapeType(QString str)
{
	if (str.isEmpty()) {
		return OCCTShapeType::NoneType;
	}
	else if (str.toUpper() == "STL") {
		return OCCTShapeType::STL;
	}
	else if (str.toUpper() == "STEP") {
		return OCCTShapeType::STEP;
	}
	else if (str.toUpper() == "IGES") {
		return OCCTShapeType::IGES;
	}
	else {
		return OCCTShapeType::NoneType;
	}
	return OCCTShapeType();
}

QStringList getOCCTShapeTypeEmnu()
{
	QStringList list;
	list.push_back(QString(u8"STL"));
	list.push_back(QString(u8"STEP"));
	list.push_back(QString(u8"IGES"));

	return list;
}

QString getOCCTShapeTypeFilterString()
{
	return QString(u8"STL Files (*.stl);;STL Files (*.stla);;step Files (*.stp);;step Files (*.step);;IGES Files (*.iges);;IGES Files (*.igs)");
}

QString get_STL_FilterString()
{
	return QString(u8"STL Files (*.stl);;STL Files (*.stla)");
}

QString get_STEP_FilterString()
{
	return QString(u8"step Files (*.stp);;step Files (*.step)");
}

QString get_IGES_FilterString()
{
	return QString(u8"IGES Files (*.iges);;IGES Files (*.igs)");
}

QString getOCCTShapeTypeFilterString(OCCTShapeType switch_on)
{
	switch (switch_on)
	{
	case(OCCTShapeType::STL): {return  get_STL_FilterString(); }
	case(OCCTShapeType::STEP): {return  get_STEP_FilterString(); }
	case(OCCTShapeType::IGES): {return  get_IGES_FilterString(); }

	default:
		return getOCCTShapeTypeFilterString();
	}
}

QString getOCCTShapeTypeFilterString(QString str)
{
	return getOCCTShapeTypeFilterString(str2OCCTShapeType(str));
}

bool SaveTopoDs_Stl(QString FilePath, const  TopoDS_Shape& shape) {
	// 将形状保存为 STL 文件
	qDebug() << u8"SaveTopoDs_Stl " << FilePath;
	StlAPI_Writer writer;
	writer.Write(shape, FilePath.toStdString().c_str()); // 保存为stl模型
	return true;
}
bool SaveTopoDs_Step(QString FilePath, const  TopoDS_Shape& shape) {
	qDebug() << u8"SaveTopoDs_Step " << FilePath;
	STEPControl_Writer writer;
	writer.Transfer(shape, STEPControl_AsIs);
	writer.Write(FilePath.toStdString().c_str());
	return true;
}
bool SaveTopoDs_IGES(QString FilePath,const TopoDS_Shape& shape) {
	qDebug() << u8"SaveTopoDs_IGES " << FilePath;
	IGESControl_Writer writer;
	writer.AddShape(shape);
	writer.Write(FilePath.toStdString().c_str());
	return true;
}

bool SaveTopoDs(QString FilePath,const  TopoDS_Shape& DataShape, OCCTShapeType shapetype)
{
	switch (shapetype)
	{
	case(OCCTShapeType::STL): { // 保存为stl

		SaveTopoDs_Stl(FilePath, DataShape);
		break;
	}
	case(OCCTShapeType::STEP): {
		SaveTopoDs_Step(FilePath, DataShape);
		break;
	}
	case(OCCTShapeType::IGES): {

		SaveTopoDs_IGES(FilePath, DataShape);
		break;
	}

	default:
		break;
	}


	return true;
}

TopoDS_Shape ReadTopoDs_IGES(QString Filepath) {
	IGESControl_Reader reader;
	reader.ReadFile(Filepath.toStdString().c_str());
	reader.TransferRoots();
	TopoDS_Shape shape = reader.OneShape();
	return shape;
}
TopoDS_Shape ReadTopoDs_Stl(QString Filepath) {
	TopoDS_Shape shape_TopoDs;
	StlAPI_Reader aReader_Stl;
	aReader_Stl.Read(shape_TopoDs, Filepath.toStdString().c_str());
	return shape_TopoDs;
}
TopoDS_Shape ReadTopoDs_Step(QString Filepath) {
	TopoDS_Shape shape;
	STEPControl_Reader reader;
	IFSelect_ReturnStatus status = reader.ReadFile(Filepath.toStdString().c_str());
	if (status == IFSelect_RetDone) {
		reader.TransferRoots();
		shape = reader.OneShape();
		return shape;
	}
	else {
		return shape;
	}
}

OCCTShapeType ReadTopoDs_Shape(QString filepath, TopoDS_Shape& shape_TopoDs)
{
	QFileInfo fileinfo(filepath);
	QString filename = fileinfo.fileName();
	QString fileSuffix = fileinfo.suffix();
	OCCTShapeType shapetype;
	if (fileSuffix.compare(u8"stl") == 0 || fileSuffix.compare(u8"stla") == 0) {
		shapetype = OCCTShapeType::STL;
		shape_TopoDs = ReadTopoDs_Stl(filepath);
		return shapetype;
	}
	else if (fileSuffix.compare(u8"step") == 0 || fileSuffix.compare(u8"stp") == 0) {
		shapetype = OCCTShapeType::STEP;
		shape_TopoDs = ReadTopoDs_Step(filepath);
		return shapetype;
	}
	else if (fileSuffix.compare(u8"iges") == 0 || fileSuffix.compare(u8"igs") == 0) {
		shapetype = OCCTShapeType::IGES;
		shape_TopoDs = ReadTopoDs_IGES(filepath);
		return shapetype;
	}
	else {
		qDebug() << QString(u8"=================open Model ====================\n");
		qDebug() << QString(u8"don't open model\n");
		qDebug() << filepath;
		qDebug() << QString(u8"=====================================\n");
		return OCCTShapeType::NoneType;
	}
}

TopoDS_Shape MergedTopoShape(std::vector<TopoDS_Shape> TopoDS_Shapelist)
{
	// 创建一个复合体
	TopoDS_Compound compound;
	BRep_Builder builder;
	builder.MakeCompound(compound);

	// 将所有的形状添加到复合体中
	for (const TopoDS_Shape& shape : TopoDS_Shapelist) {
		builder.Add(compound, shape);
	}

	// 返回合并后的复合体
	return compound;

}

void ChangeModelColor(Handle(AIS_Shape)& aisShape, Quantity_Color& redColor)
{

	// 将颜色应用到模型
	aisShape->SetColor(redColor);
}



TopoDS_Shape CreateArrow(const gp_Dir& direction, Standard_Real length, Standard_Real radius) {
	// 创建一个圆柱作为箭头的主体
	gp_Pnt origin(0, 0, 0);
	gp_Ax2 axis(origin, direction);
	BRepPrimAPI_MakeCylinder cylinder(axis, radius, length - radius * 2);

	// 创建一个圆锥作为箭头的尖端
	gp_Pnt tip = origin.Translated(length * gp_Vec(direction));
	gp_Ax2 coneAxis(tip, direction);
	BRepPrimAPI_MakeCone cone(coneAxis, radius * 2, 0, radius * 2);

	// 合并圆柱和圆锥
	TopoDS_Compound compound;
	BRep_Builder builder;
	builder.MakeCompound(compound);
	builder.Add(compound, cylinder.Shape());
	builder.Add(compound, cone.Shape());

	return compound;

}

gp_Trsf GetTransFormFromVector(const gp_Vec& vectorA, const gp_Vec& vectorB)
{
	// 计算旋转轴和旋转角度
	gp_Vec rotationAxis = vectorA.Crossed(vectorB);
	Standard_Real rotationAngle = vectorA.Angle(vectorB);
	if (rotationAxis.X() != 0 || rotationAxis.Y() != 0 || rotationAxis.Z() != 0) {
		// 创建变换，绕旋转轴旋转指定角度
		gp_Trsf transformation;
		transformation.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), rotationAxis), rotationAngle);
		return transformation;
	}
	else {
		// 创建变换，绕旋转轴旋转指定角度
		gp_Trsf transformation;
		transformation.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Vec(0, 0, 1)), 0);
		return transformation;
	}

}

TopoDS_Shape Process_RotationThetaPhi_MoveXYZ(TopoDS_Shape shape, double theta, double phi, double X, double Y, double Z)
{
	gp_Vec  Position(gp_Pnt(0, 0, 0), gp_Pnt(X, Y, Z));
	gp_Trsf rotationTransform_theta;
	rotationTransform_theta.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 1, 0)), theta);  // 绕 y 轴旋转
	gp_Trsf rotationTransform_phi;
	rotationTransform_phi.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)), phi);  // 绕 z 轴旋转
	gp_Trsf moveTransform_xyz;
	moveTransform_xyz.SetTranslation(Position);

	BRepBuilderAPI_Transform shapeTransform_theta(shape, rotationTransform_theta);
	TopoDS_Shape tempShape_theta = shapeTransform_theta.Shape();
	BRepBuilderAPI_Transform shapeTransform_phi(tempShape_theta, rotationTransform_phi);
	TopoDS_Shape tempShape_phi = shapeTransform_phi.Shape();
	BRepBuilderAPI_Transform shapeTransform_move(tempShape_phi, moveTransform_xyz);
	TopoDS_Shape result = shapeTransform_move.Shape();

	return result;
}

TopoDS_Shape CreateCartesianCoordinatesAxis(double xlength, double ylength, double zlength)
{
 
	// 创建三个方向的箭头
	TopoDS_Shape arrow1 = CreateArrow(gp_Dir(1, 0, 0), xlength, xlength*0.05); // X方向 
	TopoDS_Shape arrow2 = CreateArrow(gp_Dir(0, 1, 0), ylength, ylength*0.05); // Y方向
	TopoDS_Shape arrow3 = CreateArrow(gp_Dir(0, 0, 1), zlength, zlength*0.05); // Z方向

	// 创建雷达模型

	gp_Ax2 modelCoor = gp_Ax2(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1), gp_Dir(1, 0, 0));

 
	// 创建一个包含所有箭头的复合体
	TopoDS_Compound compound;
	BRep_Builder builder;


	builder.MakeCompound(compound);
	builder.Add(compound, arrow1);
	builder.Add(compound, arrow2);
	builder.Add(compound, arrow3);

	return compound;
}

TopoDS_Shape CreateBox(double x, double y, double z)
{
	// 创建一个长方体
	BRepPrimAPI_MakeBox box(gp_Pnt(-x / 2, -y / 2, -z / 2), gp_Pnt(x / 2, y / 2, z / 2));
	return box.Shape();
}

TopoDS_Shape CreateCylinder(double radius, double height)
{
	BRepPrimAPI_MakeCylinder makeCylinder(radius, height);
	TopoDS_Shape cylinderShape = makeCylinder.Shape();
	return cylinderShape;
}

TopoDS_Shape CreateCone(double radius1, double radius2, double height)
{
	BRepPrimAPI_MakeCone mkCone = BRepPrimAPI_MakeCone::BRepPrimAPI_MakeCone(radius1, radius2, height);
	TopoDS_Shape coneShape = mkCone.Shape();

	return coneShape;
}

TopoDS_Shape CreateSphere(double radius)
{
	return TopoDS_Shape();
}

TopoDS_Shape CreateTorus(double majorRadius, double minorRadius)
{
	return TopoDS_Shape();
}

TopoDS_Shape Cut(TopoDS_Shape& shape1, TopoDS_Shape& shape2)
{

	return TopoDS_Shape();
}

TopoDS_Shape Fuse(TopoDS_Shape& shape1, TopoDS_Shape& shape2)
{

	return TopoDS_Shape();
}

TopoDS_Shape Rotate(TopoDS_Shape& shape, gp_Ax1 axis, double angle)
{
	// 进行旋转
	angle= angle * M_PI / 180;
	gp_Trsf rotation;
	rotation.SetRotation(axis, angle); // X
	BRepBuilderAPI_Transform rotateTransform_X(shape, rotation);
	return rotateTransform_X.Shape();
}

TopoDS_Shape Translate(TopoDS_Shape& shape, gp_Vec move_vec)
{
	gp_Trsf translation;
	translation.SetTranslation(move_vec);
	BRepBuilderAPI_Transform translateTransform(shape, translation);
	return translateTransform.Shape();
}

TopoDS_Shape Scale(TopoDS_Shape& shape, gp_Pnt refrenceCenter, double scale)
{
	gp_Trsf scaleTransform;
	scaleTransform.SetScale(refrenceCenter, scale);
	BRepBuilderAPI_Transform scaleTransformBuilder(shape, scaleTransform);
	return scaleTransformBuilder.Shape();
}

TopoDS_Shape createConicalHorn(double bottomRadius, double bottomHeight, double topRadius, double topHeight)
{

	BRepPrimAPI_MakeCone mkCone = BRepPrimAPI_MakeCone::BRepPrimAPI_MakeCone(bottomRadius,topRadius,topHeight);
	TopoDS_Shape coneShape = mkCone.Shape();

	// 整体平移
	gp_Vec trans_vec(gp_Pnt(0, 0, 0), gp_Pnt(0, 0, bottomHeight));
	gp_Trsf move_trsf;
	move_trsf.SetTranslation(trans_vec);
	BRepBuilderAPI_Transform shapeTransform_move(coneShape, move_trsf); 	//  fly_Z --> incidenceAngle
	TopoDS_Shape   tempShape = shapeTransform_move.Shape(); // 平移卫星模型	


	BRepPrimAPI_MakeCylinder makeCylinder(bottomRadius, bottomHeight);
	TopoDS_Shape cylinderShape = makeCylinder.Shape();

	// 创建一个包含所有箭头的复合体
	TopoDS_Compound compound;
	BRep_Builder builder;

	builder.MakeCompound(compound);
	builder.Add(compound, tempShape);
	builder.Add(compound, cylinderShape);

	return compound;
}

TopoDS_Shape createPyramidalHorn(double bottomWidth, double bottomHeight, double bottomAtl, double topWidth, double topHeight, double topAtl)
{



	return TopoDS_Shape();
}

 TopoDS_Shape CreateWedge(double x, double y, double z)
{




	return TopoDS_Shape();
}
