#pragma once
#include <memory>
#include <QAction>
#include <QCloseEvent>
#include <QColor>
#include <QComboBox>
#include <QDateTime>
#include <QDebug>
#include <QDesktopWidget>
#include <QFileDialog>
#include <QFontComboBox>
#include <QImage>
#include <QLabel>
#include <QMainWindow>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QProgressDialog>
#include <QRect>
#include <QSettings>
#include <QSpinBox>
#include <QString>
#include <QStringList>
#include <QTextCharFormat>
#include <QTime>
#include <QToolBar>
#include <QToolButton>
#include <QListWidgetItem>

#include <QApplication>
#include <QDateTime> //添加QDateTime头文件
#include <QMovie>
#include <QPixmap>
#include <QSplashScreen>
#include <QTextCodec>

// Point Cloud Library
#include <QColorDialog>
#include <iostream>
#include <pcl/common/common.h>
#include <pcl/console/time.h> // TicToc
#include <pcl/console/time.h>
#include <pcl/filters/convolution_3d.h>
#include <pcl/filters/filter.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>

#include <boost/random.hpp> //随机数
#include <boost/thread/thread.hpp>
#include <iostream>
#include <pcl/console/time.h> // TicToc
#include <pcl/features/normal_3d.h>
#include <pcl/filters/bilateral.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/fast_bilateral.h>
#include <pcl/filters/fast_bilateral_omp.h>
#include <pcl/filters/passthrough.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/registration/ia_fpcs.h>  // 4PCS算法
#include <pcl/registration/ia_kfpcs.h> //K4PCS算法头文件
#include <pcl/registration/icp.h>
#include <pcl/registration/registration.h>
#include <pcl/search/flann_search.h>
#include <pcl/surface/concave_hull.h>
#include <pcl/surface/gp3.h> //贪婪投影三角化算法类定义的头文件
#include <pcl/surface/marching_cubes_hoppe.h> //移动立方体
#include <pcl/surface/marching_cubes_rbf.h>
#include <pcl/surface/mls.h>     //MLS
#include <pcl/surface/poisson.h> //泊松重建
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <string>
#include <vector>
#include <vtkOutputWindow.h>

#include <pcl/console/time.h>                   // TicToc
#include <pcl/filters/approximate_voxel_grid.h> // 体素滤波
#include <pcl/filters/voxel_grid.h>             // 体素滤波
#include <vtkOutputWindow.h>

#include <boost/thread/thread.hpp>
#include <pcl/ModelCoefficients.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h> //随机参数估计方法
#include <pcl/sample_consensus/model_types.h>  //模型定义
#include <pcl/segmentation/sac_segmentation.h> //RANSAC分割
#include <pcl/visualization/pcl_visualizer.h>
#include <sstream>
#include <stdlib.h> //rand()头文件
#include <vtkMassProperties.h>
#include <vtkPLYReader.h>
#include <vtkSmartPointer.h>
#include <vtkTriangleFilter.h>

#include <Eigen/Core>
#include <iostream>
#include <pcl/common/common.h>
#include <pcl/common/transforms.h>
#include <pcl/features/moment_of_inertia_estimation.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <string>
#include <string>
#include <vector>
#include <vtkAutoInit.h>
//可视化相关头文件
#include <vtkActor.h>
#include <vtkAutoInit.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
// Boost
#include <boost/math/special_functions/round.hpp>

// Visualization Toolkit (VTK)
#include <vtkRenderWindow.h>
#include "ui_pclvisualizer.h"
#include "inputdialog.h"
#include "BasePCL.h"
#include "ToolDialog.h"
#include "PointManagerClass.h"


QT_BEGIN_NAMESPACE
namespace Ui {
    class PCLVisualizer;
};
QT_END_NAMESPACE



class PCLVisualizer : public QMainWindow
{
  Q_OBJECT

public:
    CloudPointManagerClass *cloudmanager; // 点云管理器
    QProgressBar* statusbarprogressBar; // 状态栏
public:
  PCLVisualizer(QWidget* parent = nullptr);
  ~PCLVisualizer();

  void initPCV();
  void showLogItem(QString item, QString info);   //显示log信息
  void saveSetting(QString name, QString item);   // 保存设置
  QVariant getSetting(QString name);
  void createActions();  //创建动作
  void createMenus();    //创建菜单
  void createToolBars(); //创建工具栏

  //点云坐标极值
  pcl::PointXYZRGBA  p_min, p_max;

  double maxLen;

  double getMinValue(pcl::PointXYZRGBA  p1, pcl::PointXYZRGBA  p2);
  double getMaxValue(pcl::PointXYZRGBA  p1, pcl::PointXYZRGBA  p2);

  QString filePathWithName;

  // 打开进度窗口
  void openProgressDlg(int num);
  void showStatusBarTip(QString text, size_t value);
  // 更新点云信息
  void updateCloudInfo();

  /************************************************************************/
  /* 点云预处理算法 */
  /************************************************************************/
  //全局变量 PCD文件IO
  pcl::PCDWriter writer;
  pcl::PCDReader reader;

  //键盘事件
  int nextShow = 0;
  bool next_iteration = false;
  void keyboardEventOccurred(const pcl::visualization::KeyboardEvent& event,
                             void* nothing)
  {
    if (event.getKeySym() == "space" && event.keyDown()) {
      ++nextShow;
      next_iteration = true;
    }
  }

  void best_filter();
  /*
                  将点云旋转平移
  */
  void cloudTransform(pcl::PointCloud< pcl::PointXYZRGBA>::Ptr cloud_in,
                       pcl::PointCloud< pcl::PointXYZRGBA>::Ptr cloud_tr,
                      double theta = M_PI / 4,
                      double z = 0.1);

  /*
                迭代最近点算法
                配置ICP的参数,并设置只进行一次迭代，然后计算一次
*/
  void ICP_aligin(pcl::IterativeClosestPoint<pcl::PointXYZRGBA, pcl::PointXYZRGBA >::Ptr icp,
      pcl::PointCloud< pcl::PointXYZRGBA>::Ptr cloud_in,
      pcl::PointCloud< pcl::PointXYZRGBA>::Ptr cloud_RE);

  void best_aligin();

  void best_surface();

public slots:

  //新建工作台
  void newWorkStation();

  void test();
  //初始化数据
  void initPointCloud();
  //连接信号槽
  void connectSS();
  //保存文件
  void savePCDFile();
  void loadPCDFile();
  void loadPLYFile();

  //选择需要控制的坐标轴
  void chooseAxis();
  //选择颜色模式
  void chooseColorMode();
  //增大 Point Size
  void IncPointSize();
  //减小 Point Size
  void DecPointSize();
  //添加/取消坐标轴
  void AddCoordinateSystem();

protected:
  virtual void closeEvent(QCloseEvent* event);

  int point_size;
  QColor point_color;
  //创建一个共享的PCLVisualizer 对象用于显示
  pcl::visualization::PCLVisualizer::Ptr viewer_;
  //创建一个共享指针用于保存点云
  ////原始点云
  //PointCloudT::Ptr cloud_;
  ////彩色点云
  //PointCloudTRGBA::Ptr cloudRGBA_;

  /** @brief 坐标轴：0 = x | 1 = y | 2 = z */
  int filtering_axis_;

  /** @brief 颜色模式：Holds the color mode for @ref colorCloudDistances */
  int color_mode_;

private slots:

    // 测试模型
   void Test_BestSurface();


  //工具栏中的视图选择工作 6个
  void on_actionUp_triggered();

  void on_actionBottom_triggered();

  void on_actionFront_triggered();

  void on_actionBack_triggered();

  void on_actionLeft_triggered();

  void on_actionRight_triggered();

  void on_actionBGColor_triggered();

  void on_actionabout_triggered();

  void on_comboBox_Color_currentIndexChanged(const QString& arg1);

  void on_actionCoordinateSystem_triggered();

  void on_actionCameraview_triggered();

  void on_pointSizeEdt_valueChanged(int arg1);

  void on_actionbestSurface_triggered();

  void on_actionbestRemoval_triggered();

  void on_actionbestFiltering_triggered();

  void on_actionbestRegistration_triggered();

  void on_actionbestKeypoint_triggered();

  void on_actionTXT_triggered();

  void on_actionExportLog_triggered();

  void on_actionRedo_triggered();

  void on_actionquit_triggered();

  void on_actiongetAllGeo_triggered();

  void on_actionplaneSeg_triggered();

  void on_actionarea_triggered();

  void on_actionvol_triggered();

  // 新增工具项
  void on_actionStatisticalRemove_triggered(); // 统计离群点

  void on_actionDB_triggered(); // 密度离群点

  void on_actionBilateral_triggered(); //  双边滤波
   
  void on_actionMedian2_triggered(); // 中值

  void on_actionGP_triggered(); // 贪婪三角网

  void on_actionPoisson_triggered(); //  泊松



private:
  Ui::PCLVisualizer* ui;
  inputDialog* inputDlg;

  //软件设置
  QSettings* settings;
  QString logStr;
  QStringList logList;

  QTime q_time;

  bool isRBGA;

  QColor bgColor;

  QMenu* fileMenu; //各项菜单栏
  QMenu* zoomMenu;
  QMenu* rotateMenu;
  QMenu* mirrorMenu;

  QString fileName;

  //点云文件处理动作
  QAction* addCloudAction;
  QAction* newWorkStationAction;
  QAction* exportCloud2PCDAction;
  QAction* exportCloud2PLYAction;
  QAction* newCloudAction;
  QAction* copyCloudAction;
  QAction* cutCloudAction;
  QAction* pasteCloudAction;
  QAction* searchCloudAction;
  QAction* export2CSVAction;
  QAction* export2TXTAction;
  QAction* starCloudAction;
  QAction* snapShotAction;

  QAction* outliersRemoveAction; //镜像菜单项
  QAction* filterAction;
  QAction* alignAction;
  QAction* MLSAction;
  QAction* downSampleAction;
  QAction* cloudSpliceAction;
  QAction* HistogramAction;
  QAction* surfaceAction;

  QToolBar* fileTool; //工具栏
  QToolBar* algorithmTool;
};


int ShowPclvisualizer(QWidget* parent);
