#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qtabwidget.h>
#include <QSizePolicy>
#include <QHBoxLayout>
#include "event/EventCenter.h"
#include "tabformwidget.h"
#include "SelectFormWidget.h"
#include "ScanFormWidget.h"
#include "guimessagedialog.h"
#include "device/DeviceManager.h"
#include "errorhandle/GUIErrorHandle.h"
#include "loginwindow.h"
#include <QTextEdit>
#include <QScrollBar>
#include "models/User.h"
#include "AdminSettingForm.h"
#include "appvals/AppGlobalValues.h"
#include <fstream>
#include <sstream>
#include <QDateTime>
#include "TopBarWidget.h"
#include <QGestureEvent>
#include <QDockWidget>

void MainWindow::QMessageOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{

	std::cout << msg.toStdString().c_str() << std::endl;

	//QByteArray localMsg = msg.toLocal8Bit();
	//switch (type) {
	//case QtDebugMsg:
	//	fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
	//	break;
	//case QtInfoMsg:
	//	fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
	//	break;
	//case QtWarningMsg:
	//	fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
	//	break;
	//case QtCriticalMsg:
	//	fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
	//	break;
	//case QtFatalMsg:
	//	fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
	//	abort();
	//}
}

MainWindow::MainWindow(QWidget* parent) :
	QMainWindow(parent),
	ui(new Ui::MainWindow)
{

	this->loadStyleSheet("Dark2");
	ui->setupUi(this);
	tab = new QTabWidget(this);
	tab->setTabPosition(QTabWidget::South);
	tab->setContentsMargins(0, 0, 0, 0);
	connect(EventCenter::Default(), &EventCenter::PatientSelected, [=](QObject* sender, QObject* data) {
		tab->setCurrentIndex(1);
		});
	SelectFormWidget* select_form = new SelectFormWidget(this);
	tab->addTab(select_form, tr("Select"));
	ScanFormWidget* scan_form = new ScanFormWidget(this);
	tab->addTab(scan_form, tr("Scan"));
	TabFormWidget* verify_form = new TabFormWidget(this);
	tab->addTab(verify_form, tr("Verify"));
	tab->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	QVBoxLayout* layout = new QVBoxLayout(this);
	layout->setMargin(0);
	layout->setSpacing(0);
	QWidget* top = new TopBarWidget(this);
	top->setObjectName("topbarWidget");
	layout->addWidget(top);
	layout->addWidget(tab);

	ui->centralWidget->setLayout(layout);
	this->setWindowFlags(Qt::Window);
	connect(EventCenter::Default(), &EventCenter::DeviceErrorRaise, [=](QObject* parent, QObject* msg) {
		if (!this->ui->centralWidget->isVisible()) return;
		//默认旧模式
		if (!msgDialog) {
			msgDialog = new GUIMessageDialog(this);
			//msgDialog->setStyleSheet(style);
		}
		if (msg) {
			QString* str = (QString*)msg;
			msgDialog->showMessage(*str);
		}
		else {
			msgDialog->showMessage("Something went error!");
		}
		msgDialog->stopLoading();
		msgDialog->showExitButton();
		if (msgDialog->isHidden()) {
			msgDialog->setWindowModality(Qt::NonModal);
			msgDialog->exec();
		}
		});
	connect(EventCenter::Default(), &EventCenter::InvokeOperationStart, [=](QObject*, QObject* msg) {
		if (msgDialog) {
			msgDialog->hide();
			delete msgDialog;
		}
		msgDialog = new GUIMessageDialog(this);
		if (msg)
		{
			QString* str = (QString*)msg;
			msgDialog->showMessage(*str);
		}
		else {
			msgDialog->hideMessage();
		}
		msgDialog->hideExitButton();
		msgDialog->startLoading();
		AppGlobalValues::setInProcessing(true);
		//		msgDialog->showFullScreen();
		if (msgDialog->isHidden()) {
			msgDialog->show();
		}
		});
	connect(EventCenter::Default(), &EventCenter::InvokeOperationProgress, [=](QObject*, QObject* msg) {
		if (!msgDialog) msgDialog = new GUIMessageDialog(this);
		if (msg)
		{
			QVariant* var = (QVariant*)msg;
			msgDialog->showMessage(QString("Scanning %1%").arg((int)(var->toFloat() * 100.0f)));
		}
		else {
			msgDialog->hideMessage();
		}
		//		msgDialog->showFullScreen();
		if (msgDialog->isHidden())msgDialog->show();
		});
	connect(EventCenter::Default(), &EventCenter::InvokeOperationEnd, [=]() {
		if (!msgDialog) return;
		if (!msgDialog->isHidden())msgDialog->accept();
		delete msgDialog;
		msgDialog = nullptr;
		AppGlobalValues::setInProcessing(false);
		});
	connect(EventCenter::Default(), &EventCenter::RequestLogin, [=](QObject*, QObject* msg) {
		this->requestLogin();
		});
	connect(EventCenter::Default(), &EventCenter::LoginRoleChanged, [=](QObject*, QObject*) {
		if (User::Current()->isAdmin())
		{
			if (admin_tab_index == -1)
			{
				AdminSettingForm* form = new AdminSettingForm(this);
				admin_tab_index = tab->addTab(form, tr("Settings"));
			}
		}
		else {
			if (admin_tab_index != -1) {
				tab->removeTab(admin_tab_index);
				admin_tab_index = -1;
			}
		}
		qApp->processEvents();
		});
	connect(DeviceManager::Default(), &DeviceManager::raiseGlobalError, this, &MainWindow::triggerError);
	GUIErrorHandle::Default()->init();
	l = new LoginWindow(this);
	t = QThread::create([]() {
		QThread::sleep(10);
		int f = 0x00100001;
		for (int i = 0; i < 8; ++i) {
			QThread::sleep(10);
			f = f << (i * 4);
			printf("invoke %d\r\n", f);
			char* v = (char*)&f;
			QString msg;
			msg.append("w ");
			msg.append(v[0]);
			msg.append(v[1]);
			msg.append(v[2]);
			msg.append(v[3]);
			EventCenter::Default()->triggerEvent(GUIErrorRaise, nullptr, (QObject*)&msg);
		}
		});
	t->start();
	l->showFullScreen();
	centerWidgetHide();
	connect(EventCenter::Default(), &EventCenter::ReloadLanguage, [=]() {

		tab->setTabText(0, tr("Select"));
		tab->setTabText(1, tr("Scan"));
		tab->setTabText(2, tr("Verify"));
		tab->setTabText(3, tr("Settings"));

		});
}



MainWindow::~MainWindow()
{
	t->terminate();
	delete t;
	delete ui;
	delete redir;
}
void MainWindow::changeEvent(QEvent* event)
{
	if (event->type() == QEvent::LanguageChange)
	{
		ui->retranslateUi(this);
	}

	QWidget::changeEvent(event);
}


void MainWindow::loadStyleSheet(const QString& sheetName)
{
	QFile file(":/stylesheet/" + sheetName + ".css");
	file.open(QFile::ReadOnly);
	if (file.isOpen())
	{
		QString styleSheet = this->styleSheet();
		styleSheet += QLatin1String(file.readAll());
		this->setStyleSheet(styleSheet);
	}
}

void MainWindow::centerWidgetHide() {
	ui->centralWidget->setVisible(false);
}

void MainWindow::centerWidgetShow() {

	ui->centralWidget->setVisible(true);
}


QTextEdit* MainWindow::getEdit()
{
	return this->console;
}

void MainWindow::requestLogin() {

	l->clearInputData();
	l->setWindowModality(Qt::WindowModal);
	l->showFullScreen();
	this->centerWidgetHide();
	while (l->result() != QDialog::Accepted)
	{
		l->exec();
	}
	l->setResult(QDialog::Rejected);
	this->centerWidgetShow();
}

void MainWindow::debugConsoleOn() {

	debugMode = true;
	dockWidget = new QDockWidget(this);
	dockWidget->setObjectName(QString::fromUtf8("dockWidget"));
	dockWidget->setAllowedAreas(Qt::RightDockWidgetArea);
	this->addDockWidget(static_cast<Qt::DockWidgetArea>(2), dockWidget);

	QTextEdit* text_edit = new QTextEdit(this);
	text_edit->setFocusPolicy(Qt::NoFocus);
	dockWidget->setWidget(text_edit);

	const QString edit_style =
		"QScrollBar:vertical{border: 0px solid grey; background:#2d2d2d; width: 15px; margin: 0px 0 0px 0; }"
		"QScrollBar::handle:vertical{background:#5a5a5a;min-height: 25px;}"
		"QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical{background:#2d2d2d;}";
	text_edit->verticalScrollBar()->setStyleSheet(edit_style);
	//clear buffer before redirect;
	this->console = text_edit;
}

void MainWindow::triggerError(const QString& msg) {
	QString s(msg);
	qDebug() << "invoke trigger error slot msg:" << msg;
	EventCenter::Default()->triggerEvent(GUIErrorRaise, nullptr, (QObject*)&s);
}

void MainWindow::grabGestures(const QList<Qt::GestureType>& gestures)
{
	//! [enable gestures]
	foreach(Qt::GestureType gesture, gestures)
		grabGesture(gesture);
	//! [enable gestures]
}

//! [event handler]
bool MainWindow::event(QEvent* event)
{
	if (event->type() == QEvent::Gesture)
		return gestureEvent(static_cast<QGestureEvent*>(event));
	return QWidget::event(event);
}

bool MainWindow::gestureEvent(QGestureEvent* event)
{
	//qCDebug(lcExample) << "gestureEvent():" << event;
	if (QGesture* swipe = event->gesture(Qt::SwipeGesture))
		swipeTriggered(static_cast<QSwipeGesture*>(swipe));
	if (QGesture* pan = event->gesture(Qt::PanGesture))
		panTriggered(static_cast<QPanGesture*>(pan));
	//if (QGesture* pinch = event->gesture(Qt::PinchGesture))
		//pinchTriggered(static_cast<QPinchGesture*>(pinch));
	return true;
}

void MainWindow::panTriggered(QPanGesture* gesture)
{

	if (gesture->state() == Qt::GestureFinished) {
		QPointF delta = gesture->offset();
		int index = tab->currentIndex();
		if (delta.x() > 50) {

			index--;
			if (index >= 0) {
				tab->setCurrentIndex(index);
			}
		}
		if (delta.x() < -50)
		{
			index++;
			if (index < tab->count()) {
				tab->setCurrentIndex(index);
			}
		}
		qDebug() << "panTriggered" << index;
	}
}
void MainWindow::swipeTriggered(QSwipeGesture* gesture)
{

	if (gesture->state() == Qt::GestureFinished) {
		//if (gesture->horizontalDirection() == QSwipeGesture::Right) {
		//	int index = tab->currentIndex();
		//	index--;
		//	if (index >= 0) {
		//		tab->setCurrentIndex(index);
		//	}

		//}
		//if (gesture->horizontalDirection() == QSwipeGesture::Left) {
		//	int index = tab->currentIndex();
		//	index++;
		//	if (index < tab->count()) {
		//		tab->setCurrentIndex(index);
		//	}
		//}
		if (gesture->verticalDirection() == QSwipeGesture::Down) {
			if (debugMode)
			{
				dockWidget->show();
			}
		}
		if (gesture->verticalDirection() == QSwipeGesture::Up) {
			if (debugMode)
			{
				dockWidget->hide();
			}
		}
		//update();
	}
}