/****************************************************************************
**
** 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 "qquickparticleaffector_p.h"
#include <QDebug>
#include <private/qqmlglobal_p.h>
QT_BEGIN_NAMESPACE

/*!
    \qmltype Affector
    \instantiates QQuickParticleAffector
    \inqmlmodule QtQuick.Particles
    \brief Applies alterations to the attributes of logical particles at any
    point in their lifetime.
    \ingroup qtquick-particles

    The base Affector does not alter any attributes, but can be used to emit a signal
    when a particle meets certain conditions.

    If an affector has a defined size, then it will only affect particles within its size and position on screen.

    Affectors have different performance characteristics to the other particle system elements. In particular,
    they have some simplifications to try to maintain a simulation at real-time or faster. When running a system
    with Affectors, irregular frame timings that grow too large ( > one second per frame) will cause the Affectors
    to try and cut corners with a faster but less accurate simulation. If the system has multiple affectors the order
    in which they are applied is not guaranteed, and when simulating larger time shifts they will simulate the whole
    shift each, which can lead to different results compared to smaller time shifts.

    Accurate simulation for large numbers of particles (hundreds) with multiple affectors may be possible on some hardware,
    but on less capable hardware you should expect small irregularties in the simulation as simulates with worse granularity.
*/
/*!
    \qmlproperty ParticleSystem QtQuick.Particles::Affector::system
    This is the system which will be affected by the element.
    If the Affector is a direct child of a ParticleSystem, it will automatically be associated with it.
*/
/*!
    \qmlproperty list<string> QtQuick.Particles::Affector::groups
    Which logical particle groups will be affected.

    If empty, it will affect all particles.
*/
/*!
    \qmlproperty list<string> QtQuick.Particles::Affector::whenCollidingWith
    If any logical particle groups are specified here, then the affector
    will only be triggered if the particle being examined intersects with
    a particle of one of these groups.

    This is different from the groups property. The groups property selects which
    particles might be examined, and if they meet other criteria (including being
    within the bounds of the Affector, modified by shape) then they will be tested
    again to see if they intersect with a particles from one of the particle groups
    in whenCollidingWith.

    By default, no groups are specified.
*/
/*!
    \qmlproperty bool QtQuick.Particles::Affector::enabled
    If enabled is set to false, this affector will not affect any particles.

    Usually this is used to conditionally turn an affector on or off.

    Default value is true.
*/
/*!
    \qmlproperty bool QtQuick.Particles::Affector::once
    If once is set to true, this affector will only affect each particle
    once in their lifetimes. If the affector normally simulates a continuous
    effect over time, then it will simulate the effect of one second of time
    the one instant it affects the particle.

    Default value is false.
*/
/*!
    \qmlproperty Shape QtQuick.Particles::Affector::shape
    If a size has been defined, the shape property can be used to affect a
    non-rectangular area.
*/
/*!
    \qmlsignal QtQuick.Particles::Affector::affected(real x, real y)

    This signal is emitted when a particle is selected to be affected. It will not be emitted
    if a particle is considered by the Affector but not actually altered in any way.

    In the special case where an Affector has no possible effect (e.g. Affector {}), this signal
    will be emitted for all particles being considered if you connect to it. This allows you to
    execute arbitrary code in response to particles (use the Affector::onAffectParticles
    signal handler if you want to execute code which affects the particles
    themselves). As this executes JavaScript code per particle, it is not recommended to use this
    signal with a high-volume particle system.

    (\a {x}, \a {y}) is the particle's current position.
*/
QQuickParticleAffector::QQuickParticleAffector(QQuickItem *parent) :
    QQuickItem(parent), m_needsReset(false), m_ignoresTime(false), m_onceOff(false), m_enabled(true)
    , m_system(nullptr), m_updateIntSet(false), m_shape(new QQuickParticleExtruder(this))
{
}

bool QQuickParticleAffector::isAffectedConnected()
{
    IS_SIGNAL_CONNECTED(this, QQuickParticleAffector, affected, (qreal,qreal));
}


void QQuickParticleAffector::componentComplete()
{
    if (!m_system && qobject_cast<QQuickParticleSystem*>(parentItem()))
        setSystem(qobject_cast<QQuickParticleSystem*>(parentItem()));
    QQuickItem::componentComplete();
}

bool QQuickParticleAffector::activeGroup(int g) {
    if (m_updateIntSet){ //This can occur before group ids are properly assigned, but that resets the flag
        m_groupIds.clear();
        foreach (const QString &p, m_groups)
            m_groupIds << m_system->groupIds[p];
        m_updateIntSet = false;
    }
    return m_groupIds.isEmpty() || m_groupIds.contains(g);
}

bool QQuickParticleAffector::shouldAffect(QQuickParticleData* d)
{
    if (!d)
        return false;
    if (activeGroup(d->groupId)){
        if ((m_onceOff && m_onceOffed.contains(qMakePair(d->groupId, d->index)))
                || !d->stillAlive(m_system))
            return false;
        //Need to have previous location for affected anyways
        if (width() == 0 || height() == 0
                || m_shape->contains(QRectF(m_offset.x(), m_offset.y(), width(), height()), QPointF(d->curX(m_system), d->curY(m_system)))){
            if (m_whenCollidingWith.isEmpty() || isColliding(d)){
                return true;
            }
        }
    }
    return false;

}

void QQuickParticleAffector::postAffect(QQuickParticleData* d)
{
    m_system->needsReset << d;
    if (m_onceOff)
        m_onceOffed << qMakePair(d->groupId, d->index);
    if (isAffectedConnected())
        emit affected(d->curX(m_system), d->curY(m_system));
}

const qreal QQuickParticleAffector::simulationDelta = 0.020;
const qreal QQuickParticleAffector::simulationCutoff = 1.000;//If this goes above 1.0, then m_once behaviour needs special codepath

void QQuickParticleAffector::affectSystem(qreal dt)
{
    if (!m_enabled)
        return;
    //If not reimplemented, calls affectParticle per particle
    //But only on particles in targeted system/area
    updateOffsets();//### Needed if an ancestor is transformed.
    if (m_onceOff)
        dt = 1.0;
    foreach (QQuickParticleGroupData* gd, m_system->groupData) {
        if (activeGroup(gd->index)) {
            foreach (QQuickParticleData* d, gd->data) {
                if (shouldAffect(d)) {
                    bool affected = false;
                    qreal myDt = dt;
                    if (!m_ignoresTime && myDt < simulationCutoff) {
                        int realTime = m_system->timeInt;
                        m_system->timeInt -= myDt * 1000.0;
                        while (myDt > simulationDelta) {
                            m_system->timeInt += simulationDelta * 1000.0;
                            if (d->alive(m_system))//Only affect during the parts it was alive for
                                affected = affectParticle(d, simulationDelta) || affected;
                            myDt -= simulationDelta;
                        }
                        m_system->timeInt = realTime;
                    }
                    if (myDt > 0.0)
                        affected = affectParticle(d, myDt) || affected;
                    if (affected)
                        postAffect(d);
                }
            }
        }
    }
}

bool QQuickParticleAffector::affectParticle(QQuickParticleData *, qreal )
{
    return true;
}

void QQuickParticleAffector::reset(QQuickParticleData* pd)
{//TODO: This, among other ones, should be restructured so they don't all need to remember to call the superclass
    if (m_onceOff)
        if (activeGroup(pd->groupId))
            m_onceOffed.remove(qMakePair(pd->groupId, pd->index));
}

void QQuickParticleAffector::updateOffsets()
{
    if (m_system)
        m_offset = m_system->mapFromItem(this, QPointF(0, 0));
}

bool QQuickParticleAffector::isColliding(QQuickParticleData *d) const
{
    qreal myCurX = d->curX(m_system);
    qreal myCurY = d->curY(m_system);
    qreal myCurSize = d->curSize(m_system) / 2;
    foreach (const QString &group, m_whenCollidingWith){
        foreach (QQuickParticleData* other, m_system->groupData[m_system->groupIds[group]]->data){
            if (!other->stillAlive(m_system))
                continue;
            qreal otherCurX = other->curX(m_system);
            qreal otherCurY = other->curY(m_system);
            qreal otherCurSize = other->curSize(m_system) / 2;
            if ((myCurX + myCurSize > otherCurX - otherCurSize
                 && myCurX - myCurSize < otherCurX + otherCurSize)
                 && (myCurY + myCurSize > otherCurY - otherCurSize
                     && myCurY - myCurSize < otherCurY + otherCurSize))
                return true;
        }
    }
    return false;
}

QT_END_NAMESPACE

#include "moc_qquickparticleaffector_p.cpp"
