// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2009 Konrad Twardowski

#include "infowidget.h"

#include "utils.h"
#include "uwidgets.h"

#include <QHBoxLayout>

#ifdef KS_PURE_QT
	#include <QStyle>
#endif // KS_PURE_QT

// public

InfoWidget::InfoWidget() {
	setObjectName("info-widget");
	setVisible(false);

#ifdef KS_KF5
	m_messageWidget = new KMessageWidget(this);
	m_messageWidget->setCloseButtonVisible(false);
	connect(m_messageWidget, &KMessageWidget::linkActivated, [](const QString &contents) {
		Utils::openInExternalApp(contents);
	});
#else
	setAutoFillBackground(true);
	setFrameStyle(Panel | Sunken);
	setLineWidth(1_px);

	m_messageWidget = new ULabel();
	m_messageWidget->setMarginAndSpacing(5_px, 7_px);
	m_messageWidget->textLabel()->setOpenExternalLinks(true);
#endif // KS_KF5

	UWidgets::newHBoxLayout(this, { m_messageWidget }, UWidgets::STYLE_SPACING);
}

#ifdef KS_PURE_QT
bool InfoWidget::event(QEvent *e) {
	// detect system color changes (e.g. light to dark theme change)
	if (e->type() == QEvent::PaletteChange) {
		if (m_handlePaletteChange)
			updateColors();
	}

	return QFrame::event(e);
}
#endif // KS_PURE_QT

InfoWidget *InfoWidget::info(const QString &text) {
	auto *iw = new InfoWidget();
	iw->setText(text, Type::Info);

	return iw;
}

InfoWidget *InfoWidget::warning(const QString &text) {
	auto *iw = new InfoWidget();
	iw->setText(text, Type::Warning);

	return iw;
}

void InfoWidget::setText(const QString &text, const Type type) {
#ifdef KS_KF5
	switch (type) {
		case Type::Error:
			m_messageWidget->setIcon(QIcon::fromTheme("dialog-error"));
			m_messageWidget->setMessageType(KMessageWidget::Error);
			break;
		case Type::Info:
			m_messageWidget->setIcon(QIcon::fromTheme("dialog-information"));
			m_messageWidget->setMessageType(KMessageWidget::Information);
			break;
		case Type::Warning:
			m_messageWidget->setIcon(QIcon::fromTheme("dialog-warning"));
			m_messageWidget->setMessageType(KMessageWidget::Warning);
			break;
	}

	m_messageWidget->setText(text);
#else
	m_type = type;

	const int size = Utils::getSmallIconSize()
		.width();

	switch (type) {
		case Type::Error:
			#ifdef Q_OS_WIN32
			m_messageWidget->setIcon(QStyle::SP_MessageBoxCritical, size);
			#else
			m_messageWidget->setIcon("dialog-error", size);
			#endif // Q_OS_WIN32
			break;
		case Type::Info:
			#ifdef Q_OS_WIN32
			m_messageWidget->setIcon(QStyle::SP_MessageBoxInformation, size);
			#else
// FIXME: empty icon in some Desktop Environments
			m_messageWidget->setIcon("dialog-information", size);
			#endif // Q_OS_WIN32
			break;
		case Type::Warning:
		default:
			#ifdef Q_OS_WIN32
			m_messageWidget->setIcon(QStyle::SP_MessageBoxWarning, size);
			#else
			m_messageWidget->setIcon("dialog-warning", size);
			#endif // Q_OS_WIN32
			break;
	}

	updateColors();

	m_messageWidget->setText(text);
#endif // KS_KF5

// TODO: use <html> instead (global)
	setVisible(!text.isEmpty() && (text != "<qt></qt>"));
	if (isVisible())
		repaint(0_px, 0_px, width(), height());

	#ifdef KS_KF5
	// HACK: fixes height
	m_messageWidget->adjustSize();
	#endif // KS_KF5
}

// private

#ifdef KS_PURE_QT
void InfoWidget::updateColors() {
// TODO: use https://doc.qt.io/qt-6/qstylehints.html#colorScheme-prop
	const bool dark = Utils::isDark(window());

	QColor bg; // picked from the Oxygen palette

	switch (m_type) {
		case Type::Error:
			bg.setRgb(dark ? 0x9C0F0F : 0xF9CCCA); // brick red 6 / 1
			break;
		case Type::Info:
			bg.setRgb(dark ? 0x00316E : 0xBFD9FF); // sky blue 6 / blue 1
			break;
		case Type::Warning:
		default:
			bg.setRgb(dark ? 0xAC4311 : 0xFFD9B0); // hot orange 6 / 1
			break;
	}

	QPalette p;

	QColor fg = dark ? 0xeeeeee : Qt::black;
	QColor border = dark ? bg.lighter(120) : bg.darker(120);

	p.setColor(QPalette::Window, bg);
	p.setColor(QPalette::WindowText, fg);
	p.setColor(QPalette::Light, border);
	p.setColor(QPalette::Dark, border);

	m_handlePaletteChange = false;
	setPalette(p);
	m_handlePaletteChange = true;
}
#endif // KS_PURE_QT
