//
// Created by Krad on 2021/10/8.
//

#include "ScanFormWidget.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QToolButton>
#include "ui_tabformwidget.h"
#include "guimacros.h"
#include "patientinformationform.h"
#include <QButtonGroup>
#include "event/EventCenter.h"
#include <QImage>
#include <QPainter>
#include <qdebug.h>
#include "log/UserOperationLog.h"
#include <QLabel>

#ifdef WIN32
#else
#include <cmath>
#endif

ScanFormWidget::ScanFormWidget(QWidget* parent) : TabFormWidget(parent) {
	const char* style = "QWidget#PatientInformationForm{min-width:300px;max-width:300px; margin-right:10}"
		"QWidget#patientinformation_panel{ border-right:1px solid #0078d8}"
		"QWidget#patientinformation_panel QLabel{font-size:20px; }"
		"QWidget#param_widget{min-width:300px;max-width:300px;border-left:1px solid #0078d8}"
		"QWidget#broadcast_widget{border:2px solid #515151; border-radius: 20px; background-color:black}"
		"QWidget#broadcast_widget QLabel{background-color:black}"
		"QLabel#lbl_protocol{font-size:32px; margin:0; color:silver}"
		"QLabel#lbl_title,QLabel#lbl_ptitle{font-size:20px;margin:0; border-bottom:1px solid silver}"
		"QLabel#lbl_end{font-size:20px;margin:0; border-top:1px solid #0078d8}"
		"QLabel#lbl_e{font-size:20px;}"
		"";
	this->setStyleSheet(this->styleSheet().append(style));
	QHBoxLayout* layout = new QHBoxLayout();
	ui->commandWidget->setLayout(layout);

	QLabel* lbl_Protocol = new QLabel(this);
	lbl_Protocol->setText(tr("Protocol"));
	lbl_Protocol->setAlignment(Qt::AlignTop);
	lbl_Protocol->setObjectName("lbl_protocol");
	layout->addWidget(lbl_Protocol);
	QWidget* spacerLine = new QWidget(this);
	spacerLine->setFixedWidth(2);
	spacerLine->setObjectName("verSpaceLine");
	layout->addWidget(spacerLine);
	ADD_TOOL_BTN(Left, ":/icons/left.png");
	ADD_TOOL_BTN(Right, ":/icons/right.png");
	btnLeft->setText(tr("LEFT"));
	btnRight->setText(tr("RIGHT"));

	QButtonGroup* group = new QButtonGroup(this);
	btnLeft->setCheckable(true);
	btnLeft->setChecked(true);
	btnRight->setCheckable(true);
	group->addButton(btnRight, 1);
	group->addButton(btnLeft, 0);
	layout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding));
	QWidget* spacerLine2 = new QWidget(this);
	spacerLine2->setFixedWidth(2);
	spacerLine2->setObjectName("verSpaceLine");
	layout->addWidget(spacerLine2);
	ADD_TOOL_BTN(Refresh, ":/icons/scan_e.png");
	ADD_TOOL_BTN(Preview, ":/icons/rec.png");

	ADD_TOOL_BTN(Stop, ":/icons/stop.png");
	ADD_TOOL_BTN(Scan, ":/icons/scan.png");

	btnRefresh->setText(tr("Refresh"));
	btnPreview->setText(tr("Preview"));
	btnStop->setText(tr("Stop"));
	btnScan->setText(tr("Scan"));

	QHBoxLayout* contentLayout = new QHBoxLayout();
	this->ui->contentWidget->setLayout(contentLayout);
	PatientInformationForm* patient_information = new PatientInformationForm(this);
	contentLayout->addWidget(patient_information);
	QWidget* param_widget = new QWidget(this);
	QWidget* broadcast_widget = new QWidget(this);
	broadcast_widget->setObjectName("broadcast_widget");
	QLabel* viewer = new QLabel(broadcast_widget);
	viewer->setObjectName("viewer");
	viewer->setFixedSize(800, 800);
	viewer->setText("");
	QHBoxLayout* viewerLayout = new QHBoxLayout(viewer);
	broadcast_widget->setLayout(viewerLayout);
	viewerLayout->addWidget(viewer);
	contentLayout->addWidget(broadcast_widget);
	param_widget->setObjectName("param_widget");
	QVBoxLayout* paramLayout = new QVBoxLayout(param_widget);
	QLabel* lblPreview = new QLabel(this);
	lblPreview->setText(tr("Preview Parameters"));
	lblPreview->setObjectName("lbl_title");
	paramLayout->addWidget(lblPreview);
	QLabel* lbl_e = new QLabel(this);
	lbl_e->setWordWrap(true);
	lbl_e->setObjectName("lbl_e");
	lbl_e->setText(tr("some settings\n\nparameters\n"));
	paramLayout->addWidget(lbl_e);
	QLabel* lbl_end = new QLabel(this);
	lbl_end->setObjectName("lbl_end");
	paramLayout->addWidget(lbl_end);
	QLabel* lblParams = new QLabel(this);
	lblParams->setText(tr("Scan Parameters"));
	lblParams->setObjectName("lbl_title");
	paramLayout->addWidget(lblParams);
	QLabel* lbl_e2 = new QLabel(this);
	lbl_e2->setWordWrap(true);
	lbl_e2->setObjectName("lbl_e");
	lbl_e2->setText(tr("some settings\n\nparameters\n"));
	paramLayout->addWidget(lbl_e2);
	QLabel* lbl_end2 = new QLabel(this);
	lbl_end2->setObjectName("lbl_end");
	paramLayout->addWidget(lbl_end2);
	paramLayout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding));
	contentLayout->addWidget(param_widget);
	pat_inf = patient_information;

	btnScan->setEnabled(false);
	btnRefresh->setEnabled(false);
	btnPreview->setEnabled(false);
	btnStop->setEnabled(false);


	//Events---------------------------------------------------------------
	connect(EventCenter::Default(), &EventCenter::PatientSelected, [=](QObject* sender, QObject* data) {
		if (unset)
		{
			btnScan->setEnabled(true);
			btnRefresh->setEnabled(true);
			btnPreview->setEnabled(true);
			btnStop->setEnabled(true);
			unset = false;
		}
		patient_information->setPatientInformation((PatientInformation*)data);
		});
	connect(EventCenter::Default(), &EventCenter::ResponseStop, [=](QObject* sender, QObject* data) {
		setPreviewing(false);
		});
	connect(EventCenter::Default(), &EventCenter::ResponsePreview, [=](QObject* sender, QObject* data) {
		setPreviewing(true);
		static const size_t Row = 140;
		static const size_t Col = 140;
		static const float pixelSpacing = 1.5f;
		static const float halfROIWidth = 100.0f;
		uchar c_data[Row][Col];
		uchar* data_ptr = c_data[0];
		for (int i = 0; i < Row; i++) {
			data_ptr = c_data[i];
			memset(data_ptr, 0, Col);
		}
		QImage img(c_data[0], Col, Row, QImage::Format_Grayscale8);
		viewer->setFixedSize(800, 800);
		QPixmap pic = QPixmap::fromImage(img).scaledToHeight(800, Qt::SmoothTransformation);
		QPainter painter(&pic);
		QPen pen;
		pen.setStyle(Qt::DashLine);
		pen.setWidth(3);
		QFont font("Futura");
		font.setPixelSize(26);
		font.setBold(true);
		painter.setFont(font);
		pen.setColor(QColor(255, 255, 0));
		painter.setPen(pen);
		painter.drawText(400 - 13 * 5, 400 + 13, "Loading...");
		viewer->setPixmap(pic);
		});

	connect(EventCenter::Default(), &EventCenter::ResponsePreviewData, [=](QObject* sender, QObject* data) {
		if (!data)return;
		static const size_t Row = 140;
		static const size_t Col = 140;
		static const float pixelSpacing = 1.5f;
		static const float halfROIWidth = 100.0f;
		QByteArray* array = (QByteArray*)data;
		uchar* raw_dataptr = (uchar*)array->data();
		uchar c_data[Row][Col];
		uchar* data_ptr = c_data[0];
		for (int i = 0; i < Row; i++) {
			data_ptr = c_data[i];
			memcpy(data_ptr, raw_dataptr, Col);
			raw_dataptr += Col;

		}
		raw_dataptr = (uchar*)array->data();
		QImage img(c_data[0], Col, Row, QImage::Format_Grayscale8);
		viewer->setFixedSize(800, 800);
		QPixmap pic = QPixmap::fromImage(img).scaledToHeight(800, Qt::SmoothTransformation);
		QPainter painter(&pic);
		QPen pen;
		pen.setColor(QColor(255, 255, 0, 100));
		pen.setStyle(Qt::DashLine);
		pen.setWidth(3);
		QFont font("Futura");
		font.setPixelSize(26);
		font.setBold(true);
		painter.setFont(font);
		painter.setPen(pen);
		static int borderSpacing = round(((pixelSpacing * (Row * 0.5f) - halfROIWidth) * (800.0f / (1.5f * 140.0f))));
		painter.drawLine(borderSpacing, borderSpacing, borderSpacing, 800 - borderSpacing);
		painter.drawLine(borderSpacing + 1, borderSpacing, 800 - borderSpacing, borderSpacing);
		painter.drawLine(borderSpacing + 1, 800 - borderSpacing, 800 - borderSpacing, 800 - borderSpacing);
		painter.drawLine(800 - borderSpacing, borderSpacing + 1, 800 - borderSpacing, 800 - borderSpacing - 1);
		pen.setColor(QColor(255, 255, 0));
		painter.setPen(pen);
		painter.drawText(335,40,QString("Previewing, current frame:%1").arg(++currentFrame));
		painter.drawText(borderSpacing + 13, 400 + 13, "L");
		painter.drawText(800 - borderSpacing - 30, 400 + 13, "R");
		painter.drawText(400 - 13, borderSpacing + 30, "H");
		painter.drawText(400 - 13, 800 - borderSpacing - 13, "F");
		painter.drawText(borderSpacing + 6, borderSpacing + 30, "ROI");
		viewer->setPixmap(pic);
		});
	connect(EventCenter::Default(), &EventCenter::PatientSelected, [=](QObject* sender, QObject* data) {
		patient_information->setPatientInformation((PatientInformation*)data);
		});
	connect(btnRefresh, &QToolButton::clicked, [=]() {
		QString patientInf(patient_information->getCurrentPatientJsonString(false));
		LOG_USER_OPERATION(StartRefresh);
		EventCenter::Default()->triggerEvent(GUIEvents::RequestEmptyScan, nullptr, (QObject*)(&patientInf));
		});
	connect(btnPreview, &QToolButton::clicked, [=]() {
		LOG_USER_OPERATION(StartPreview);
		EventCenter::Default()->triggerEvent(GUIEvents::RequestPreviewScan, nullptr, nullptr);
		});
	connect(btnScan, &QToolButton::clicked, [=]() {
		QString patientInf(patient_information->getCurrentPatientJsonString(false));
		LOG_USER_OPERATION(StartScan);
		EventCenter::Default()->triggerEvent(GUIEvents::RequestPatientScan, nullptr, (QObject*)(&patientInf));
		});
	connect(btnStop, &QToolButton::clicked, [=]() {
		LOG_USER_OPERATION(Stop);
		EventCenter::Default()->triggerEvent(GUIEvents::RequestStop, nullptr, nullptr);
		});

	connect(group, SIGNAL(buttonClicked(int)), this, SLOT(protocolChanged(int)));

	connect(EventCenter::Default(), &EventCenter::ReloadLanguage, [=]() {
		btnLeft->setText(tr("LEFT"));
		btnRight->setText(tr("RIGHT"));
		btnRefresh->setText(tr("Refresh"));
		btnPreview->setText(tr("Preview"));
		btnStop->setText(tr("Stop"));
		btnScan->setText(tr("Scan"));
		lbl_Protocol->setText(tr("Protocol"));
		lblPreview->setText(tr("Preview Parameters"));
		lblParams->setText(tr("Scan Parameters"));
		lbl_e->setText(tr("some settings\n\nparameters\n"));
		lbl_e2->setText(tr("some settings\n\nparameters\n"));
		});



	previewfunc = [=](bool val)->void {
		viewer->setVisible(val);
		btnPreview->setCheckable(val);
		btnPreview->setChecked(val);
		btnPreview->setEnabled(!val);
		btnRefresh->setEnabled(!val);
		btnScan->setEnabled(!val);
	};
}

ScanFormWidget::~ScanFormWidget() {

}

void ScanFormWidget::protocolChanged(int type) {
	printf("%d\r\n", type);
	pat_inf->setProtocol(type);
}

void ScanFormWidget::setPreviewing(bool val) {
	if (previewfunc) previewfunc(val);
}


