/***************************************************************************
    qgseditorwidgetwrapper.h
     --------------------------------------
    Date                 : 20.4.2013
    Copyright            : (C) 2013 Matthias Kuhn
    Email                : matthias at opengis dot ch
 ***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef QGSEDITORWIDGETWRAPPER_H
#define QGSEDITORWIDGETWRAPPER_H

#include <QObject>
#include <QMap>
#include <QVariant>

class QgsVectorLayer;
class QgsField;

#include "qgseditorwidgetconfig.h"
#include "qgsattributeeditorcontext.h"
#include "qgswidgetwrapper.h"

/**
 * Manages an editor widget
 * Widget and wrapper share the same parent
 *
 * A wrapper controls one attribute editor widget and is able to create a default
 * widget or use a pre-existent widget. It is able to set the widget to the value implied
 * by a field of a vector layer, or return the value it currently holds. Every time it is changed
 * it has to emit a valueChanged signal. If it fails to do so, there is no guarantee that the
 * changed status of the widget will be saved.
 *
 */
class GUI_EXPORT QgsEditorWidgetWrapper : public QgsWidgetWrapper
{
    Q_OBJECT
  public:
    /**
     * Create a new widget wrapper
     *
     * @param vl        The layer on which the field is
     * @param fieldIdx  The field which will be controlled
     * @param editor    An editor widget. Can be NULL if one should be autogenerated.
     * @param parent    A parent widget for this widget wrapper and the created widget.
     */
    explicit QgsEditorWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* editor = 0, QWidget* parent = 0 );

    /**
     * Will be used to access the widget's value. Read the value from the widget and
     * return it properly formatted to be saved in the attribute.
     *
     * If an invalid variant is returned this will be interpreted as no change.
     * Be sure to return a NULL QVariant if it should be set to NULL.
     *
     * @return The current value the widget represents
     */
    virtual QVariant value() = 0;

    /**
     * Access the field index.
     *
     * @return The index of the field you are working on
     *
     * @see layer()
     */
    int fieldIdx();

    /**
     * Access the field.
     *
     * @return The field you are working on
     *
     * @see layer()
     */
    QgsField field();

    /**
     * Access the default value of the field.
     *
     * @return the default value of the field
     *
     * @see layer()
     */
    QVariant defaultValue();

    /**
     * Will return a wrapper for a given widget
     * @param widget The widget which was created by a wrapper
     * @return The wrapper for the widget or NULL
     */
    static QgsEditorWidgetWrapper* fromWidget( QWidget* widget );

    /**
     * Is used to enable or disable the edit functionality of the managed widget.
     * By default this will enable or disable the whole widget
     *
     * @param enabled  Enable or Disable?
     */
    void setEnabled( bool enabled ) override;

  signals:
    /**
     * Emit this signal, whenever the value changed.
     *
     * @param value The new value
     */
    void valueChanged( const QVariant& value );

  public slots:
    /**
     * Will be called when the feature changes
     *
     * Is forwarded to the slot \link setValue() \endlink
     *
     * @param feature The new feature
     */
    void setFeature( const QgsFeature& feature ) override;

    /**
     * Is called, when the value of the widget needs to be changed. Update the widget representation
     * to reflect the new value.
     *
     * @param value The new value of the attribute
     */
    virtual void setValue( const QVariant& value ) = 0;

  protected slots:
    /**
     * If you emit to this slot in your implementation, an appropriate change notification
     * will be broadcasted. Helper for string type widgets.
     *
     * @param value The value
     */
    void valueChanged( const QString& value );

    /**
     * If you emit to this slot in your implementation, an appropriate change notification
     * will be broadcasted. Helper for int type widgets.
     *
     * @param value The value
     * @note python name valueChangedInt
     */
    void valueChanged( int value );

    /**
     * If you emit to this slot in your implementation, an appropriate change notification
     * will be broadcasted. Helper for double type widgets.
     *
     * @param value The value
     * @note python name valueChangedDouble
     */
    void valueChanged( double value );

    /**
     * If you emit to this slot in your implementation, an appropriate change notification
     * will be broadcasted. Helper for bool type widgets.
     *
     * @param value The value
     * @note python name valueChangedBool
     */
    void valueChanged( bool value );

    /**
     * If you emit to this slot in your implementation, an appropriate change notification
     * will be broadcasted. Helper for longlong type widgets.
     *
     * @param value The value
     */
    void valueChanged( qlonglong value );

    /**
     * Will call the value() method to determine the emitted value
     */
    void valueChanged();

  private:
    int mFieldIdx;
};

// We'll use this class inside a QVariant in the widgets properties
Q_DECLARE_METATYPE( QgsEditorWidgetWrapper* )

#endif // QGSEDITORWIDGETWRAPPER_H
