/****************************************************************************
**
** 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)
{
    for (auto groupId : groupIds()) {
        for (QQuickParticleData* data : qAsConst(m_system->groupData[groupId]->data)) {
            if (data->delegate == item){
                m_deletables << item;
                data->delegate = nullptr;
                return;
            }
        }
    }
}

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)))) {
            if (mpa->m_parentItem != nullptr)
                item->setParentItem(mpa->m_parentItem);
            mpa->detach();
        }
        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)) {
                QQuickItem* parentItem = nullptr;
                if (!m_pendingItems.isEmpty()){
                    QQuickItem *item = m_pendingItems.front();
                    m_pendingItems.pop_front();
                    parentItem = item->parentItem();
                    d->delegate = item;
                }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_parentItem = parentItem;
                        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"
