#include "gui/dialog/about.h"
#include "core/json.h"
#include "core/version.h"
#include "core/session.h"
#include "core/strings.h"
#include "gui/widgets/text.h"
#include "pugixml.hpp"
#include <QFont>
#include <QHBoxLayout>
#include <QTextBrowser>
#include <QTextCharFormat>
#include <QTextCursor>
#include <QCoreApplication>
#include <curl/curl.h>
#ifdef WIN32
#include "sys/win32/dark_theme.h"
#endif

template <typename T, size_t N>
constexpr size_t array_size(T (&)[N]) {
	return N;
}

/* used for JSON for Modern C++ */
#define CONCAT_VERSION_NX(major, minor, patch) "v" #major "." #minor "." #patch
#define CONCAT_VERSION(major, minor, patch) CONCAT_VERSION_NX(major, minor, patch)

/* Ahhh, my dumb little hack to get this to be constexpr :) */
static constexpr const char pugixml_version[] = {
	PUGIXML_VERSION / 1000 % 10 + '0', /* Major */
	'.',
	PUGIXML_VERSION / 100 % 10 + '0', /* Minor */
	PUGIXML_VERSION / 10 % 10 + '0',
	'.',
	PUGIXML_VERSION % 10 + '0', /* Patch */
	'\0'
};

const char* get_curl_version() {
	const curl_version_info_data* data = curl_version_info(CURLVERSION_NOW);
	return data->version;
}

AboutWindow::AboutWindow(QWidget* parent) : QDialog(parent) {
	setMinimumSize(641, 325);
	setWindowTitle(tr("About Minori"));
	setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
	setAutoFillBackground(true);

	QHBoxLayout* layout = new QHBoxLayout(this);

	/* we have to generate this on-the-fly for localization purposes */
	static const QString html = QString(
		"<body>"
		"  <h2 style=\"font-weight: normal;\"><strong>Minori</strong> " MINORI_VERSION "</h2>"
		"  <p>"
		"    <strong>" + QCoreApplication::tr("Author:") + "</strong><br>"
		"    Paper (@mrpapersonic)"
		"  </p>"
		"  <p>"
		"    <strong>" + QCoreApplication::tr("Third party components:") + "</strong><br>"
		    "<a href=\"https://curl.se/\">libcurl v") + get_curl_version() + "</a>"
		    ", "
		    "<a href=\"https://p.yusukekamiyamane.com/\">Fugue Icons v3.5.6</a>"
		    ", "
		    "<a href=\"https://github.com/erengy/anitomy\">Anitomy</a>"
		    ", "
		    "<a href=\"https://github.com/nlohmann/json\">JSON for Modern C++ " CONCAT_VERSION(NLOHMANN_JSON_VERSION_MAJOR,
			                                                                                   NLOHMANN_JSON_VERSION_MINOR,
			                                                                                   NLOHMANN_JSON_VERSION_PATCH) "</a>"
		    ", "
		    "<a href=\"https://pugixml.org/\">pugixml v" + pugixml_version + "</a>"
		    ", "
		    "<a href=\"https://github.com/pulzed/mINI\">mINI v0.9.14</a>"
		"  </p>"
		"<span>"
		"<strong>" + QCoreApplication::tr("Special thanks:") + "</strong>"
		"</span>"
		"  <ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 15px; margin-right: 0px; -qt-list-indent:0;\">"
		"    <li><strong>Eren Okka</strong> " + QCoreApplication::tr("for creating Taiga") + "</li>"
		"    <li><strong>Alex Huszagh</strong> " + QCoreApplication::tr("and") + " <strong>Colin Duquesnoy</strong> " +
		        QCoreApplication::tr("for creating BreezeStyleSheets, on which the dark theme in this program is "
		        "based off of") + "</li>"
		"    <li><strong>Andy Brice</strong> " + QCoreApplication::tr("for providing some sample code for "
		        "detecting dark mode on Windows and macOS") + "</li>"
		"    <li><strong>Manuel Wudka-Robles</strong> " + QCoreApplication::tr("for providing information on "
		        "getting open file descriptors on macOS") + "</li>"
		"  </ul>"
		"</body>";

	{
		QPalette pal = QPalette();
		pal.setColor(QPalette::Window, pal.color(QPalette::Base));
		setPalette(pal);
	}

	{
		QTextBrowser* paragraph = new QTextBrowser(this);
		paragraph->setOpenExternalLinks(true);
		paragraph->setFrameShape(QFrame::NoFrame);
		paragraph->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
		paragraph->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
		paragraph->setHtml(html);

		layout->addWidget(paragraph);
	}
}

void AboutWindow::showEvent(QShowEvent* event) {
	QDialog::showEvent(event);
#ifdef WIN32
	win32::SetTitleBarsToBlack(session.config.theme.IsInDarkTheme());
#endif
}

#include "gui/dialog/moc_about.cpp"
