/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2025 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK 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 version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/


#ifndef __FIELD_EDITOR__
#define __FIELD_EDITOR__

#include <QObject>
#include <QLabel>
#include <QWidget>

#include "CamiTKExtensionModelPresenter.h"
#include <VariantDataModel.h>

/**
 * @brief Abstract class for field editor
 *
 * A field editor should be included in a CamiTKExtensionModelPresenter and which role is to provide
 * a GUI for a VariantDataModel (part of the CamiTKExtensionModel full model).
 *
 * It has:
 * - a name (displayed as the label)
 * - a description (displayed as tooltip/whatsthat)
 *
 * As an editor for one field, it should be appended to a gridlayout that contains all the other edited fields.
 *
 * It must be subclassed to provide a specific widget to edit specific types of value (atomic value, textfield...).
 */
class FieldEditor : public QObject {
    Q_OBJECT
public:
    /// Constructor
    /// Creates a field for the given data model inside the given presenter
    /// A name and description can be associated with the field (it will be used when the field is added to a gridlayout,
    /// @see appendRowTo).
    FieldEditor(CamiTKExtensionModelPresenter* presenter, VariantDataModel& dataModel, const QString& name = "", const QString& description = "");

    /// Destructor (delete myWidget)
    virtual ~FieldEditor();

    /// Creates the editor widget (must be implemented in inheriting classes)
    virtual QWidget* getWidget() = 0;

    /// Adds a row at the end of the given layout with two columns:
    /// - first column contains the name of the field
    /// - second column contains the widget
    /// If hasDeleteButton is true, an extra delete button is added next to the label.
    /// When the delete button is clicked, the entire added row will be deleted
    /// removing the edited data model.
    virtual void appendRowTo(QGridLayout* layout, bool canBeDeleted = false);

    /// Is the widget and labels currently enabled
    void setEnabled(bool isEnabled);

signals:
    /// emitted when the edited value has changed (useful to synchronize other field editor depending of this editor current value)
    void valueChanged(VariantDataModel& changedDataModel);

protected:
    /// The presenter that contains the full VariantDataModel
    CamiTKExtensionModelPresenter* presenter;

    /// The edited data model (part of the presenter's full model)
    VariantDataModel& dataModel;

    /// The created widget (inheriting **must** use this to create their widgets)
    QWidget* myWidget;

    /// Name of the field (displayed as a label)
    QString name;

    /// Description (displayed as tool tip / what's that)
    QString description;

    /// where the widget is added
    QGridLayout* myGridLayout;

    /// the row label widget (that contains the name of the row)
    /// the label text can be modified (see CamiTKPropertyFieldEditor.h for an example)
    QLabel* rowLabel;

protected slots:

    /// Called when the (optional) delete button is called
    /// This will make user the user knows what she/he does
    /// If deletion is confirmed by the user, remove the data model
    virtual void deleteButtonClicked();

};

#endif // __FIELD_EDITOR__