/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qqmlpropertymap.h"

#include <private/qmetaobjectbuilder_p.h>
#include <private/qqmlopenmetaobject_p.h>

#include <QDebug>

QT_BEGIN_NAMESPACE

//QQmlPropertyMapMetaObject lets us listen for changes coming from QML
//so we can emit the changed signal.
class QQmlPropertyMapMetaObject : public QQmlOpenMetaObject
{
public:
    QQmlPropertyMapMetaObject(QQmlPropertyMap *obj, QQmlPropertyMapPrivate *objPriv, const QMetaObject *staticMetaObject);

protected:
    QVariant propertyWriteValue(int, const QVariant &) override;
    void propertyWritten(int index) override;
    void propertyCreated(int, QMetaPropertyBuilder &) override;
    int createProperty(const char *, const char *) override;

    const QString &propertyName(int index);

private:
    QQmlPropertyMap *map;
    QQmlPropertyMapPrivate *priv;
};

class QQmlPropertyMapPrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QQmlPropertyMap)
public:
    QQmlPropertyMapMetaObject *mo;
    QStringList keys;

    QVariant updateValue(const QString &key, const QVariant &input);
    void emitChanged(const QString &key, const QVariant &value);
    bool validKeyName(const QString& name);

    const QString &propertyName(int index) const;
};

bool QQmlPropertyMapPrivate::validKeyName(const QString& name)
{
    //The following strings shouldn't be used as property names
    return  name != QLatin1String("keys")
         && name != QLatin1String("valueChanged")
         && name != QLatin1String("QObject")
         && name != QLatin1String("destroyed")
         && name != QLatin1String("deleteLater");
}

QVariant QQmlPropertyMapPrivate::updateValue(const QString &key, const QVariant &input)
{
    Q_Q(QQmlPropertyMap);
    return q->updateValue(key, input);
}

void QQmlPropertyMapPrivate::emitChanged(const QString &key, const QVariant &value)
{
    Q_Q(QQmlPropertyMap);
    emit q->valueChanged(key, value);
}

const QString &QQmlPropertyMapPrivate::propertyName(int index) const
{
    Q_ASSERT(index < keys.size());
    return keys[index];
}

QQmlPropertyMapMetaObject::QQmlPropertyMapMetaObject(QQmlPropertyMap *obj, QQmlPropertyMapPrivate *objPriv, const QMetaObject *staticMetaObject)
    : QQmlOpenMetaObject(obj, staticMetaObject)
{
    map = obj;
    priv = objPriv;
}

QVariant QQmlPropertyMapMetaObject::propertyWriteValue(int index, const QVariant &input)
{
    return priv->updateValue(priv->propertyName(index), input);
}

void QQmlPropertyMapMetaObject::propertyWritten(int index)
{
    priv->emitChanged(priv->propertyName(index), value(index));
}

void QQmlPropertyMapMetaObject::propertyCreated(int, QMetaPropertyBuilder &b)
{
    priv->keys.append(QString::fromUtf8(b.name()));
}

int QQmlPropertyMapMetaObject::createProperty(const char *name, const char *value)
{
    if (!priv->validKeyName(QString::fromUtf8(name)))
        return -1;
    return QQmlOpenMetaObject::createProperty(name, value);
}

/*!
    \class QQmlPropertyMap
    \brief The QQmlPropertyMap class allows you to set key-value pairs that can be used in QML bindings.
    \inmodule QtQml

    QQmlPropertyMap provides a convenient way to expose domain data to the UI layer.
    The following example shows how you might declare data in C++ and then
    access it in QML.

    In the C++ file:
    \code
    // create our data
    QQmlPropertyMap ownerData;
    ownerData.insert("name", QVariant(QString("John Smith")));
    ownerData.insert("phone", QVariant(QString("555-5555")));

    // expose it to the UI layer
    QQuickView view;
    QQmlContext *ctxt = view.rootContext();
    ctxt->setContextProperty("owner", &ownerData);

    view.setSource(QUrl::fromLocalFile("main.qml"));
    view.show();
    \endcode

    Then, in \c main.qml:
    \code
    Text { text: owner.name + " " + owner.phone }
    \endcode

    The binding is dynamic - whenever a key's value is updated, anything bound to that
    key will be updated as well.

    To detect value changes made in the UI layer you can connect to the valueChanged() signal.
    However, note that valueChanged() is \b NOT emitted when changes are made by calling insert()
    or clear() - it is only emitted when a value is updated from QML.

    \note It is not possible to remove keys from the map; once a key has been added, you can only
    modify or clear its associated value.

    \note When deriving a class from QQmlPropertyMap, use the
    \l {QQmlPropertyMap::QQmlPropertyMap(DerivedType *derived, QObject *parent)} {protected two-argument constructor}
    which ensures that the class is correctly registered with the Qt \l {Meta-Object System}.

    \note The QMetaObject of a QQmlPropertyMap is dynamically generated and modified.
    Operations on that meta object are not thread safe, so applications need to take
    care to explicitly synchronize access to the meta object.
*/

/*!
    Constructs a bindable map with parent object \a parent.
*/
QQmlPropertyMap::QQmlPropertyMap(QObject *parent)
: QQmlPropertyMap(&staticMetaObject, parent)
{
}

/*!
    Destroys the bindable map.
*/
QQmlPropertyMap::~QQmlPropertyMap()
{
}

/*!
    Clears the value (if any) associated with \a key.
*/
void QQmlPropertyMap::clear(const QString &key)
{
    Q_D(QQmlPropertyMap);
    d->mo->setValue(key.toUtf8(), QVariant());
}

/*!
    Returns the value associated with \a key.

    If no value has been set for this key (or if the value has been cleared),
    an invalid QVariant is returned.
*/
QVariant QQmlPropertyMap::value(const QString &key) const
{
    Q_D(const QQmlPropertyMap);
    return d->mo->value(key.toUtf8());
}

/*!
    Sets the value associated with \a key to \a value.

    If the key doesn't exist, it is automatically created.
*/
void QQmlPropertyMap::insert(const QString &key, const QVariant &value)
{
    Q_D(QQmlPropertyMap);

    if (d->validKeyName(key)) {
        d->mo->setValue(key.toUtf8(), value);
    } else {
        qWarning() << "Creating property with name"
                   << key
                   << "is not permitted, conflicts with internal symbols.";
    }
}

/*!
    Returns the list of keys.

    Keys that have been cleared will still appear in this list, even though their
    associated values are invalid QVariants.
*/
QStringList QQmlPropertyMap::keys() const
{
    Q_D(const QQmlPropertyMap);
    return d->keys;
}

/*!
    \overload

    Same as size().
*/
int QQmlPropertyMap::count() const
{
    Q_D(const QQmlPropertyMap);
    return d->keys.count();
}

/*!
    Returns the number of keys in the map.

    \sa isEmpty(), count()
*/
int QQmlPropertyMap::size() const
{
    Q_D(const QQmlPropertyMap);
    return d->keys.size();
}

/*!
    Returns true if the map contains no keys; otherwise returns
    false.

    \sa size()
*/
bool QQmlPropertyMap::isEmpty() const
{
    Q_D(const QQmlPropertyMap);
    return d->keys.isEmpty();
}

/*!
    Returns true if the map contains \a key.

    \sa size()
*/
bool QQmlPropertyMap::contains(const QString &key) const
{
    Q_D(const QQmlPropertyMap);
    return d->keys.contains(key);
}

/*!
    Returns the value associated with the key \a key as a modifiable
    reference.

    If the map contains no item with key \a key, the function inserts
    an invalid QVariant into the map with key \a key, and
    returns a reference to it.

    \sa insert(), value()
*/
QVariant &QQmlPropertyMap::operator[](const QString &key)
{
    //### optimize
    Q_D(QQmlPropertyMap);
    QByteArray utf8key = key.toUtf8();
    if (!d->keys.contains(key))
        insert(key, QVariant());//force creation -- needed below

    return d->mo->valueRef(utf8key);
}

/*!
    \overload

    Same as value().
*/
QVariant QQmlPropertyMap::operator[](const QString &key) const
{
    return value(key);
}

/*!
    Returns the new value to be stored for the key \a key.  This function is provided
    to intercept updates to a property from QML, where the value provided from QML is \a input.

    Override this function to manipulate the property value as it is updated.  Note that
    this function is only invoked when the value is updated from QML.
*/
QVariant QQmlPropertyMap::updateValue(const QString &key, const QVariant &input)
{
    Q_UNUSED(key)
    return input;
}

/*! \internal */
QQmlPropertyMap::QQmlPropertyMap(const QMetaObject *staticMetaObject, QObject *parent)
    : QObject(*(new QQmlPropertyMapPrivate), parent)
{
    Q_D(QQmlPropertyMap);
    d->mo = new QQmlPropertyMapMetaObject(this, d, staticMetaObject);
}

/*!
    \fn void QQmlPropertyMap::valueChanged(const QString &key, const QVariant &value)
    This signal is emitted whenever one of the values in the map is changed. \a key
    is the key corresponding to the \a value that was changed.

    \note valueChanged() is \b NOT emitted when changes are made by calling insert()
    or clear() - it is only emitted when a value is updated from QML.
*/

/*!
    \fn template<class DerivedType> QQmlPropertyMap::QQmlPropertyMap(DerivedType *derived, QObject *parent)

    Constructs a bindable map with parent object \a parent.  Use this constructor
    in classes derived from QQmlPropertyMap.

    The type of \a derived is used to register the property map with the \l {Meta-Object System},
    which is necessary to ensure that properties of the derived class are accessible.
    This type must be derived from QQmlPropertyMap.
*/

QT_END_NAMESPACE
