/*
    PIQt Utils - Qt utilites for PIP

    Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef pivariant_edit_H
#define pivariant_edit_H

#include "pivariant.h"
#include "qad_piqt_utils_export.h"

#include <QBoxLayout>
#include <QDebug>
#include <QLabel>
#include <QWidget>

#define REGISTER_PIVARIANTEDITOR(type_name, class_name)                                                        \
	STATIC_INITIALIZER_BEGIN                                                                                   \
		PIVariantEditorBase::registerEditor<class_name>(PIVariant::typeIDFromName(PIStringAscii(#type_name))); \
	STATIC_INITIALIZER_END

class PIVariantEdit;


class QAD_PIQT_UTILS_EXPORT PIVariantEditorBase: public QWidget {
	friend class PIVariantEdit;

public:
	PIVariantEditorBase(QWidget * parent = nullptr);
	virtual ~PIVariantEditorBase() {}

	virtual void setValue(const PIVariant & v) = 0;
	virtual PIVariant value() const            = 0;

	virtual PIVariantMap attributes() const { return PIVariantMap(); }
	static PIVariantMap defaultAttributes() { return PIVariantMap(); }

	virtual void retranslate() {}

	static QString vtTr(const PIString & txt);

	template<typename T>
	static void registerEditor(uint type_id) {
		if (factories().contains(type_id)) {
			piCout << "[PIVariantEditorBase::registerEditor] Editor with typeID" << type_id << "already registered, ignore";
			return;
		}
		factories()[type_id]          = []() -> PIVariantEditorBase * { return new T(); };
		default_attributes()[type_id] = T::defaultAttributes();
		// qDebug() << "register" << T::staticMetaObject.className() << type_id;
	}

	static PIVariantEditorBase * createEditor(uint type_id);
	static bool editorExists(uint type_id);
	static PIVariantMap editorDefaultAttributes(uint type_id);
	static PIVariantTypes::Enum createGrouping();

protected:
	void createBoxLayout(QBoxLayout::Direction d = QBoxLayout::LeftToRight);
	virtual void setFullEditMode(bool on) {}

	virtual void applyAttributes(const PIVariantMap & a) {}

private:
	void changeEvent(QEvent * e) override;

	static PIMap<uint, PIVariantEditorBase * (*)()> & factories();
	static PIMap<uint, PIVariantMap> & default_attributes();
};


class QAD_PIQT_UTILS_EXPORT PIVariantEdit: public PIVariantEditorBase {
	Q_OBJECT

public:
	PIVariantEdit(QWidget * parent = nullptr);
	~PIVariantEdit();

	void setValue(const PIVariant & v, uint type_id);
	void setValue(const PIVariant & v) override { setValue(v, v.typeID()); }
	PIVariant value() const override;

	void setAttributes(const PIVariantMap & a);
	PIVariantMap attributes() const override;

	void setFullEditMode(bool on) override;
	void retranslate() override;

private:
	PIVariantEditorBase * editor = nullptr;
	PIVariantMap _attributes;
	QLabel * label;
	uint current_type_id = -1;
};


#endif
