/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "private/qdeclarativerepeater_p.h"
#include "private/qdeclarativerepeater_p_p.h"

#include "private/qdeclarativevisualitemmodel_p.h"
#include <private/qdeclarativeglobal_p.h>
#include <qdeclarativelistaccessor_p.h>

#include <qlistmodelinterface_p.h>

QT_BEGIN_NAMESPACE
QDeclarativeRepeaterPrivate::QDeclarativeRepeaterPrivate()
: model(0), ownModel(false)
{
}

QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
{
    if (ownModel)
        delete model;
}

/*!
    \qmlclass Repeater QDeclarativeRepeater
    \ingroup qml-utility-elements
    \since 4.7
    \inherits Item

    \brief The Repeater element allows you to repeat an Item-based component using a model.

    The Repeater element is used to create a large number of
    similar items. Like other view elements, a Repeater has a \l model and a \l delegate:
    for each entry in the model, the delegate is instantiated
    in a context seeded with data from the model. A Repeater item is usually
    enclosed in a positioner element such as \l Row or \l Column to visually
    position the multiple delegate items created by the Repeater.

    The following Repeater creates three instances of a \l Rectangle item within
    a \l Row:

    \snippet doc/src/snippets/declarative/repeaters/repeater.qml import
    \codeline
    \snippet doc/src/snippets/declarative/repeaters/repeater.qml simple

    \image repeater-simple.png

    A Repeater's \l model can be any of the supported \l {qmlmodels}{data models}.
    Additionally, like delegates for other views, a Repeater delegate can access
    its index within the repeater, as well as the model data relevant to the
    delegate. See the \l delegate property documentation for details.

    Items instantiated by the Repeater are inserted, in order, as
    children of the Repeater's parent.  The insertion starts immediately after
    the repeater's position in its parent stacking list.  This allows
    a Repeater to be used inside a layout. For example, the following Repeater's
    items are stacked between a red rectangle and a blue rectangle:

    \snippet doc/src/snippets/declarative/repeaters/repeater.qml layout

    \image repeater.png


    \note A Repeater item owns all items it instantiates. Removing or dynamically destroying
    an item created by a Repeater results in unpredictable behavior.


    \section2 Considerations when using Repeater

    The Repeater element creates all of its delegate items when the repeater is first
    created. This can be inefficient if there are a large number of delegate items and
    not all of the items are required to be visible at the same time. If this is the case,
    consider using other view elements like ListView (which only creates delegate items 
    when they are scrolled into view) or use the \l {Dynamic Object Creation} methods to 
    create items as they are required.

    Also, note that Repeater is \l {Item}-based, and can only repeat \l {Item}-derived objects. 
    For example, it cannot be used to repeat QtObjects:
    \badcode
    Item {
        //XXX does not work! Can't repeat QtObject as it doesn't derive from Item.
        Repeater {
            model: 10
            QtObject {}
        }
    }
    \endcode
 */

/*!
    \qmlsignal Repeater::onItemAdded(int index, Item item)
    \since QtQuick 1.1

    This handler is called when an item is added to the repeater. The \a index
    parameter holds the index at which the item has been inserted within the
    repeater, and the \a item parameter holds the \l Item that has been added.
*/

/*!
    \qmlsignal Repeater::onItemRemoved(int index, Item item)
    \since QtQuick 1.1

    This handler is called when an item is removed from the repeater. The \a index
    parameter holds the index at which the item was removed from the repeater,
    and the \a item parameter holds the \l Item that was removed.

    Do not keep a reference to \a item if it was created by this repeater, as
    in these cases it will be deleted shortly after the handler is called.
*/

QDeclarativeRepeater::QDeclarativeRepeater(QDeclarativeItem *parent)
  : QDeclarativeItem(*(new QDeclarativeRepeaterPrivate), parent)
{
}

QDeclarativeRepeater::~QDeclarativeRepeater()
{
}

/*!
    \qmlproperty any Repeater::model

    The model providing data for the repeater.

    This property can be set to any of the supported \l {qmlmodels}{data models}:

    \list
    \o A number that indicates the number of delegates to be created by the repeater
    \o A model (e.g. a ListModel item, or a QAbstractItemModel subclass)
    \o A string list
    \o An object list
    \endlist

    The type of model affects the properties that are exposed to the \l delegate.

    \sa {qmlmodels}{Data Models}
*/
QVariant QDeclarativeRepeater::model() const
{
    Q_D(const QDeclarativeRepeater);
    return d->dataSource;
}

void QDeclarativeRepeater::setModel(const QVariant &model)
{
    Q_D(QDeclarativeRepeater);
    if (d->dataSource == model)
        return;

    clear();
    if (d->model) {
        disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
        disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
        disconnect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
        disconnect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
        /*
        disconnect(d->model, SIGNAL(createdItem(int,QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*)));
        disconnect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*)));
    */
    }
    d->dataSource = model;
    QObject *object = qvariant_cast<QObject*>(model);
    QDeclarativeVisualModel *vim = 0;
    if (object && (vim = qobject_cast<QDeclarativeVisualModel *>(object))) {
        if (d->ownModel) {
            delete d->model;
            d->ownModel = false;
        }
        d->model = vim;
    } else {
        if (!d->ownModel) {
            d->model = new QDeclarativeVisualDataModel(qmlContext(this), this);
            d->ownModel = true;
        }
        if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model))
            dataModel->setModel(model);
    }
    if (d->model) {
        connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
        connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
        connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
        connect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
        /*
        connect(d->model, SIGNAL(createdItem(int,QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*)));
        connect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*)));
        */
        regenerate();
    }
    emit modelChanged();
    emit countChanged();
}

/*!
    \qmlproperty Component Repeater::delegate
    \default

    The delegate provides a template defining each item instantiated by the repeater.

    Delegates are exposed to a read-only \c index property that indicates the index
    of the delegate within the repeater. For example, the following \l Text delegate
    displays the index of each repeated item:

    \table
    \row
    \o \snippet doc/src/snippets/declarative/repeaters/repeater.qml index
    \o \image repeater-index.png
    \endtable

    If the \l model is a \l{QStringList-based model}{string list} or
    \l{QObjectList-based model}{object list}, the delegate is also exposed to
    a read-only \c modelData property that holds the string or object data. For
    example:

    \table
    \row
    \o \snippet doc/src/snippets/declarative/repeaters/repeater.qml modeldata
    \o \image repeater-modeldata.png
    \endtable

    If the \l model is a model object (such as a \l ListModel) the delegate
    can access all model roles as named properties, in the same way that delegates
    do for view classes like ListView.

    \sa {QML Data Models}
 */
QDeclarativeComponent *QDeclarativeRepeater::delegate() const
{
    Q_D(const QDeclarativeRepeater);
    if (d->model) {
        if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model))
            return dataModel->delegate();
    }

    return 0;
}

void QDeclarativeRepeater::setDelegate(QDeclarativeComponent *delegate)
{
    Q_D(QDeclarativeRepeater);
    if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model))
       if (delegate == dataModel->delegate())
           return;

    if (!d->ownModel) {
        d->model = new QDeclarativeVisualDataModel(qmlContext(this));
        d->ownModel = true;
    }
    if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model)) {
        dataModel->setDelegate(delegate);
        regenerate();
        emit delegateChanged();
    }
}

/*!
    \qmlproperty int Repeater::count

    This property holds the number of items in the repeater.
*/
int QDeclarativeRepeater::count() const
{
    Q_D(const QDeclarativeRepeater);
    if (d->model)
        return d->model->count();
    return 0;
}

/*!
    \qmlmethod Item Repeater::itemAt(index)
    \since QtQuick 1.1

    Returns the \l Item that has been created at the given \a index, or \c null
    if no item exists at \a index.
*/
QDeclarativeItem *QDeclarativeRepeater::itemAt(int index) const
{
    Q_D(const QDeclarativeRepeater);
    if (index >= 0 && index < d->deletables.count())
        return d->deletables[index];
    return 0;

}

void QDeclarativeRepeater::componentComplete()
{
    QDeclarativeItem::componentComplete();
    regenerate();
}

QVariant QDeclarativeRepeater::itemChange(GraphicsItemChange change,
                                       const QVariant &value)
{
    QVariant rv = QDeclarativeItem::itemChange(change, value);
    if (change == ItemParentHasChanged) {
        regenerate();
    }

    return rv;
}

void QDeclarativeRepeater::clear()
{
    Q_D(QDeclarativeRepeater);
    bool complete = isComponentComplete();

    if (d->model) {
        while (d->deletables.count() > 0) {
            QDeclarativeItem *item = d->deletables.takeLast();
            if (complete)
                emit itemRemoved(d->deletables.count()-1, item);
            d->model->release(item);
        }
    }
    d->deletables.clear();
}

void QDeclarativeRepeater::regenerate()
{
    Q_D(QDeclarativeRepeater);
    if (!isComponentComplete())
        return;

    clear();

    if (!d->model || !d->model->count() || !d->model->isValid() || !parentItem() || !isComponentComplete())
        return;

    for (int ii = 0; ii < count(); ++ii) {
        QDeclarativeItem *item = d->model->item(ii);
        if (item) {
            QDeclarative_setParent_noEvent(item, parentItem());
            item->setParentItem(parentItem());
            item->stackBefore(this);
            d->deletables << item;
            emit itemAdded(ii, item);
        }
    }
}

void QDeclarativeRepeater::itemsInserted(int index, int count)
{
    Q_D(QDeclarativeRepeater);
    if (!isComponentComplete())
        return;
    for (int i = 0; i < count; ++i) {
        int modelIndex = index + i;
        QDeclarativeItem *item = d->model->item(modelIndex);
        if (item) {
            QDeclarative_setParent_noEvent(item, parentItem());
            item->setParentItem(parentItem());
            if (modelIndex < d->deletables.count())
                item->stackBefore(d->deletables.at(modelIndex));
            else
                item->stackBefore(this);
            d->deletables.insert(modelIndex, item);
            emit itemAdded(modelIndex, item);
        }
    }
    emit countChanged();
}

void QDeclarativeRepeater::itemsRemoved(int index, int count)
{
    Q_D(QDeclarativeRepeater);
    if (!isComponentComplete() || count <= 0)
        return;
    while (count--) {
        QDeclarativeItem *item = d->deletables.takeAt(index);
        emit itemRemoved(index, item);
        if (item)
            d->model->release(item);
        else
            break;
    }
    emit countChanged();
}

void QDeclarativeRepeater::itemsMoved(int from, int to, int count)
{
    Q_D(QDeclarativeRepeater);
    if (!isComponentComplete() || count <= 0)
        return;
    if (from + count > d->deletables.count()) {
        regenerate();
        return;
    }
    QList<QDeclarativeItem*> removed;
    int removedCount = count;
    while (removedCount--)
        removed << d->deletables.takeAt(from);
    for (int i = 0; i < count; ++i)
        d->deletables.insert(to + i, removed.at(i));
    d->deletables.last()->stackBefore(this);
    for (int i = d->model->count()-1; i > 0; --i) {
        QDeclarativeItem *item = d->deletables.at(i-1);
        item->stackBefore(d->deletables.at(i));
    }
}

void QDeclarativeRepeater::modelReset()
{
    if (!isComponentComplete())
        return;
    regenerate();
    emit countChanged();
}

QT_END_NAMESPACE
