#include "gui/dialog/about.h"
#include "core/json.h"
#include "core/session.h"
#include "core/strings.h"
#include "gui/widgets/text.h"

#include "pugixml.hpp"

#include "utf8proc.h"

#include <QCoreApplication>
#include <QFont>
#include <QHBoxLayout>
#include <QTextBrowser>
#include <QTextCharFormat>
#include <QTextCursor>

#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;
}

static constexpr semver::version pugixml_version{PUGIXML_VERSION / 1000 % 10, PUGIXML_VERSION / 10 % 100,
                                                 PUGIXML_VERSION % 10};
static constexpr semver::version json_version{NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR,
                                              NLOHMANN_JSON_VERSION_PATCH};
static constexpr semver::version semver_version{SEMVER_VERSION_MAJOR, SEMVER_VERSION_MINOR, SEMVER_VERSION_PATCH};

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 */
	const QString html =
	    QString("<body>"
	            "  <h2 style=\"font-weight: normal;\"><strong>Minori</strong> v" +
	            Strings::ToQString(session.version.to_string()) +
	            "</h2>"
	            "  <p>"
	            "    <strong>" +
	            tr("Author:") +
	            "</strong><br>"
	            "    Paper (@mrpapersonic)"
	            "  </p>"
	            "  <p>"
	            "    <strong>" +
	            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++ v" +
	    Strings::ToQString(json_version.to_string()) +
	    "</a>"
	    ", "
	    "<a href=\"https://pugixml.org/\">pugixml v" +
	    Strings::ToQString(pugixml_version.to_string()) +
	    "</a>"
	    ", "
	    "<a href=\"https://github.com/Neargye/semver\">semver v" +
	    Strings::ToQString(semver_version.to_string()) +
	    "</a>"
	    ", "
	    "<a href=\"http://juliastrings.github.io/utf8proc/\">utf8proc v" +
	    Strings::ToQString(utf8proc_version()) +
	    "</a>"
	    ", parts of "
	    "<a href=\"https://github.com/erengy/anisthesia\">Anisthesia</a>"
	    "  </p>"
	    "<span>"
	    "<strong>" +
	    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> " +
	    tr("for creating <a href=\"https://taiga.moe/\">Taiga</a>") +
	    "</li>"
	    "    <li><strong>Alex Huszagh</strong> " +
	    tr("and") + " <strong>Colin Duquesnoy</strong> " +
	    tr("for creating BreezeStyleSheets, on which the dark theme in this program is "
	       "based off of") +
	    "</li>"
	    "    <li><strong>Andy Brice</strong> " +
	    tr("for providing some sample code for "
	       "detecting dark mode on Windows and macOS") +
	    "</li>"
	    "    <li><strong>Manuel Wudka-Robles</strong> " +
	    tr("for providing information on "
	       "getting open file descriptors on macOS") +
	    "</li>"
	    "  </ul>"
	    "</body>";

	setBackgroundRole(QPalette::Base);

	{
		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
}
