
#include "ImageShowDialogClass.h"
#include "ui_ImageShowDialogClass.h"
ImageShowDialogClass ::ImageShowDialogClass(QWidget *parent)
	: QDialog(parent)
{
	ui=new Ui::ImageShowDialogClass;
	ui->setupUi(this);
	ui->m_plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
	connect(this->ui->m_plot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(updateCursor(QMouseEvent*)));
	this->graphclass=LAMPDATASHOWCLASS::NOWINDOWS;

	this->menubar = new QMenuBar(this);
	QMenu* windowsMenu = this->menubar->addMenu(u8"数据");
	QAction* action_cursor_enable = windowsMenu->addAction(u8"打开游标");
	QObject::connect(action_cursor_enable,SIGNAL(triggered()),this,SLOT(on_action_cursor_enable_trigged()));
	this->tracer=new QCPItemTracer(this->ui->m_plot);
	this->m_plot = ui->m_plot;
	
	this->desCursor = nullptr;
	this->HlineCursor = nullptr;
	this->VlineCursor = nullptr;

	this->desCursorflag=false;
	this->HlineCursorflag=false;
	this->VlineCursorflag = false;
	
	this->statusbar=new QStatusBar(this);
	this->statusbar->setMaximumHeight(20);
	this->statusbar->setMinimumHeight(20);
	
	ui->verticalLayout->setMenuBar(this->menubar);
	ui->verticalLayout->addWidget(this->statusbar);
	this->setLayout(ui->verticalLayout);
}


ImageShowDialogClass::~ImageShowDialogClass()
{}


void ImageShowDialogClass::on_action_cursor_enable_trigged()
{
	this->desCursor =  	new ImageShowCursorDesClass(this);
	
	this->desCursorflag = true;
	for (size_t i = 0; i < this->getGraphCount(); i++) {
		if (this->getGraphClass(i) == LAMPDATASHOWCLASS::LAMPColorMap) {
			this->HlineCursorflag = true;
			this->VlineCursorflag = true;
		}
	}

	//下面的代码就是设置游标的外观
	this->setMouseTracking(true);
	tracer->setInterpolating(false);//禁用插值
	tracer->setPen(QPen(Qt::DashLine));//虚线游标
	tracer->setStyle(QCPItemTracer::tsPlus);//游标样式：十字星、圆圈、方框
	tracer->setBrush(Qt::red);//游标颜色

	if (this->graphclass == LAMPDATASHOWCLASS::LAMPColorMap) {
		this->HlineCursor = new ImageShowCursorLineClass(this);
		this->VlineCursor = new ImageShowCursorLineClass(this);
		QObject::connect(this->HlineCursor, SIGNAL(windowsClose()), this, SLOT(on_action_Hlinecursor_close_trigged()));
		QObject::connect(this->VlineCursor, SIGNAL(windowsClose()), this, SLOT(on_action_VVlinecursor_close_trigged()));
		QObject::connect(this->ui->m_plot->xAxis, SIGNAL(rangeChanged(QCPRange)), this->HlineCursor, SLOT(xAxisRangeChanged(QCPRange)));
		QObject::connect(this->ui->m_plot->yAxis, SIGNAL(rangeChanged(QCPRange)), this->HlineCursor, SLOT(xAxisRangeChanged(QCPRange)));
		this->HlineCursor->show();
		this->VlineCursor->show();
	}
	this->desCursor->show();
	QObject::connect(this->desCursor, SIGNAL(windowsClose()), this, SLOT(on_action_descursor_close_trigged()));
}

void ImageShowDialogClass::PlotLine(QVector<double> xs, QVector<double> dataValues,QString Name)
{
	if (dataValues.count() == 0) { return; }
	QCPGraph* graph = ui->m_plot->addGraph();
	graph->setName(Name);
	graph->setData(xs, dataValues);
	double min_y = dataValues[0];
	double max_y = dataValues[0];
	for (size_t i = 0; i < dataValues.count(); i++) {
		min_y = min_y > dataValues[i] ? dataValues[i] : min_y;
		max_y = max_y < dataValues[i] ? dataValues[i] : max_y;
	}

	double min_x = xs[0];
	double max_x = xs[0];
	for (size_t i = 0; i < xs.count(); i++) {
		min_x = min_x > xs[i] ? xs[i] : min_x;
		max_x = max_x < xs[i] ? xs[i] : max_x;
	}
	 ui->m_plot->xAxis->setRange(min_x, max_x);
	 ui->m_plot->yAxis->setRange(min_y, max_y);
	 ui->m_plot->legend->setVisible(true);
	 ui->m_plot->replot();


	//下面的代码就是设置游标的外观
	this->setMouseTracking(true);
	tracer->setInterpolating(false);//禁用插值
	tracer->setPen(QPen(Qt::DashLine));//虚线游标
	tracer->setStyle(QCPItemTracer::tsPlus);//游标样式：十字星、圆圈、方框
	tracer->setBrush(Qt::red);//游标颜色
	tracer->setGraph(graph); // 确保游标跟随
	this->m_graphMap.insert(Name, graph);

}

void ImageShowDialogClass::Scatter(double dx,double dy)
{
	QVector<double>xs(0);
	QVector<double>ys(0);
	xs.push_back(dx);
	ys.push_back(dy);
	// 设置画笔风格
	QPen drawPen;
	drawPen.setColor(Qt::red);
	drawPen.setWidth(4);

	// 绘制散点
	QCPGraph* curGraph = ui->m_plot->addGraph();
	curGraph->setPen(drawPen);
	curGraph->setLineStyle(QCPGraph::lsNone);
	curGraph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 2));
	curGraph->setData(xs, ys);

	ui->m_plot->xAxis->setVisible(true);
	ui->m_plot->yAxis->setVisible(true);

}

void ImageShowDialogClass::Scatter(QVector<double> xs, QVector<double> ys)
{
	// 设置画笔风格
	QPen drawPen;
	drawPen.setColor(Qt::red);
	drawPen.setWidth(4);

	// 绘制散点
	QCPGraph* curGraph = ui->m_plot->addGraph();
	curGraph->setPen(drawPen);
	curGraph->setLineStyle(QCPGraph::lsNone);
	curGraph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 2));
	curGraph->setData(xs, ys);

	ui->m_plot->xAxis->setVisible(true);
	ui->m_plot->yAxis->setVisible(true);
 
}

void ImageShowDialogClass::load_double_MatrixX_data(Eigen::MatrixXd data, QString name)
{
	this->setWindowTitle(name);
	this->graphclass = LAMPDATASHOWCLASS::LAMPColorMap;
	int ny = data.rows();     // 行数
	int nx = data.cols();  // 列数
	// 创建 Color Map
	QCPColorMap* colorMap = new QCPColorMap(ui->m_plot->xAxis, ui->m_plot->yAxis);
	colorMap->data()->setSize(nx, ny); // 设置 Color Map 的大小
	colorMap->data()->setRange(QCPRange(0, nx), QCPRange(0, ny)); // 设置坐标轴的范围

	// 填充数据
	for (int xIndex = 0; xIndex < nx; ++xIndex) {
		for (int yIndex = 0; yIndex < ny; ++yIndex) {
			double magnitude = data(yIndex, xIndex); // 或者使用 std::arg() 获取相位
			colorMap->data()->setCell(xIndex, yIndex,magnitude);
		}
	}

	colorMap->setGradient(QCPColorGradient::gpJet);
	colorMap->rescaleDataRange(true);
	ui->m_plot->rescaleAxes();
	ui->m_plot->replot();

}

void ImageShowDialogClass::load_double_MatrixX_data(Eigen::MatrixXd X, Eigen::MatrixXd Y, Eigen::MatrixXd data, QString name)
{
	this->graphclass = LAMPDATASHOWCLASS::LAMPColorMap;
	int nx = data.cols();     // 行数
	int ny = data.rows();  // 列数
	// 创建 Color Map
	ui->m_plot->xAxis->setRange(X(0, 0), X(0, nx - 1));
	ui->m_plot->yAxis->setRange(Y(0, 0), Y(ny - 1, 0));
	QCPColorMap* colorMap = new QCPColorMap(ui->m_plot->xAxis, ui->m_plot->yAxis);
	colorMap->data()->setSize(ny, nx); // 设置 Color Map 的大小
	colorMap->data()->setRange(QCPRange(X(0,0), X(0,nx-1)), QCPRange(Y(0,0),Y(ny-1,0))); // 设置坐标轴的范围
	// 填充数据
	for (int xIndex = 0; xIndex < nx; ++xIndex) {
		for (int yIndex = 0; yIndex < ny; ++yIndex) {
			double magnitude = data(yIndex, xIndex); // 或者使用 std::arg() 获取相位
			colorMap->data()->setCell(yIndex, xIndex, magnitude);
		}
	}

	// add a color scale:
	QCPColorScale* m_colorScale = new QCPColorScale(m_plot);
	m_plot->plotLayout()->addElement(0, 1, m_colorScale);
	m_colorScale->setType(QCPAxis::atRight);
	colorMap->setColorScale(m_colorScale);

	colorMap->setGradient(QCPColorGradient::gpJet);
	colorMap->rescaleDataRange(true);
	ui->m_plot->rescaleAxes();
	ui->m_plot->replot();
}

void ImageShowDialogClass::load_double_data(float* data, long rows, long cols, QString name)
{
	Eigen::MatrixXd dataArr = Eigen::MatrixXd::Zero(rows, cols);
	for (long i = 0; i < rows; i++) {
		for (long j = 0; j < cols; j++) {
			dataArr(i, j) = data[i * cols + j];
		}
	}
	this->load_double_MatrixX_data(dataArr, name);
}

void ImageShowDialogClass::load_double_data(double* data, long rows, long cols, QString name)
{
	Eigen::MatrixXd dataArr = Eigen::MatrixXd::Zero(rows, cols);
	for (long i = 0; i < rows; i++) {
		for (long j = 0; j < cols; j++) {
			dataArr(i, j) = data[i * cols + j];
		}
	}
	this->load_double_MatrixX_data(dataArr, name);
}

void ImageShowDialogClass::load_double_data(float* Xs, float* Ys, float* data, long rows, long cols, QString name)
{

	Eigen::MatrixXd dataArr = Eigen::MatrixXd::Zero(rows, cols);
	Eigen::MatrixXd dataX = Eigen::MatrixXd::Zero(rows, cols);
	Eigen::MatrixXd dataY = Eigen::MatrixXd::Zero(rows, cols);
	for (long i = 0; i < rows; i++) {
		for (long j = 0; j < cols; j++) {
			dataArr(i, j) = data[i * cols + j];
			dataX(i, j) = Xs[i * cols + j];
			dataY(i, j) = Ys[i * cols + j];
		}
	}
	this->load_double_MatrixX_data(dataX,dataY,dataArr, name);


}

void ImageShowDialogClass::remove_Data(QString name)
{
	for(size_t i=0;i<this->m_plot->graphCount();i++){
		if (this->m_plot->graph(i)->name() == name) {
			this->m_plot->removeGraph(i);
			this->m_plot->replot();
			return;
		}
	}
}

 

LAMPDATASHOWCLASS ImageShowDialogClass::getGraphClass(size_t i)
{
	if (this->m_plot->graphCount() == 0 || i > this->m_plot->graphCount())
	{
		return LAMPDATASHOWCLASS::NOWINDOWS;
	}
	QCPAbstractPlottable* plottable = this->ui->m_plot->plottable(i);
	if (dynamic_cast<QCPGraph*>(plottable)) {
		return LAMPDATASHOWCLASS::LAMPGraph;
	}
	else if (dynamic_cast<QCPScatterStyle*>(plottable)) {
		return LAMPDATASHOWCLASS::LAMPScatterStyle;
	}
	else if (dynamic_cast<QCPColorMap*>(plottable)) {
		return LAMPDATASHOWCLASS::LAMPColorMap;
	}
	else {
		return LAMPDATASHOWCLASS::NOWINDOWS;
	}
}
 

size_t ImageShowDialogClass::getGraphCount()
{
	return this->m_plot->graphCount();
}

void ImageShowDialogClass::on_action_descursor_close_trigged()
{
	this->desCursorflag = false;
}

void ImageShowDialogClass::on_action_Hlinecursor_close_trigged()
{
	this->HlineCursorflag = false;
}

void ImageShowDialogClass::on_action_VVlinecursor_close_trigged()
{
	this->VlineCursorflag = false;
}

void ImageShowDialogClass::updateCursor(QMouseEvent *event)
{
	if (this->desCursorflag &&this->HlineCursorflag &&this->VlineCursorflag) {
		//下面的代码就是设置游标的外观
		this->setMouseTracking(false);
	}
	else {
		// 准备获取数据
		QPoint pos = event->pos();
		double x=this->m_plot->xAxis->pixelToCoord(pos.x()); // 将鼠标位置映射到图表坐标系中
		double y = this->m_plot->yAxis->pixelToCoord(pos.y());
		this->statusbar->showMessage(u8"X: "+QString::number(x,'f', 6)+" y: "+QString::number(y, 'f', 6));
		if (this->desCursorflag) {
			if (this->graphclass == LAMPDATASHOWCLASS::LAMPColorMap) {
				QCPColorMap* colorMap = dynamic_cast<QCPColorMap*>(this->ui->m_plot->plottable(0));
				double dataValue = colorMap->data()->data(x, y);
				this->desCursor->updateCursorContent(u8"X: " + QString::number(x, 'f', 6) + " y: " + QString::number(y, 'f', 6) +u8"\n"	+u8"DataValue: "+QString::number(dataValue));
			

				double xMin = this->m_plot->xAxis->range().lower;
				double xMax = this->m_plot->xAxis->range().upper;
				double yMin = this->m_plot->yAxis->range().lower;
				double yMax = this->m_plot->yAxis->range().upper;

				long XCount = 1000;
				double xdelte = (xMax - xMin) / (XCount-1);
				double ydelte = (yMax - yMin) / (XCount-1);

				qDebug() << xMin << "," << xMax << " " << yMin << "," << yMax << "  " << XCount<<" "<<xdelte<<" "<<ydelte;

				QVector<double> Hx(XCount);
				QVector<double> Hy(XCount);
				QVector<double> Vx(XCount);
				QVector<double> Vy(XCount);

				for (long i = 0; i < XCount; i++)
				{
					Hx[i] = i * xdelte + xMin;
					Hy[i] = colorMap->data()->data(Hx[i], y);
					Vx[i] = i * ydelte + yMin;
					Vy[i] = colorMap->data()->data(x, Vx[i]);
				}
 
				this->HlineCursor->UpdatePlotLine(Hx, Hy, u8"水平"); // 水平
				this->VlineCursor->UpdatePlotLine(Vx, Vy, u8"垂直"); // 垂直

			}
			else if (this->graphclass == LAMPDATASHOWCLASS::LAMPGraph) {
				
			}
			else if (this->graphclass == LAMPDATASHOWCLASS::LAMPScatterStyle) {
				
			}
			else {
				this->desCursor->updateCursorContent(u8"无法识别图像类型");
			}
		}
		if (this->HlineCursorflag) {

			 
		}
		if (this->VlineCursorflag) {

		}
	}
}


ImageShowCursorDesClass::ImageShowCursorDesClass(QWidget* parent)
{
	// 创建 QLabel
	label = new QLabel(this);
	QFont font;
	font.setPointSize(20);  // 设置字体大小为20
	label->setFont(font);
	// 创建布局
	QVBoxLayout* layout = new QVBoxLayout(this);
	layout->addWidget(label);

	// 设置布局
	setLayout(layout);
	this->resize(100, 50);
}

ImageShowCursorDesClass::~ImageShowCursorDesClass()
{
}

void ImageShowCursorDesClass::closeEvent(QCloseEvent* event)
{
	QDialog::closeEvent(event);
}


void ImageShowCursorDesClass::updateCursorContent(QString content) {
 
	this->label->setText(content);

}


ImageShowCursorLineClass::ImageShowCursorLineClass(QWidget* parent):QDialog(parent)
{
	this->menubar = new QMenuBar(this);
	//QMenu* toolMenu = this->menubar->addMenu(u8"工具");
	//QAction* action_add_compare_line = toolMenu->addAction(u8"添加对比数据");
	//QObject::connect(action_add_compare_line, SIGNAL(triggered()), this, SLOT(load_new_compare_line()));
 
	this->tracerEnable = false;
	this->tracer = nullptr;
	this->tracerXText = nullptr;
	this->tracerYText = nullptr;
	// 创建 QLabel
	this->customPlot = new QCustomPlot(this);
	
	// 创建布局
	QVBoxLayout* layout = new QVBoxLayout(this);
	layout->addWidget(this->customPlot);

	// 设置布局
	setLayout(layout);
	this->tracer = new QCPItemTracer(this->customPlot);
	this->tracerYText = new QCPItemText(this->customPlot);
	this->tracerXText = new QCPItemText(this->customPlot);
	QObject::connect(this->customPlot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(updateCursor(QMouseEvent*)));
	this->customPlot->legend->setVisible(true);
	this->setMinimumWidth(600);
	this->setMinimumHeight(400);
}

ImageShowCursorLineClass::~ImageShowCursorLineClass()
{

}

void ImageShowCursorLineClass::loadPlotLine(QVector<double> xs, QVector<double> dataValues,QString Name)
{
	if (dataValues.count() == 0) { return; }
	QCPGraph* graph = this->customPlot->addGraph();
	graph->setName(Name);
	graph->setData(xs, dataValues);
	double min_y = dataValues[0];
	double max_y = dataValues[0];
	for (size_t i = 0; i < dataValues.count(); i++) {
		min_y = min_y > dataValues[i] ? dataValues[i] : min_y;
		max_y = max_y < dataValues[i] ? dataValues[i] : max_y;
	}

	double min_x = xs[0];
	double max_x = xs[0];
	for (size_t i = 0; i < xs.count(); i++) {
		min_x = min_x > xs[i] ? xs[i] : min_x;
		max_x = max_x < xs[i] ? xs[i] : max_x;
	}
	customPlot->xAxis->setRange(min_x, max_x);
	customPlot->yAxis->setRange(min_y, max_y);
	customPlot->legend->setVisible(true);
	customPlot->replot();
	
	
	//下面的代码就是设置游标的外观
	this->setMouseTracking(true);
	tracer->setInterpolating(false);//禁用插值
	tracer->setPen(QPen(Qt::DashLine));//虚线游标
	tracer->setStyle(QCPItemTracer::tsPlus);//游标样式：十字星、圆圈、方框
	tracer->setBrush(Qt::red);//游标颜色
	tracer->setGraph(graph); // 确保游标跟随
	this->m_graphMap.insert(Name, graph);
	this->TrackName = Name;

}

void ImageShowCursorLineClass::UpdatePlotLine(QVector<double> xs, QVector<double> dataValues, QString Name)
{
	this->customPlot->clearGraphs();
	this->loadPlotLine(xs, dataValues, Name);
}

void ImageShowCursorLineClass::updateCursor(QMouseEvent* event)
{
	if (tracerEnable)//游标使能
	{
 
		double x = this->customPlot->xAxis->pixelToCoord(event->pos().x());//鼠标点的像素坐标转plot坐标
  
		tracer->setGraphKey(x);//设置游标的X值（这就是游标随动的关键代码）
		double traceX = tracer->position->key();
		double traceY = tracer->position->value();

		tracerXText->setText(QDateTime::fromMSecsSinceEpoch(traceX * 1000.0).toString("hh:mm:ss.zzz"));//游标文本框，指示游标的X值
		tracerYText->setText(QString::number(traceY));//游标文本框，指示游标的Y值

		////计算游标X值对应的所有曲线的Y值
		//for (int i = 0; i < this->customPlot->graphCount(); i++)
		//{
		//	QCPGraph* graph = dynamic_cast<QCPGraph*>(this->customPlot->plottable(i));
		//	//搜索左边离traceX最近的key对应的点，详情参考findBegin函数的帮助
		//	QCPDataContainer<QCPGraphData>::const_iterator coorPoint = graph->data().data()->findBegin(traceX, true);//true代表向左搜索
		//	qDebug() << QString("graph%1对应的Y值是").arg(i) << coorPoint->value;
		//}
	}
 
 
}

void ImageShowCursorLineClass::closeEvent(QCloseEvent* event)
{
	QDialog::closeEvent(event);
}

void  ImageShowCursorLineClass::xAxisRangeChanged(QCPRange range) {
	this->customPlot->xAxis->setRange(range);
	customPlot->replot();
}

void  ImageShowCursorLineClass::yAxisRangeChanged(QCPRange range) {
	this->customPlot->yAxis->setRange(range);
	customPlot->replot();
}

void ImageShowCursorLineClass::on_SwichTracerGraph_Name()
{
}

void ImageShowCursorLineClass::load_new_compare_line()
{



}
 