#include "ModelProcess.h"
#include "EchoShowProcess/FEKOResultImport.h"
#include "TaskXml/TaskTreeClass.h"
#include <QDebug>
#include <opencascade/BRepPrimAPI_MakeBox.hxx>
#include <opencascade/BRepOffsetAPI_DraftAngle.hxx>


ModelProcess::ModelProcess(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);   
    this->initConstVariable();
    // 设置背景色
    this->showConntentsWindows();
    //this->showModelInfoWindows();
    this->showInnerModelWindow();
    this->initOCCTView();
    //this->initModelInformationShow();
    this->initMenuList();
    this->initBandingEvent();
    this->initTaskDocker();
  
    this->initFileOperatorMenu();
}

ModelProcess::~ModelProcess()
{

}

void ModelProcess::on_action_Open_triggered()
{
    //myDocument3d->OpenFile();
    this->myGeomWidget->Show3d();

}


void ModelProcess::on_action_Modelsave_triggered() // 保存整体模型
{
    this->myDocument3d->SaveModelFile();

}

void ModelProcess::on_actionCalibrationConstCreate_triggered()
{
 

}

void ModelProcess::on_actionImageSetting_triggered()
{
    FEKOImageSettingTaskNodeClass* imageNode = new FEKOImageSettingTaskNodeClass();
    QString xmlfilepath = getSaveFilePath(this, QString::fromUtf8(u8"任务xml"),  QString::fromUtf8(u8"xml文件 (*.xml)"));
    imageNode->loadXmlFile(xmlfilepath);
    imageNode->TaskWindows->setOCCTDocument(this->myDocument3d->myContext);
    this->addTaskNode(imageNode);
    imageNode->ExcuteTask();
}

void ModelProcess::on_action_ScatterExport_triggered()
{
    EchoTableEditWindow* echoEditwindow = new EchoTableEditWindow(this);
    
    echoEditwindow->show();

}

void ModelProcess::on_actionFEKOImage_triggered()
{
    LAMPImageCreateClass* imagewindows = new LAMPImageCreateClass;
    imagewindows->on_pushButton_loadfekosimulationxml_clicked();
    imagewindows->show();
}

void ModelProcess::on_action_antScatteringFEKOSetting_triggered()
{
    FEKOScatterSettingTaskNodeClass* scattertasknode=new FEKOScatterSettingTaskNodeClass();
    QString xmlfilepath = getSaveFilePath(this, QString::fromUtf8(u8"任务xml"), QString::fromUtf8(u8"xml文件 (*.xml)"));
    scattertasknode->loadXmlFile(xmlfilepath);
    scattertasknode->TaskWindows->setDocument3d(this->myDocument3d->myContext);
    this->addTaskNode(scattertasknode);
    scattertasknode->ExcuteTask();
}

void ModelProcess::on_action_openImageShowWindows_triggered()
{
    LAMPDataShowClass* datashowclass=new LAMPDataShowClass();
    datashowclass->show();
}

void ModelProcess::ShowTaskListMenu(QPoint p)
{
    qDebug() << u8"成像任务管理右击菜单";
    this->TaskListContextMenu->exec(QCursor::pos());
}

void ModelProcess::ShowTaskWindows()
{
    QList<QTreeWidgetItem*> selectNodes = this->ui.treeWidgetTask->selectedItems(); // 获取顶层
    QTreeWidgetItem* imageNode = selectNodes.at(0);
    imageNode->data(0, Qt::UserRole).value<TaskNode*>()->ExcuteTask();
}

void ModelProcess::addTaskNode(TaskNode* Node)
{
    // 往qtTree 添加节点
    QTreeWidgetItem* topNode = this->ui.treeWidgetTask->topLevelItem(0); // 获取顶层
    QTreeWidgetItem* imageSetNode = new QTreeWidgetItem();
    imageSetNode->setText(0, Node->getTaskName());
    imageSetNode->setData(0, Qt::UserRole, QVariant::fromValue(Node));
    topNode->addChild(imageSetNode);
}

void ModelProcess::removeTaskNode(TaskNode* Node)
{




}


bool ModelProcess::showConntentsWindows()
{
    qDebug() << u8"showConntentsWindows\n";
    if (this->dockWidget) {
         
    }
    else {
        this->dockWidget = new QDockWidget(this);
        this->dockWidget->setObjectName(QString::fromUtf8("dockWidget"));
        this->dockWidget->setWindowTitle(QString::fromUtf8(u8"模型窗口列表"));
    }
	if (this->dockWidgetContents) {

	}
	else {
		this->dockWidgetContents = new QWidget();
		this->dockWidgetContents->setObjectName(QString::fromUtf8("dockWidgetContents"));
        this->dockWidgetContents->setWindowTitle(QString::fromUtf8(u8"模型详细列表"));
	}

	verticalLayout = new QVBoxLayout(this->dockWidgetContents);
	verticalLayout->setSpacing(6);
	verticalLayout->setContentsMargins(11, 11, 11, 11);
	verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
	dockWidget->setWidget(this->dockWidgetContents);
	this->addDockWidget(Qt::LeftDockWidgetArea, dockWidget);

    return true;
}

bool ModelProcess::showModelInfoWindows()
{
    qDebug() << u8"showModelInfoWindows\n";
	if (this->dockWidget_modelinfoshow) {

	}
	else {

		dockWidget_modelinfoshow = new QDockWidget(this);
		dockWidget_modelinfoshow->setObjectName(QString::fromUtf8("dockWidget_modelinfoshow"));
	}
	if (this->dockWidget_ModelInfoShowWindows) {

	}
	else {
		dockWidget_ModelInfoShowWindows = new QWidget();
		dockWidget_ModelInfoShowWindows->setObjectName(QString::fromUtf8("dockWidget_ModelInfoShowWindows"));
	}
    verticalLayout_ModelInfoShowWindows = new QVBoxLayout(dockWidget_ModelInfoShowWindows);
    verticalLayout_ModelInfoShowWindows->setSpacing(6);
    verticalLayout_ModelInfoShowWindows->setContentsMargins(11, 11, 11, 11);
    verticalLayout_ModelInfoShowWindows->setObjectName(QString::fromUtf8("verticalLayout_2"));
	dockWidget_modelinfoshow->setWidget(dockWidget_ModelInfoShowWindows);
	this->addDockWidget(Qt::RightDockWidgetArea, this->dockWidget_modelinfoshow);
	return true;
}

bool ModelProcess::showInnerModelWindow()
{
     qDebug() << u8"showInnerModelWindow\n";
    if(this->dockWidget_InnerModel){}
    else {
        dockWidget_InnerModel = new QDockWidget(this);
        dockWidget_InnerModel->setObjectName(QString::fromUtf8("dockWidget_InnerModel"));
    }
    if (this->dockWidget_InnerModelWindows) {

    }
    else {
        dockWidget_InnerModelWindows = new QWidget();
        dockWidget_InnerModelWindows->setObjectName(QString::fromUtf8("dockWidget_InnerModelWindows"));
    }
    this->dockWidget_InnerModel->setWindowTitle(u8"内置模式库");
    verticalLayout_ModelInfoShowWindows = new QVBoxLayout(dockWidget_InnerModelWindows);
    verticalLayout_ModelInfoShowWindows->setSpacing(6);
    verticalLayout_ModelInfoShowWindows->setContentsMargins(11, 11, 11, 11);
    verticalLayout_ModelInfoShowWindows->setObjectName(QString::fromUtf8("verticalLayout_3"));
    dockWidget_InnerModel->setWidget(dockWidget_InnerModelWindows);
   this->addDockWidget(Qt::RightDockWidgetArea, dockWidget_InnerModel);
    return true;
}

void ModelProcess::actionOpenRaster()
{
    QString filename = getOpenFilePath(this, u8"打开影像文件",u8"ENVI Data (*.dat);;tiff (*.tif);;");
    // 判断是否为复数对象？
    qDebug() << filename;
	QFileInfo fileinfo(filename);
	qDebug() << fileinfo.fileName();
    GDALDataType dataType = getGDALDataType(filename);
    if (dataType == GDT_CFloat32 || dataType == GDT_CFloat64) {
		ComplexDataShowNode* node = new ComplexDataShowNode(this);
		node->bangdindWindows(this);
		node->OpenData(filename);
		this->myDocument3d->addTaskNode(node);
    }
    else {
		DataShowNode* node = new DataShowNode(this);
		node->bangdindWindows(this);
		node->OpenData(filename);
		this->myDocument3d->addTaskNode(node);
    }
}

void ModelProcess::actionOpenModel()
{
    QString  stlpath = getOpenFilePath(
        this,
        QString::fromUtf8(u8"导入模型"),
        QString::fromUtf8(u8"STL Files (*.stl);;STL Files (*.stla);;step Files (*.stp);;step Files (*.step);;IGES Files (*.iges);;IGES Files (*.igs)"));
    OCCTShapeModelNode* node = new OCCTShapeModelNode(this);
    node->setDataFile(stlpath);
    this->myDocument3d->addTaskNode(node);
}

bool ModelProcess::initFileOperatorMenu()
{
    QAction* action_OpenFileRaster=this->ui.menu_FileOpenOperator->addAction(u8"打开影像");
    QObject::connect(action_OpenFileRaster, SIGNAL(triggered()), this, SLOT(actionOpenRaster()));
    QAction* action_OpenModelStl = this->ui.menu_FileOpenOperator->addAction(u8"打开模型");
    QObject::connect(action_OpenModelStl, SIGNAL(triggered()), this, SLOT(actionOpenModel()));


    return false;
}

bool ModelProcess::initConstVariable()
{
    // 模型相关界面
    this->dockWidget = nullptr;
    this->dockWidgetContents = nullptr;
    this->verticalLayout = nullptr;
    this->dockWidget_modelinfoshow = nullptr;
    this->dockWidget_ModelInfoShowWindows = nullptr;
    this->verticalLayout_ModelInfoShowWindows = nullptr;
    this->dockWidget_InnerModel = nullptr;
    this->dockWidget_InnerModelWindows = nullptr;
    this->verticalLayout_InnerModelWindows = nullptr;
    this->myDocument3d = nullptr;
    this->selectModeMenu = nullptr; // 选择模式切换
    this->showModelMenu = nullptr;
    this->myGeomWidget = nullptr; // 模型渲染串口
    this->TopoShapeTreeViewer = nullptr;
    return true;
}

bool ModelProcess::initOCCTView()
{
    // 初始化 OCCT
    if (this->myDocument3d) {
    
    }
    else {
        this->myDocument3d = new DocumentCommon(this); // 3D 模型
         
    }
    this->verticalLayout->addWidget(this->myDocument3d);
    QVBoxLayout* aViewLayout = new QVBoxLayout(this->ui.OCCViewGLWidget);
    aViewLayout->setContentsMargins(0, 0, 0, 0);
    this->myGeomWidget = new GeomWidget(myDocument3d, this->ui.OCCViewGLWidget);// 创建一个三维显示对象
    aViewLayout->addWidget(this->myGeomWidget);
    this->myGeomWidget->setContentsMargins(0, 0, 0, 0);
    this->myDocument3d->InitAixs();     // 计算三维坐标轴
    this->myGeomWidget->FitAll();

    return true;
}

void ModelProcess::on_action_FEKO2csv_triggered() {

    qDebug() << u8"启动FEKO->csv 文件 \n";
    QString  xmlfilepath = getSaveFilePath(this, QString::fromUtf8(u8"设置FEKO结果导入任务xml"),   QString::fromUtf8(u8"xml文件 (*.xml)"));
    qDebug() <<  u8"选择 xmlfile 文件路径：\t " + xmlfilepath + u8"\n" ;
    FEKOResultImportTaskNode* fekoresulttask = new FEKOResultImportTaskNode();
    fekoresulttask->loadXmlFile(xmlfilepath);
    fekoresulttask->ExcuteTask();
    return;
}

// 初始化对象数据
bool ModelProcess::initSelectModeMenu()
{
	this->selectModeMenu = new QMenu(u8"模型选择模式",this);
	QAction* actiion_VerticesSelect3dSample = this->selectModeMenu->addAction(u8"选择顶点");
	QObject::connect(actiion_VerticesSelect3dSample, SIGNAL(triggered()), this->myDocument3d, SLOT(VerticesSelect3dSample()));

	QAction* actiion_EdgesSelect3dSample = this->selectModeMenu->addAction(u8"选择边");
	QObject::connect(actiion_EdgesSelect3dSample, SIGNAL(triggered()), this->myDocument3d, SLOT(EdgesSelect3dSample()));

	QAction* actiion_FacesSelect3dSample = this->selectModeMenu->addAction(u8"选择面");
	QObject::connect(actiion_FacesSelect3dSample, SIGNAL(triggered()), this->myDocument3d, SLOT(FacesSelect3dSample()));

	QAction* actiion_NeutralPointSelect3dSample = this->selectModeMenu->addAction(u8"模型整体选择");
	QObject::connect(actiion_NeutralPointSelect3dSample, SIGNAL(triggered()), this->myDocument3d, SLOT(NeutralPointSelect3dSample()));

	return true;
}

bool ModelProcess::initGeometryShowModelMenu()
{
    this->showModelMenu = new QMenu(u8"视图显示模式");
    QAction* actiion_ShowHideMehsGrid = this->showModelMenu->addAction(u8"显示/关闭平面网格");
    QObject::connect(actiion_ShowHideMehsGrid, SIGNAL(triggered()), this->myDocument3d, SLOT(ShowOrHideActivateGridMesh()));

    QAction* actiion_ShowHideAixesGrid = this->showModelMenu->addAction(u8"显示/关闭立方网格");
    QObject::connect(actiion_ShowHideMehsGrid, SIGNAL(triggered()), this->myDocument3d, SLOT(ShowOrHideActivateAxisGris()));

 
    return true;
}

bool ModelProcess::initModelInformationShow()
{
     
    if (this->TopoShapeTreeViewer) {

    }
    else {
        this->TopoShapeTreeViewer = new OCCTopoShapeTreeViewer(this); // 3D 模型
    }
    this->verticalLayout_ModelInfoShowWindows->addWidget(this->TopoShapeTreeViewer);
    this->myDocument3d->setShapeInfomationWindows(this->TopoShapeTreeViewer);


    return true;
}

bool ModelProcess::initMenuList()
{



    this->initSelectModeMenu();
    this->initGeometryShowModelMenu();
    this->ui.menu_modelOperator->addMenu(this->selectModeMenu);
    this->ui.menu_modelOperator->addMenu(this->showModelMenu);

    return true;
}

bool ModelProcess::initBandingEvent()
{
    QObject::connect(this->myDocument3d, SIGNAL(ShowSelectItemFullExtend(const TopoDS_Shape &)), this->myGeomWidget, SLOT(ShowExtend(const TopoDS_Shape & )));
    return true;
}

bool ModelProcess::initTaskDocker()
{
    this->ui.dockWidget_Task->setHidden(false);
    this->ui.dockWidget_Task->setWindowTitle(QString::fromUtf8(u8"任务列表"));
    // 初始化任务列表
  //  this->ui.treeWidgetTask->setColumnCount(0);
    QStringList headerLabels;
    headerLabels <<u8"名称" << u8"描述";
    this->ui.treeWidgetTask->setHeaderLabels(headerLabels);
    QTreeWidgetItem* topNode = this->ui.treeWidgetTask->topLevelItem(0); // 获取顶层
    if (topNode) {
        topNode->setText(0, u8"成像任务");
    }
    else {
        this->ui.treeWidgetTask->insertTopLevelItem(0, new QTreeWidgetItem(this->ui.treeWidgetTask, QStringList(u8"任务")));
    }


    this->ui.treeWidgetTask->setContextMenuPolicy(Qt::CustomContextMenu); 

    this->TaskListContextMenu =       new QMenu(this->ui.treeWidgetTask);
    QAction* openTaskNodeAction = this->TaskListContextMenu->addAction(u8"打开"); // 
    QObject::connect(openTaskNodeAction, SIGNAL(triggered()), this, SLOT(ShowTaskWindows()));

    QObject::connect(this->ui.treeWidgetTask, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(ShowTaskListMenu(QPoint)));
 
    return false;
}


QDockWidget* ModelProcess::getdockWidget_command(QString dockerTitle,Qt::DockWidgetArea layoutear)
{
    QDockWidget*  dockWidget_command = new QDockWidget(this);
    dockWidget_command->setObjectName(dockerTitle);
    dockWidget_command->setWindowTitle(dockerTitle);
    this->addDockWidget(layoutear, dockWidget_command);
    return dockWidget_command;
}
 

///////////////////////////////////////////////////////
// ModelProcess 常见命令
//////////////////////////////////////////////////////


QString ModelProcess::moveTopoShape(QString toponame, QString move_x, QString move_y, QString move_z)
{
   // OCCTObjectCheckBox* topoShapeItem = this->getTopoShapeItem(toponame);
 
    return QString();
}

 
bool ModelProcess::ShowTopoShape(TopoDS_Shape topoShape, QString topoName, bool isShow)
{
    this->myDocument3d->addOCCTObjItem(topoShape, topoName, isShow);
    return true;
}

bool ModelProcess::removeShape(QString topoName)
{
    this->myDocument3d->removeTaskNode(topoName);
    return false;
}

QString ModelProcess::createBox(QString topoName,double dx,double dy,double dz,double angle)
{
    TopoDS_Shape S = BRepPrimAPI_MakeBox(dx, dy, dz);
    BRepOffsetAPI_DraftAngle adraft(S);
    TopExp_Explorer Ex;
    for (Ex.Init(S, TopAbs_FACE); Ex.More(); Ex.Next()) {
        TopoDS_Face F = TopoDS::Face(Ex.Current());
        Handle(Geom_Plane) surf = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(F));
        gp_Pln apln = surf->Pln();
        gp_Dir dirF = apln.Axis().Direction();
        if (dirF.IsNormal(gp_Dir(0., 0., 1.), Precision::Angular()))
            adraft.Add(F, gp_Dir(0., 0., 1.), angle * M_PI / 180, gp_Pln(gp::XOY()));
    }
    TopoDS_Shape resultShape = adraft.Shape();
    this->myDocument3d->addOCCTObjItem(resultShape, topoName, true);

    return topoName;
}
 