#include "pivariant_geoposition.h"

#include "mapitemimage.h"
#include "osm_geocoding.h"
#include "piqt.h"
#include "pivaluetree.h"
#include "ui_pivariant_geoposition.h"
#include "ui_pivariant_geoposition_map.h"

#include <QFileDialog>


REGISTER_PIVARIANTEDITOR(PIGeoPosition, PIVariantEditors::GeoPosition);

#define GeoUI reinterpret_cast<Ui::GeoPosition *>(ui)

using Attribute = PIValueTree::Attribute;


PIVariantEditors::GeoPosition::GeoPosition() {
	QWidget * w = new QWidget();
	ui          = new Ui::GeoPosition();
	GeoUI->setupUi(w);
	layout()->addWidget(w);
	connect(GeoUI->buttonMap, &QToolButton::clicked, this, [this]() {
		QDialog dlg;
		Ui::GeoPositionMap ui;
		ui.setupUi(&dlg);
		ui.map->setCenter(PI2QGeoPosition(value().value<PIGeoPosition>()));
		auto * item = new MapItemImage(QPixmap(":/icons/location.png"));
		item->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
		item->setScale(0.333 * appScale(this));
		item->setPosition(ui.map->center());
		ui.map->addItem(item);
		OSMGeocodingResult * gc_res = nullptr;
		connect(ui.map, &MapView::mapClicked, this, [this, item, &gc_res, ui](QPointF c) {
			item->setPosition(c);
			if (gc_res) gc_res->abort();
			gc_res = OSMGeocoding::queue(c);
			ui.label->setText("-");
			connect(gc_res, &OSMGeocodingResult::ready, this, [&gc_res, ui]() {
				ui.label->setText(gc_res->displayName());
				gc_res = nullptr;
			});
		});
		ui.map->mapClicked(ui.map->center());
		if (dlg.exec() != QDialog::Accepted) return;
		PIGeoPosition gp({item->position().x(), item->position().y(), 0.}, PIGeoPosition::Geodetic);
		setValue(PIVariant::fromValue(gp));
	});
}


PIVariantEditors::GeoPosition::~GeoPosition() {
	delete GeoUI;
}


void PIVariantEditors::GeoPosition::setValue(const PIVariant & v) {
	val = v.value<PIGeoPosition>();
	GeoUI->line->setText(PI2QString(v.toString()));
}


PIVariant PIVariantEditors::GeoPosition::value() const {
	PIGeoPosition g = __PIVariantFunctions__<PIString>::castVariant<PIGeoPosition>(Q2PIString(GeoUI->line->text()));
	return PIVariant::fromValue(g);
}


void PIVariantEditors::GeoPosition::applyAttributes(const PIVariantMap & a) {
	bool ro = a.value(Attribute::readOnly, GeoUI->line->isReadOnly()).toBool();
	GeoUI->line->setReadOnly(ro);
	GeoUI->buttonMap->setHidden(ro);
}
