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

#include <QDebug>
#include <QFrame>
#include <QLabel>
#include <QTextBlock>
#include <QVBoxLayout>
#include <QScrollArea>
#include <QDebug>

namespace TextWidgets {

/* Generic header meant to be used in conjunction with Section<T> */

Header::Header(QWidget* parent)
	: QWidget(parent)
	, title_(new QLabel(this))
	, separator_(new QFrame(this)) {
	QVBoxLayout* layout = new QVBoxLayout(this);
	setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);

	title_->setTextFormat(Qt::PlainText);

	{
		QFont font = title_->font();
		font.setWeight(QFont::Bold);
		title_->setFont(font);
	}

	separator_->setFrameShape(QFrame::HLine);
	separator_->setFrameShadow(QFrame::Sunken);
	separator_->setFixedHeight(2);

	layout->addWidget(title_.data());
	layout->addWidget(separator_.data());
	layout->setSpacing(0);
	layout->setContentsMargins(0, 0, 0, 0);
}

void Header::SetText(const std::string& text) {
	title_->setText(Strings::ToQString(text));
	updateGeometry();
}

/* ---------------------------------------------------------------------------------- */
/* "Paragraph" widgets, as in widgets meant to hold a bunch of text. */

Paragraph::Paragraph(QWidget *parent) : QWidget(parent), label_(new QLabel) {
	QVBoxLayout *layout = new QVBoxLayout(this);
	layout->setSpacing(0);
	layout->setContentsMargins(0, 0, 0, 0);

	label_->setTextInteractionFlags(Qt::TextBrowserInteraction);

	/* defaults */
	SetWordWrap(true);
	SetSelectable(true);

	layout->addWidget(label_.data());
}

void Paragraph::SetText(const std::string& text) {
	label_->setText(Strings::ToQString(text));
}

void Paragraph::SetSelectable(bool enable) {
	label_->setAttribute(Qt::WidgetAttribute::WA_TransparentForMouseEvents, !enable);
	label_->setCursor(enable ? Qt::IBeamCursor : Qt::ArrowCursor);
}

void Paragraph::SetWordWrap(bool enable) {
	label_->setWordWrap(enable);
}

/* LabelledParagraph implementation */

LabelledParagraph::LabelledParagraph(QWidget* parent)
	: QWidget(parent)
	, contents_(new QWidget)
	, contents_layout_(new QGridLayout) {
	QHBoxLayout* ly = new QHBoxLayout(this);

	contents_layout_->setVerticalSpacing(1);
	contents_layout_->setHorizontalSpacing(20);
	contents_layout_->setContentsMargins(0, 0, 0, 0);
	contents_layout_->setColumnStretch(1, 0);

	contents_->setLayout(contents_layout_.data());

	ly->addWidget(contents_.data());
	ly->setContentsMargins(0, 0, 0, 0);
}

LabelledParagraph::~LabelledParagraph() {
	data_.clear();
}

void LabelledParagraph::Clear(void) {
	for (auto& [label, data] : data_) {
		contents_layout_->removeWidget(label.data());
		contents_layout_->removeWidget(data.data());
	}

	data_.clear();
}

void LabelledParagraph::SetData(const std::vector<std::pair<std::string, std::string>>& data) {
	Clear();

	data_.reserve(data.size());
	for (std::size_t i = 0; i < data.size(); i++) {
		QSharedPointer<QLabel> first(new QLabel);
		QSharedPointer<QLabel> second(new QLabel);

		first->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);

		first->setText(Strings::ToQString(data[i].first));
		second->setText(Strings::ToQString(data[i].second));

		data_.push_back({first, second});

		contents_layout_->addWidget(first.data(), i, 0);
		contents_layout_->addWidget(second.data(), i, 1);
	}
}

void LabelledParagraph::SetStyle(int style) {
	const QString style_sheet = (style & LabelledParagraph::BoldedLabels) ? "font-weight: bold;" : "";
	for (auto& [label, data] : data_)
		label->setStyleSheet(style_sheet);

	// TODO ElidedData
}

} // namespace TextWidgets
