// *************************************************************************************************
//
// QPropertyEditor v 0.1
//
// --------------------------------------
// Copyright (C) 2007 Volker Wiendl
//
//
// This library 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 2.1 of the License, or any later version.
//
// This library 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 library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#ifndef PROPERTY_H_
#define PROPERTY_H_

#include <Qt/qwidget.h>
#include <Qt/qstyleoption.h>
#include <Qt/qvariant.h>

/**
 * The Property class is the base class for all properties in the QPropertyEditor
 * You can implement custom properties inherited from this class to further enhence the
 * functionality of the QPropertyEditor
 */
class Property : public QObject {
    Q_OBJECT

public:

    /**
     * Constructor
     *
     * @param name the name of the property within the propertyObject (will be used in the QPropertyEditorWidget view too)
     * @param propertyObject the object that contains the property
     * @param parent optional parent object 
     */
    Property(const QString& name = QString(), QObject* propertyObject = 0, QObject* parent = 0);

    /**
     * The value stored by this property
     * @return QVariant the data converted to a QVariant
     */
    virtual QVariant value(int role = Qt::UserRole) const;
    /**
     * Sets the value stored by this property
     * @param value the data converted to a QVariant
     */
    virtual void setValue(const QVariant& value);

    /**
     * Returns the QObject which contains the property managed by this instance
     * @return QObject* pointer to the QObject that contains user defined properties
     */
    QObject* propertyObject() {
        return m_propertyObject;
    }

    /**
     * Flag if property is used for indicating a group or really manages a property
     * @return bool true if this property is only used to display a category in the QPropertyEditorWidget
     */
    bool isRoot() {
        return m_propertyObject == 0;
    }

    /**
     * Flag if the property can be set
     * @return bool true if this property has no set method
     */
    bool isReadOnly();

    /**
     * Returns the row of this instance within the QPropertyModel
     * @return int row within the QPropertyModel
     */
    int row() {
        return parent()->children().indexOf(this);
    }

    /**
     * returns optional settings for the editor widget that is used to manipulate the properties value
     * @return QString a string that contains property settings for the editor widget (e.g. "minimum=1.0;maximum=10.0;")
     */
    QString editorHints() {
        return m_hints;
    }

    /**
     * Sets properties for the editor widget that is used to manipulate the data value managed by this instance
     * @param hints a string containing property settings for the editor widget that manipulates this property
     */
    virtual void setEditorHints(const QString& hints) {
        m_hints = hints;
    }

    /**
     * Creates an editor for the data managed by this instance
     * @param parent widget the newly created editor widget will be child of
     * @param option currently not used
     * @return QWidget* pointer to the editor widget
     */
    virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option);

    /**
     * Returns the data of the editor widget used to manipulate this instance
     * @return QVariant the data converted to a QVariant
     */
    virtual QVariant editorData(QWidget *editor);

    /**
     * Changes the editor widget's data to a specific value
     * @param editor the editor widget
     * @param data the data to set in the editor widget
     * @return bool true if editor widget was set to the given data successfully, false if the data can not be set in the editor (e.g. wrong datatype)
     */
    virtual bool setEditorData(QWidget *editor, const QVariant& data);

    /**
     * Tries to find the first property that manages the given propertyObject
     * @param propertyObject
     * @return Property
     */
    Property* findPropertyObject(QObject* propertyObject);

private slots:
    /**
     * This slot is used to immediately set the properties when the editor widget's value of a double or float 
     * property has changed
     * @param value the new value
     */
    void setValue(double value);
    /**
     * This slot is used to immediately set the properties when the editor widget's value of an integer
     * property has changed
     * @param value the new value
     */
    void setValue(int value);

private:
    QObject* m_propertyObject;
    QString  m_hints;

};

#endif
