#include "desktop.h"
#include "SH_server_base.h"
#include <qad_types.h>
#include <QTemporaryFile>
#include <QFile>
#include <QDebug>
#include <QStyle>
#include <QPainter>
#include <QGridLayout>
#include <QApplication>
#include <QScreen>
#include <QDesktopServices>
#ifdef Q_OS_WINDOWS
#  include <windows.h>
#  include <winreg.h>
HKEY openReg(HKEY root, const QString & name) {
	HKEY key = nullptr;
	if (RegCreateKeyExA(root, name.toLatin1().data(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, NULL) != ERROR_SUCCESS) {
		piCout << errorString();
		return nullptr;
	}
	return key;
}
bool writeReg(HKEY key, LPCWSTR name, const QString & value) {
	QVector<wchar_t> str(value.size() + 1);
	value.toWCharArray(str.data());
	if (RegSetValueExW(key, name, 0, REG_SZ, (LPBYTE)(str.data()), str.size() * sizeof(wchar_t)) != ERROR_SUCCESS) {
		piCout << errorString();
		return false;
	}
	return true;
}
#endif


QSize prefSize(const QWidget * w) {return QSize(300, 30) * appScale(w);}


NotificationWidget::NotificationWidget(): QFrame() {
	setFrameShape(QFrame::StyledPanel);
	setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
	lbl = new QLabel();
	lim = new QLabel();
	title = new QLabel("SHS Server");
	btn = new QToolButton();
	QGridLayout * l = new QGridLayout();
	lbl->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
	lbl->setWordWrap(true);
	lbl->setWordWrap(true);
	lim->setPixmap(QPixmap(":/icons/SH_pult_remote.png"));
	lim->setFixedSize(preferredIconSize(1.5, this));
	lim->setScaledContents(true);
	title->setStyleSheet("font:bold;");
	btn->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
	l->addWidget(lim, 0, 0);
	l->addWidget(title, 0, 1);
	//l->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Preferred), 0, 1);
	l->addWidget(btn, 0, 2);
	l->addWidget(lbl, 1, 0, 1, 3);
	setLayout(l);
	setWindowOpacity(0.85);
	connect(btn, SIGNAL(clicked(bool)), this, SLOT(deleteLater()));
}


NotificationWidget::~NotificationWidget() {
}


void NotificationWidget::setText(const QString & t) {
	lbl->setText(t);
}


QSize NotificationWidget::sizeHint() const {
	return prefSize(this);
}


void NotificationWidget::mousePressEvent(QMouseEvent * e) {
	QFrame::mousePressEvent(e);
	if (btn->underMouse()) return;
	emit clicked();
	deleteLater();
}




DesktopLayer::DesktopLayer(): QObject(), settings("SHS", "Pult") {
	pult_window = 0;
	pult_tray = 0;
	btn_close = new QToolButton();
	btn_close->setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
	btn_close->setText("Close all");
	connect(btn_close, SIGNAL(clicked(bool)), this, SLOT(closeAll()));
	QDesktopServices::setUrlHandler("shsserver", this, SLOT(URLTriggered(QUrl)));
	registerURI();
}


DesktopLayer::~DesktopLayer() {
	delete btn_close;
	qDeleteAll(widgets);
	widgets.clear();
}


void DesktopLayer::setPultTray(QSystemTrayIcon * t) {
	pult_tray = t;
	if (!pult_tray) return;
	tray_im = pult_tray->icon().pixmap(pult_tray->icon().actualSize(QSize(1024, 1024))).toImage();
}


DesktopLayer * DesktopLayer::instance() {
	static DesktopLayer * ret = new DesktopLayer();
	return ret;
}


void DesktopLayer::showWidgets() {
	QRect r = QApplication::primaryScreen()->availableGeometry();
	//qDebug() << r;
	int margin = appScale(pult_window) * 8;
	int y = r.height();
	for (int i = widgets.size() - 1; i >= 0; --i) {
		NotificationWidget * w = widgets[i];
		w->adjustSize();
		y -= w->height() + margin;
		w->move(r.width() - w->width() - margin, y);
		w->show();
	}
	btn_close->resize(prefSize(btn_close));
	y -= btn_close->height() + margin;
	btn_close->move(r.width() - btn_close->width() - margin, y);
	btn_close->setVisible(widgets.size() > 1);
	setTrayImage();
}


void DesktopLayer::setTrayImage() {
	if (!pult_tray) return;
	QImage im = tray_im;
	if (!widgets.isEmpty()) {
		QPainter p(&im);
		int w = im.width(), h = im.height();
		p.setPen(Qt::NoPen);
		p.setBrush(QColor(0xa0a0ff));
		QRectF r(w/2, h/2, w/2.1, h/2.1);
		p.drawRoundedRect(r, 50, 50, Qt::RelativeSize);
		p.setPen(Qt::black);
		QFont f("DejaVu Sans");
		f.setPixelSize(r.height() / 1.1);
		p.setFont(f);
		p.drawText(r, Qt::AlignCenter, QString::number(widgets.size()));
	}
	pult_tray->setIcon(QIcon(QPixmap::fromImage(im)));
}


void DesktopLayer::registerURI() {
#if defined(Q_OS_WINDOWS)
	HKEY key = openReg(HKEY_CURRENT_USER, "SOFTWARE\\Classes\\shsserver");
	if (!key) return;
	writeReg(key, NULL, "URL:shsserver");
	writeReg(key, L"URL Protocol", "");
	RegCloseKey(key);
	key = openReg(HKEY_CURRENT_USER, "SOFTWARE\\Classes\\shsserver\\shell\\open\\command");
	if (!key) return;
	writeReg(key, NULL, "\"" + QApplication::applicationFilePath().replace('/', "\\") + "\" --address \"%1\"");
	RegCloseKey(key);
#elif defined(Q_OS_WINDOWS)
#endif
}


void DesktopLayer::closeAll() {
	foreach (NotificationWidget * w, widgets)
		w->deleteLater();
	widgets.clear();
	btn_close->hide();
}


void DesktopLayer::clicked() {
//	qDebug() << "clicked";
	if (!pult_window) return;
	pult_window->showNormal();
	//if (pult_window->windowState() == Qt::WindowMinimized)
//	qDebug() << pult_window->windowState();
//	pult_window->window()->showNormal();
	pult_window->activateWindow();
	pult_window->raise();
	pult_window->setFocus();
}


void DesktopLayer::deleted(QObject * o) {
	widgets.removeAll((NotificationWidget*)o);
	showWidgets();
}


void DesktopLayer::URLTriggered(QUrl url) {
	qDebug() << "url" << url;
}


void DesktopLayer::notify(QString s) {
	if (!pult_window) return;
	NotificationWidget * w = new NotificationWidget();
	connect(w, SIGNAL(clicked()), this, SLOT(clicked()));
	connect(w, SIGNAL(destroyed(QObject*)), this, SLOT(deleted(QObject*)));
	w->setText(s);
	widgets << w;
	showWidgets();
}

