#include "OCCTModelOperator.h"
#include <opencascade/BRepBuilderAPI_Transform.hxx>
#include <opencascade/Bnd_Box.hxx>
#include <opencascade/BRepBndLib.hxx>


OCCTModelOperator::OCCTModelOperator(QString TopoName,QWidget *parent, Handle(AIS_InteractiveContext) myContext)
	: QDialog(parent)
{
	ui.setupUi(this);
	setWindowFlags(Qt::Window);
	setWindowTitle(TopoName);
	// 参数初设
	this->ui.radioButton_NoCopy->setChecked(true);
	this->ui.radioButton_Time->setChecked(true);
	this->myContext = myContext;
	this->ModelName = TopoName;
	// 处理平移

	QDoubleValidator* validator = new QDoubleValidator(); // 限制参数
	ui.lineEdit_Move_From_X->setValidator(validator);
	ui.lineEdit_Move_From_Z->setValidator(validator);
	ui.lineEdit_Move_From_Y->setValidator(validator);
	ui.lineEdit_Move_To_X->setValidator(validator);
	ui.lineEdit_Move_To_Y->setValidator(validator);
	ui.lineEdit_Move_To_Z->setValidator(validator);
	ui.lineEdit_Rotation_Center_X->setValidator(validator);
	ui.lineEdit_Rotation_Center_Y->setValidator(validator);
	ui.lineEdit_Rotation_Center_Z->setValidator(validator);
	ui.lineEdit_Rotation_Axis_X->setValidator(validator);
	ui.lineEdit_Rotation_Axis_Y->setValidator(validator);
	ui.lineEdit_Rotation_Axis_Z->setValidator(validator);

	ui.lineEdit_Scale_refrence_point_X->setValidator(validator);
	ui.lineEdit_Scale_refrence_point_Y->setValidator(validator);
	ui.lineEdit_Scale_refrence_point_Z->setValidator(validator);

	QDoubleValidator* validatorScale = new QDoubleValidator();
	validatorScale->setBottom(0.0);
	ui.lineEdit_ScaleValue->setValidator(validatorScale);

	// 初始化
	ui.lineEdit_Move_From_X->setText(u8"0.0");
	ui.lineEdit_Move_From_Z->setText(u8"0.0");
	ui.lineEdit_Move_From_Y->setText(u8"0.0");
	ui.lineEdit_Move_To_X->setText(u8"0.0");
	ui.lineEdit_Move_To_Y->setText(u8"0.0");
	ui.lineEdit_Move_To_Z->setText(u8"0.0");
	ui.lineEdit_Rotation_Center_X->setText(u8"0.0");
	ui.lineEdit_Rotation_Center_Y->setText(u8"0.0");
	ui.lineEdit_Rotation_Center_Z->setText(u8"0.0");
	ui.lineEdit_Rotation_Axis_X->setText(u8"0.0");
	ui.lineEdit_Rotation_Axis_Y->setText(u8"0.0");
	ui.lineEdit_Rotation_Axis_Z->setText(u8"0.0");
	ui.lineEdit_ScaleValue->setText(u8"1.0");
	ui.lineEdit_Scale_refrence_point_X->setText(u8"0.0");
	ui.lineEdit_Scale_refrence_point_Y->setText(u8"0.0");
	ui.lineEdit_Scale_refrence_point_Z->setText(u8"0.0");
	// 缩放中心参数化
	ui.radioButton_Auto->setChecked(true);
	// 参数初始化
	this->UpdataVariable();
	// 事件绑定

	if (TopoName.isEmpty()) {
		this->ui.radioButton_Copy->setChecked(true);
		this->ui.radioButton_NoCopy->setEnabled(false); 
	}

}

OCCTModelOperator::~OCCTModelOperator()
{}

void OCCTModelOperator::setTopoDs_Shape(TopoDS_Shape ds)
{
	// 创建一个复制模型
	BRepBuilderAPI_Copy copyBuilder;
	copyBuilder.Perform(ds);
	this->Datashape = copyBuilder.Shape();

	// 创建一个复制模型
	BRepBuilderAPI_Copy copyBuilder2;
	copyBuilder2.Perform(ds);
	this->DataShapeBAK = copyBuilder2.Shape();

	this->Data_AIS = new AIS_Shape(this->Datashape); // 计算
	
	this->UpdateScaleRefrencepoint();
	this->UpdataVariable();

}

TopoDS_Shape OCCTModelOperator::getTopoDs_Shape()
{
	return this->Datashape;
}

TopoDS_Shape OCCTModelOperator::getTopoDs_ShapeBAK()
{
	return this->DataShapeBAK;
}

void OCCTModelOperator::toString()
{
	qDebug() << u8"move ";
	qDebug() <<QString("X: %1 --> %1").arg(Move_From_X, 0, 'e', 8).arg(Move_To_X, 0, 'e', 8);
	qDebug() <<QString("Y: %1 --> %1").arg(Move_From_Y, 0, 'e', 8).arg(Move_To_Y, 0, 'e', 8);
	qDebug() <<QString("Z: %1 --> %1").arg(Move_From_Z, 0, 'e', 8).arg(Move_To_Z, 0, 'e', 8);
	qDebug() << u8"Rotatino Center Point  ";
	qDebug() <<QString("X: %1").arg(Rotation_Center_X);
	qDebug() <<QString("Y: %1").arg(Rotation_Center_Y);
	qDebug() <<QString("Z: %1").arg(Rotation_Center_Z);
	qDebug() << u8"Rotatino Axis Angle  ";
	qDebug() <<QString("%1").arg(Rotation_angle_X); // 绕X轴旋转角度
	qDebug() <<QString("%1").arg(Rotation_angle_Y);
	qDebug() <<QString("%1").arg(Rotation_angle_Z);
	qDebug() << u8"Scale  ";
	qDebug() <<QString("%1").arg(ScaleDouble);
	qDebug() <<QString("X%1").arg(this->ScaleRefrencePoint_X);
	qDebug() <<QString("Y%1").arg(this->ScaleRefrencePoint_Y);
	qDebug() <<QString("Z%1").arg(this->ScaleRefrencePoint_Z);
}

Handle(AIS_InteractiveObject) OCCTModelOperator::getAIS()
{
	return new AIS_Shape(this->Datashape);
}

Handle(AIS_InteractiveObject)  OCCTModelOperator::getAISBAK()
{
	return new AIS_Shape(this->DataShapeBAK);
}

void OCCTModelOperator::ExcuteOperator()
{
	this->ProcesssModel();
	if (this->ui.radioButton_Copy->isChecked()) { // 复制模型
		emit this->ResultExportCopyAndCreateNew(this);
	}
	else {
		emit this->ResultExport(this);
	}


}

void OCCTModelOperator::UpdataVariable()
{
	this->Move_From_X = this->ui.lineEdit_Move_From_X->text().toDouble();
	this->Move_From_Z = this->ui.lineEdit_Move_From_Z->text().toDouble();
	this->Move_From_Y = this->ui.lineEdit_Move_From_Y->text().toDouble();
	this->Move_To_X = this->ui.lineEdit_Move_To_X->text().toDouble();
	this->Move_To_Y = this->ui.lineEdit_Move_To_Y->text().toDouble();
	this->Move_To_Z = this->ui.lineEdit_Move_To_Z->text().toDouble();
	this->Rotation_Center_X = this->ui.lineEdit_Rotation_Center_X->text().toDouble();
	this->Rotation_Center_Y = this->ui.lineEdit_Rotation_Center_Y->text().toDouble();
	this->Rotation_Center_Z = this->ui.lineEdit_Rotation_Center_Z->text().toDouble();
	this->Rotation_angle_X = this->ui.lineEdit_Rotation_Axis_X->text().toDouble();
	this->Rotation_angle_Y = this->ui.lineEdit_Rotation_Axis_Y->text().toDouble();
	this->ScaleDouble = this->ui.lineEdit_ScaleValue->text().toDouble();

	this->ScaleRefrencePoint_X=this->ui.lineEdit_Scale_refrence_point_X->text().toDouble();
	this->ScaleRefrencePoint_Y=this->ui.lineEdit_Scale_refrence_point_Y->text().toDouble();
	this->ScaleRefrencePoint_Z=this->ui.lineEdit_Scale_refrence_point_Z->text().toDouble();
}

void OCCTModelOperator::UpdateScaleRefrencepoint()
{
	if (this->ui.radioButton_Auto->isChecked()) {
		// 假设你有一个 TopoDS_Shape 对象，例如一个立方体
		TopoDS_Shape myShape = this->DataShapeBAK; // 你需要将其替换为实际的形状对象
		GProp_GProps volumeProperties;

		// 计算几何特性
		BRepGProp::VolumeProperties(myShape, volumeProperties, Standard_False, Standard_False, Standard_False);

		//// 获取质心
		gp_Pnt centerOfMass = volumeProperties.CentreOfMass();

		this->ui.lineEdit_Scale_refrence_point_X->setText(QString("%1").arg(centerOfMass.X(), 0, 'e', 8));
		this->ui.lineEdit_Scale_refrence_point_Y->setText(QString("%1").arg(centerOfMass.Y(), 0, 'e', 8));
		this->ui.lineEdit_Scale_refrence_point_Z->setText(QString("%1").arg(centerOfMass.Z(), 0, 'e', 8));
	}
}

void OCCTModelOperator::PreViewOperator()
{
	this->UpdataVariable();
	this->toString();

	if (this->ui.radioButton_Time->isChecked()) {
		this->ProcesssModel();
	}
}

void OCCTModelOperator::ApplyModel()
{
	
	if (this->myContext) {
		qDebug() << u8"模型移除";
		
		//this->myContext->Erase(this->Data_AIS, Standard_True);
		this->myContext->Remove(this->Data_AIS, Standard_False);
		this->myContext->UpdateCurrentViewer();
		this->Datashape.Nullify();
		//this->Data_AIS->Delete();
		//this->myContext->Remove(this->Datashape, Standard_True);
	}

	// 平移模型
	double move_x = this->Move_To_X - this->Move_From_X;
	double move_y = this->Move_To_Y - this->Move_From_Y;
	double move_z = this->Move_To_Z - this->Move_From_Z;

	// 进行平移
	gp_Trsf translation;
	translation.SetTranslation(gp_Vec(move_x, move_y, move_z));
	BRepBuilderAPI_Transform translateTransform(this->DataShapeBAK, translation);
 
	TopoDS_Shape translatedShape = translateTransform.Shape();

	double Rotation_centor_x = this->Rotation_Center_X;
	double Rotation_centor_y = this->Rotation_Center_Y;
	double Rotation_centor_z = this->Rotation_Center_Z;
	// 确定旋转中心
	gp_Pnt rotationCenter(Rotation_centor_x, Rotation_centor_y, Rotation_centor_z);  // 中心点坐标
	// 计算旋转轴
	gp_Ax1 rotationAxis_X(rotationCenter, gp_Dir(1.0, 0.0, 0.0));
	gp_Ax1 rotationAxis_Y(rotationCenter, gp_Dir(0.0, 1.0, 0.0));
	gp_Ax1 rotationAxis_Z(rotationCenter, gp_Dir(0.0, 0.0, 1.0));

	double angle_x = this->Rotation_angle_X / 180.0 * M_PI;
	double angle_y = this->Rotation_angle_Y / 180.0 * M_PI;
	double angle_z = this->Rotation_angle_Z / 180.0 * M_PI;

	// 进行旋转
	gp_Trsf rotation_X;
	rotation_X.SetRotation(rotationAxis_X, angle_x); // X
	BRepBuilderAPI_Transform rotateTransform_X(translatedShape, rotation_X);
	TopoDS_Shape rotatedShape_X = rotateTransform_X.Shape();

	// 进行旋转
	gp_Trsf rotation_Y;
	rotation_Y.SetRotation(rotationAxis_Y, angle_y); // Y
	BRepBuilderAPI_Transform rotateTransform_Y(rotatedShape_X, rotation_Y);
	TopoDS_Shape rotatedShape_Y = rotateTransform_Y.Shape();

	// 进行旋转
	gp_Trsf rotation_Z;
	rotation_Z.SetRotation(rotationAxis_Z, angle_z); // Z
	BRepBuilderAPI_Transform rotateTransform_Z(rotatedShape_Y, rotation_Z);
	TopoDS_Shape rotatedShape = rotateTransform_Z.Shape();

	// 创建一个 BRepBuilderAPI_Transform 对象来进行缩放
	gp_Pnt refrenceCenter(ScaleRefrencePoint_X, ScaleRefrencePoint_Y, ScaleRefrencePoint_Z);  // 中心点坐标
	gp_Trsf scaleTransform;
	scaleTransform.SetScale(refrenceCenter, ScaleDouble);
	BRepBuilderAPI_Transform scaleTransformBuilder(rotatedShape, scaleTransform);
 
	// 应用变换
	if (scaleTransformBuilder.IsDone()) {
		this->Datashape = scaleTransformBuilder.Shape();
	}
	else {

	}
	// 内存释放
	translatedShape.Nullify();
	rotatedShape_X.Nullify();
	rotatedShape_Y.Nullify();
	rotatedShape.Nullify();

	if (this->myContext) {
		qDebug() << u8"图像刷新";
		this->Data_AIS.Nullify();

		// 创建或获取对象的 AIS_Shape
		Handle(AIS_Shape) aisShape = new AIS_Shape(this->Datashape);
		
		// 创建一个颜色对象，例如红色
		Quantity_Color redColor(1.0, 0.0, 0.0, Quantity_TOC_RGB); // RGB红色

		ChangeModelColor(aisShape, redColor);

		this->Data_AIS = aisShape;
		
		this->myContext->Display(this->Data_AIS, Standard_True); // 立刻刷新
		this->myContext->AddOrRemoveSelected(this->Data_AIS, Standard_True);
	}
	// 处理响应逻辑
	emit this->RefreshResult(this);

}

void OCCTModelOperator::ProcesssModel()
{
	this->ApplyModel();
}

void OCCTModelOperator::on_lineEdit_Move_From_X_returnPressed()
{
	
	this->PreViewOperator();
}



void OCCTModelOperator::on_lineEdit_Move_From_Z_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Move_From_Y_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Move_To_X_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Move_To_Y_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Move_To_Z_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Rotation_Center_X_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Rotation_Center_Y_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Rotation_Center_Z_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Rotation_Axis_X_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Rotation_Axis_Y_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Rotation_Axis_Z_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Scale_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Scale_refrence_point_X_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Scale_refrence_point_Y_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_Scale_refrence_point_Z_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_lineEdit_ScaleValue_returnPressed()
{
	this->PreViewOperator();
}

void OCCTModelOperator::on_radioButton_Auto_toggled(bool flag)
{
	if (flag) {
		this->ui.lineEdit_Scale_refrence_point_X->setEnabled(false);
		this->ui.lineEdit_Scale_refrence_point_Y->setEnabled(false);
		this->ui.lineEdit_Scale_refrence_point_Z->setEnabled(false);
		this->UpdateScaleRefrencepoint();
	}
}

void OCCTModelOperator::on_radioButton_NoAuto_toggled(bool flag)
{
	if (flag) {
		this->ui.lineEdit_Scale_refrence_point_X->setEnabled(true);
		this->ui.lineEdit_Scale_refrence_point_Y->setEnabled(true);
		this->ui.lineEdit_Scale_refrence_point_Z->setEnabled(true);
		this->UpdateScaleRefrencepoint();
	}
}


void OCCTModelOperator::on_pushButton_ok_clicked()
{
	this->UpdataVariable();

	this->ApplyModel();

	if (this->myContext) {
		qDebug() << u8"模型移除";
		this->myContext->Remove(this->Data_AIS, Standard_False);
		this->myContext->UpdateCurrentViewer();
		
	}
	// 创建一个复制模型
	BRepBuilderAPI_Copy copyBuilder;
	copyBuilder.Perform(this->Datashape);
	this->DataShapeBAK = copyBuilder.Shape();
 
	if (this->ui.radioButton_Copy->isChecked()) {
		emit this->ResultExportCopyAndCreateNew(this);
	}
	else {
		emit this->ResultExport(this);
	}
	this->close();
}

void OCCTModelOperator::on_pushButton_apply_clicked()
{
	this->UpdataVariable();

	this->ApplyModel();

	if (this->myContext) {
		qDebug() << u8"模型移除";
		//this->myContext->Erase(this->Data_AIS, Standard_True);
		this->myContext->Remove(this->Data_AIS, Standard_False);
		this->myContext->UpdateCurrentViewer();
  
	}
	// 创建一个复制模型
	BRepBuilderAPI_Copy copyBuilder;
	copyBuilder.Perform(this->Datashape);
	this->DataShapeBAK = copyBuilder.Shape();

	if (this->ui.radioButton_Copy->isChecked()) {
		emit this->ResultExportCopyAndCreateNew(this);
	}
	else {
		emit this->ResultExport(this);
	}
}

void OCCTModelOperator::on_pushButton_Cancel_clicked()
{
	this->close();
}
