#include "PropertyTypeCustomization_PointF.h"
#include "QQuickDetailsViewLayoutBuilder.h"
#include "QQuickDetailsViewMananger.h"
#include "QPropertyHandle.h"
#include <QPointF>
#include <QQmlEngine>
#include <QQmlContext>

void PropertyTypeCustomization_PointF::customizeHeaderRow(QPropertyHandle* inPropertyHandle, QQuickDetailsViewRowBuilder* inBuilder)
{
	auto slotPair = inBuilder->makeNameValueSlot();

	QQuickItem* nameEditor = inPropertyHandle->setupNameEditor(slotPair.first);

	QQuickItem* valueLabel = inBuilder->setupItem(slotPair.second, R"(
		import QtQuick;
		import QtQuick.Controls;
		import ColorPalette;
		Item{
			property string pointText
			implicitHeight: 25
			width: parent.width
			anchors.verticalCenter: parent.verticalCenter
			Text {
				anchors.fill: parent
				verticalAlignment: Text.AlignVCenter
				text: pointText
				color: ColorPalette.theme.textPrimary
			}
		}
	)");

	auto updateLabel = [valueLabel](const QVariant& var) {
		QPointF pt = var.value<QPointF>();
		valueLabel->setProperty("pointText", QString("  (%1, %2)").arg(pt.x(), 0, 'f', 3).arg(pt.y(), 0, 'f', 3));
	};
	updateLabel(inPropertyHandle->getVar());

	QObject::connect(inPropertyHandle, &QPropertyHandle::asVarChanged, valueLabel, updateLabel);

	QQmlEngine* engine = qmlEngine(inBuilder->rootItem());
	QQmlContext* context = qmlContext(inBuilder->rootItem());
	context->parentContext()->setContextProperty("heightProxy", valueLabel);
}

void PropertyTypeCustomization_PointF::customizeChildren(QPropertyHandle* inPropertyHandle, QQuickDetailsViewLayoutBuilder* inBuilder)
{
	auto makeChild = [&](const QString& name, std::function<QVariant(const QPointF&)> getter) {
		inBuilder->addProperty(
			inPropertyHandle->findOrCreateChild(
				QMetaType::fromType<double>(),
				name,
				[inPropertyHandle, getter]() -> QVariant {
					return getter(inPropertyHandle->getVar().value<QPointF>());
				},
				[inPropertyHandle, name](const QVariant& var) {
					QPointF pt = inPropertyHandle->getVar().value<QPointF>();
					if (name == "x")
						pt.setX(var.toDouble());
					else
						pt.setY(var.toDouble());
					inPropertyHandle->setVar(pt);
				}
			),
			name
		);
	};

	makeChild("x", [](const QPointF& pt) { return pt.x(); });
	makeChild("y", [](const QPointF& pt) { return pt.y(); });
}
