/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick 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 "qquickitemparticle_p.h"
#include <QtQuick/qsgnode.h>
#include <QTimer>
#include <QQmlComponent>
#include <QDebug>

QT_BEGIN_NAMESPACE

/*!
    \qmltype ItemParticle
    \instantiates QQuickItemParticle
    \inqmlmodule QtQuick.Particles
    \inherits ParticlePainter
    \brief For specifying a delegate to paint particles.
    \ingroup qtquick-particles

*/


/*!
    \qmlmethod QtQuick.Particles::ItemParticle::freeze(Item item)

    Suspends the flow of time for the logical particle which \a item represents,
    allowing you to control its movement.
*/

/*!
    \qmlmethod QtQuick.Particles::ItemParticle::unfreeze(Item item)

    Restarts the flow of time for the logical particle which \a item represents,
    allowing it to be moved by the particle system again.
*/

/*!
    \qmlmethod QtQuick.Particles::ItemParticle::take(Item item, bool prioritize)

    Asks the ItemParticle to take over control of \a item positioning temporarily.
    It will follow the movement of a logical particle when one is available.

    By default items form a queue when waiting for a logical particle, but if
    \a prioritize is \c true, then it will go immediately to the head of the
    queue.

    ItemParticle does not take ownership of the item, and will relinquish
    control when the logical particle expires. Commonly at this point you will
    want to put it back in the queue, you can do this with the below line in
    the delegate definition:

    \code
    ItemParticle.onDetached: itemParticleInstance.take(delegateRootItem);
    \endcode

    or delete it, such as with the below line in the delegate definition:

    \code
    ItemParticle.onDetached: delegateRootItem.destroy();
    \endcode
*/

/*!
    \qmlmethod QtQuick.Particles::ItemParticle::give(Item item)

    Orders the ItemParticle to give you control of the \a item. It will cease
    controlling it and the item will lose its association to the logical
    particle.
*/

/*!
    \qmlproperty bool QtQuick.Particles::ItemParticle::fade

    If true, the item will automatically be faded in and out
    at the ends of its lifetime. If false, you will have to
    implement any entry effect yourself.

    Default is true.
*/
/*!
    \qmlproperty Component QtQuick.Particles::ItemParticle::delegate

    An instance of the delegate will be created for every logical particle, and
    moved along with it. As an alternative to using delegate, you can create
    Item instances yourself and hand them to the ItemParticle to move using the
    \l take method.

    Any delegate instances created by ItemParticle will be destroyed when
    the logical particle expires.
*/

QQuickItemParticle::QQuickItemParticle(QQuickItem *parent) :
    QQuickParticlePainter(parent), m_fade(true), m_lastT(0), m_activeCount(0), m_delegate(nullptr)
{
    setFlag(QQuickItem::ItemHasContents);
    clock = new Clock(this);
    clock->start();
}

QQuickItemParticle::~QQuickItemParticle()
{
    delete clock;
    qDeleteAll(m_managed);
}

void QQuickItemParticle::freeze(QQuickItem* item)
{
    m_stasis << item;
}


void QQuickItemParticle::unfreeze(QQuickItem* item)
{
    m_stasis.remove(item);
}

void QQuickItemParticle::take(QQuickItem *item, bool prioritize)
{
    if (prioritize)
        m_pendingItems.push_front(item);
    else
        m_pendingItems.push_back(item);
}

void QQuickItemParticle::give(QQuickItem *item)
{
    //TODO: This
    Q_UNUSED(item);
}

void QQuickItemParticle::initialize(int gIdx, int pIdx)
{
    Q_UNUSED(gIdx);
    Q_UNUSED(pIdx);
}

void QQuickItemParticle::commit(int, int)
{
}

void QQuickItemParticle::processDeletables()
{
    foreach (QQuickItem* item, m_deletables){
        if (m_fade)
            item->setOpacity(0.);
        item->setVisible(false);
        QQuickItemParticleAttached* mpa;
        if ((mpa = qobject_cast<QQuickItemParticleAttached*>(qmlAttachedPropertiesObject<QQuickItemParticle>(item))))
            mpa->detach();//reparent as well?
        int idx = -1;
        if ((idx = m_managed.indexOf(item)) != -1) {
            m_managed.takeAt(idx);
            delete item;
        }
        m_activeCount--;
    }
    m_deletables.clear();
}

void QQuickItemParticle::tick(int time)
{
    Q_UNUSED(time);//only needed because QTickAnimationProxy expects one
    processDeletables();

    for (auto groupId : groupIds()) {
        for (QQuickParticleData* d : qAsConst(m_system->groupData[groupId]->data)) {
            if (!d->delegate && d->t != -1 && d->stillAlive(m_system)) {
                if (!m_pendingItems.isEmpty()){
                    d->delegate = m_pendingItems.front();
                    m_pendingItems.pop_front();
                }else if (m_delegate){
                    d->delegate = qobject_cast<QQuickItem*>(m_delegate->create(qmlContext(this)));
                    if (d->delegate)
                        m_managed << d->delegate;
                }
                if (d && d->delegate){//###Data can be zero if creating an item leads to a reset - this screws things up.
                    d->delegate->setX(d->curX(m_system) - d->delegate->width() / 2); //TODO: adjust for system?
                    d->delegate->setY(d->curY(m_system) - d->delegate->height() / 2);
                    QQuickItemParticleAttached* mpa = qobject_cast<QQuickItemParticleAttached*>(qmlAttachedPropertiesObject<QQuickItemParticle>(d->delegate));
                    if (mpa){
                        mpa->m_mp = this;
                        mpa->attach();
                    }
                    d->delegate->setParentItem(this);
                    if (m_fade)
                        d->delegate->setOpacity(0.);
                    d->delegate->setVisible(false);//Will be set to true when we prepare the next frame
                    m_activeCount++;
                }
            }
        }
    }
}

void QQuickItemParticle::reset()
{
    QQuickParticlePainter::reset();

    // delete all managed items which had their logical particles cleared
    // but leave it alone if the logical particle is maintained
    QSet<QQuickItem*> lost = QSet<QQuickItem*>(m_managed.cbegin(), m_managed.cend());
    for (auto groupId : groupIds()) {
        for (QQuickParticleData* d : qAsConst(m_system->groupData[groupId]->data)) {
            lost.remove(d->delegate);
        }
    }
    m_deletables.unite(lost);
    //TODO: This doesn't yet handle calling detach on taken particles in the system reset case
    processDeletables();
}


QSGNode* QQuickItemParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d)
{
    //Dummy update just to get painting tick
    if (m_pleaseReset)
        m_pleaseReset = false;

    prepareNextFrame();

    update();//Get called again
    if (n)
        n->markDirty(QSGNode::DirtyMaterial);
    return QQuickItem::updatePaintNode(n,d);
}

void QQuickItemParticle::prepareNextFrame()
{
    if (!m_system)
        return;
    qint64 timeStamp = m_system->systemSync(this);
    qreal curT = timeStamp/1000.0;
    qreal dt = curT - m_lastT;
    m_lastT = curT;
    if (!m_activeCount)
        return;

    //TODO: Size, better fade?
    for (auto groupId : groupIds()) {
        for (QQuickParticleData* data : qAsConst(m_system->groupData[groupId]->data)) {
            QQuickItem* item = data->delegate;
            if (!item)
                continue;
            float t = ((timeStamp / 1000.0f) - data->t) / data->lifeSpan;
            if (m_stasis.contains(item)) {
                data->t += dt;//Stasis effect
                continue;
            }
            if (t >= 1.0f){//Usually happens from load
                m_deletables << item;
                data->delegate = nullptr;
            }else{//Fade
                data->delegate->setVisible(true);
                if (m_fade){
                    float o = 1.f;
                    if (t <0.2f)
                        o = t * 5;
                    if (t > 0.8f)
                        o = (1-t)*5;
                    item->setOpacity(o);
                }
            }
            item->setX(data->curX(m_system) - item->width() / 2 - m_systemOffset.x());
            item->setY(data->curY(m_system) - item->height() / 2 - m_systemOffset.y());
        }
    }
}

QQuickItemParticleAttached *QQuickItemParticle::qmlAttachedProperties(QObject *object)
{
    return new QQuickItemParticleAttached(object);
}

QT_END_NAMESPACE

#include "moc_qquickitemparticle_p.cpp"
