#include "core/version.h"
#include "gui/widgets/text.h"
#include "gui/dialog/about.h"
#include "core/json.h"
#include "pugixml.hpp"
#include <curl/curl.h>
#include <QFont>
#include <QTextCharFormat>
#include <QTextBrowser>
#include <QTextCursor>
#include <QHBoxLayout>

#define CONCAT_VERSION_NX(major, minor, patch) \
	("v" #major "." #minor "." #patch)

#define CONCAT_VERSION(major, minor, patch) \
	CONCAT_VERSION_NX(major, minor, patch)

#define SET_TITLE_FONT(font, format, cursor) \
	{ \
		font = cursor.charFormat().font(); \
		font.setPointSize(10); \
		format.setFont(font); \
		cursor.setCharFormat(format); \
	}

#define SET_PARAGRAPH_FONT(font, format, cursor) \
	{ \
		font = cursor.charFormat().font(); \
		font.setPointSize(8); \
		format.setFont(font); \
		cursor.setCharFormat(format); \
	}

#define SET_FONT_BOLD(font, format, cursor) \
	{ \
		font = cursor.charFormat().font(); \
		font.setBold(true); \
		format.setFont(font); \
		cursor.setCharFormat(format); \
	}

#define UNSET_FONT_BOLD(font, format, cursor) \
	{ \
		font = cursor.charFormat().font(); \
		font.setBold(false); \
		format.setFont(font); \
		cursor.setCharFormat(format); \
	}

#define SET_FORMAT_HYPERLINK(format, cursor, link) \
	{ \
		format.setAnchor(true); \
		format.setAnchorHref(link); \
		cursor.setCharFormat(format); \
	}
#define UNSET_FORMAT_HYPERLINK(format, cursor) \
	{ \
		format.setAnchor(false); \
		format.setAnchorHref(""); \
		cursor.setCharFormat(format); \
	}

AboutWindow::AboutWindow(QWidget* parent) : QDialog(parent) {
	setWindowTitle(tr("About Minori"));
	setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
	setLayout(new QHBoxLayout);

	QPalette pal = QPalette();
	pal.setColor(QPalette::Window, pal.color(QPalette::Base));
	setPalette(pal);
	setAutoFillBackground(true);

	QFont font;
	QTextCharFormat format;
	QTextBrowser* paragraph = new QTextBrowser(this);
	paragraph->setOpenExternalLinks(true);
	paragraph->setFrameShape(QFrame::NoFrame);
	paragraph->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
	paragraph->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
	QTextCursor cursor = paragraph->textCursor();
	SET_TITLE_FONT(font, format, cursor);
	SET_FONT_BOLD(font, format, cursor);
	cursor.insertText("Minori");
	UNSET_FONT_BOLD(font, format, cursor);
	cursor.insertText(" " MINORI_VERSION);
	SET_PARAGRAPH_FONT(font, format, cursor);
	cursor.insertBlock();
	cursor.insertBlock();
	SET_FONT_BOLD(font, format, cursor);
	cursor.insertText(tr("Author:"));
	UNSET_FONT_BOLD(font, format, cursor);
	cursor.insertBlock();
	cursor.insertText(tr("Paper"));
	cursor.insertBlock();
	cursor.insertBlock();
	SET_FONT_BOLD(font, format, cursor);
	cursor.insertText(tr("Third party components:"));
	UNSET_FONT_BOLD(font, format, cursor);
	cursor.insertBlock();
	SET_FORMAT_HYPERLINK(format, cursor, "https://github.com/nlohmann/json");
	cursor.insertText(tr("JSON for Modern C++ ") + CONCAT_VERSION(NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH));
	UNSET_FORMAT_HYPERLINK(format, cursor);
	cursor.insertText(", ");
	{
		curl_version_info_data* data = curl_version_info(CURLVERSION_NOW);
		SET_FORMAT_HYPERLINK(format, cursor, "https://curl.se/");
		cursor.insertText(tr("libcurl v") + data->version);
		UNSET_FORMAT_HYPERLINK(format, cursor);
		cursor.insertText(", ");
	}
	SET_FORMAT_HYPERLINK(format, cursor, "https://p.yusukekamiyamane.com/");
	cursor.insertText(tr("Fugue Icons ") + CONCAT_VERSION(3, 5, 6));
	UNSET_FORMAT_HYPERLINK(format, cursor);
	cursor.insertText(", ");
	SET_FORMAT_HYPERLINK(format, cursor, "https://pugixml.org/");
	cursor.insertText(tr("pugixml v") + QString::number(PUGIXML_VERSION / 1000) + "." + QString::number(PUGIXML_VERSION / 10 % 100) + "." + QString::number(PUGIXML_VERSION % 10));
	UNSET_FORMAT_HYPERLINK(format, cursor);
	cursor.insertText(", ");
	SET_FORMAT_HYPERLINK(format, cursor, "https://github.com/erengy/anitomy");
	cursor.insertText(tr("Anitomy"));
	UNSET_FORMAT_HYPERLINK(format, cursor);
	cursor.insertBlock();
	cursor.insertBlock();
	SET_FONT_BOLD(font, format, cursor);
	cursor.insertText(tr("Links:"));
	UNSET_FONT_BOLD(font, format, cursor);
	cursor.insertBlock();
	layout()->addWidget(paragraph);
}
