#include "pivariant_edit.h"

#include "piqt.h"
#include "pivaluetree_edit.h"

#include <QEvent>


PIVariantEditorBase::PIVariantEditorBase(QWidget * parent): QWidget(parent) {
	Q_INIT_RESOURCE(qad_piqt_widgets);
	createBoxLayout();
}


QString PIVariantEditorBase::vtTr(const PIString & txt) {
	PIByteArray utf = txt.toUTF8();
	utf.append(0);
	QString ret = QCoreApplication::translate("QAD::PIValueTreeEdit", reinterpret_cast<const char *>(utf.data()));
	ret.detach();
	return ret;
}


PIVariantEditorBase * PIVariantEditorBase::createEditor(uint type_id) {
	auto f = factories().value(type_id, nullptr);
	if (!f) return nullptr;
	auto ret = f();
	ret->retranslate();
	return ret;
}


bool PIVariantEditorBase::editorExists(uint type_id) {
	return factories().value(type_id, nullptr);
}


PIVariantMap PIVariantEditorBase::editorDefaultAttributes(uint type_id) {
	return default_attributes().value(type_id);
}


PIVariantTypes::Enum PIVariantEditorBase::createGrouping() {
	PIVariantTypes::Enum ret;
	ret << PIVariantTypes::Enumerator(PIValueTreeEdit::Indent, "indent") << PIVariantTypes::Enumerator(PIValueTreeEdit::Groups, "groups")
		<< PIVariantTypes::Enumerator(PIValueTreeEdit::Tabs, "tabs");
	ret.selectValue(PIValueTreeEdit::Groups);
	return ret;
}


void PIVariantEditorBase::createBoxLayout(QBoxLayout::Direction d) {
	auto * l = new QBoxLayout(d);
	l->setContentsMargins(0, 0, 0, 0);
	setLayout(l);
}


void PIVariantEditorBase::changeEvent(QEvent * e) {
	if (e->type() == QEvent::LanguageChange) retranslate();
	QWidget::changeEvent(e);
}


PIMap<uint, PIVariantEditorBase * (*)()> & PIVariantEditorBase::factories() {
	static PIMap<uint, PIVariantEditorBase * (*)()> ret;
	return ret;
}


PIMap<uint, PIVariantMap> & PIVariantEditorBase::default_attributes() {
	static PIMap<uint, PIVariantMap> ret;
	return ret;
}


PIVariantEdit::PIVariantEdit(QWidget * parent): PIVariantEditorBase(parent) {
	label = new QLabel();
	label->setAlignment(Qt::AlignCenter);
	setValue(PIVariant());
}


PIVariantEdit::~PIVariantEdit() {
	delete label;
}


void PIVariantEdit::setValue(const PIVariant & v, uint type_id) {
	if (type_id == 0) type_id = v.typeID();
	if (current_type_id != type_id || !editor) {
		if (editor) delete editor;
		current_type_id = type_id;
		editor          = PIVariantEditorBase::createEditor(current_type_id);
		if (editor) {
			editor->applyAttributes(_attributes);
			layout()->removeWidget(label);
			layout()->addWidget(editor);
			label->hide();
		} else {
			label->setText(!v.isValid() ? tr("Invalid type") : tr("No editor for %1").arg(PI2QString(PIVariant::typeNameFromID(type_id))));
			layout()->addWidget(label);
			label->show();
		}
	}
	if (!editor) return;
	editor->setValue(v);
}


PIVariant PIVariantEdit::value() const {
	if (!editor) return PIVariant();
	return editor->value();
}


void PIVariantEdit::setAttributes(const PIVariantMap & a) {
	_attributes = a;
	if (!editor) return;
	editor->applyAttributes(_attributes);
}


PIVariantMap PIVariantEdit::attributes() const {
	if (!editor) return PIVariantMap();
	return editor->attributes();
}


void PIVariantEdit::setFullEditMode(bool on) {
	if (!editor) return;
	editor->setFullEditMode(on);
}


void PIVariantEdit::retranslate() {
	if (!editor) return;
	editor->retranslate();
}
