/****************************************************************************
**
** 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 "qquickcustomaffector_p.h"
#include <private/qqmlengine_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qjsvalue_p.h>
#include <QQmlEngine>
#include <QDebug>
QT_BEGIN_NAMESPACE

//TODO: Move docs (and inheritence) to real base when docs can propagate. Currently this pretends to be the base class!
/*!
    \qmlsignal QtQuick.Particles::Affector::affectParticles(Array particles, real dt)

    This signal is emitted when particles are selected to be affected. particles contains
    an array of particle objects which can be directly manipulated.

    dt is the time since the last time it was affected. Use dt to normalize
    trajectory manipulations to real time.

    Note that JavaScript is slower to execute, so it is not recommended to use this in
    high-volume particle systems.

    The corresponding handler is \c onAffectParticles.
*/

/*!
    \qmlproperty StochasticDirection QtQuick.Particles::Affector::position

    Affected particles will have their position set to this direction,
    relative to the ParticleSystem. When interpreting directions as points,
    imagine it as an arrow with the base at the 0,0 of the ParticleSystem and the
    tip at where the specified position will be.
*/

/*!
    \qmlproperty StochasticDirection QtQuick.Particles::Affector::velocity

    Affected particles will have their velocity set to this direction.
*/


/*!
    \qmlproperty StochasticDirection QtQuick.Particles::Affector::acceleration

    Affected particles will have their acceleration set to this direction.
*/


/*!
    \qmlproperty bool QtQuick.Particles::Affector::relative

    Whether the affected particles have their existing position/velocity/acceleration added
    to the new one.

    Default is true.
*/
QQuickCustomAffector::QQuickCustomAffector(QQuickItem *parent) :
    QQuickParticleAffector(parent)
    , m_position(&m_nullVector)
    , m_velocity(&m_nullVector)
    , m_acceleration(&m_nullVector)
    , m_relative(true)
{
}

bool QQuickCustomAffector::isAffectConnected()
{
    IS_SIGNAL_CONNECTED(this, QQuickCustomAffector, affectParticles, (const QJSValue &, qreal));
}

void QQuickCustomAffector::affectSystem(qreal dt)
{
    //Acts a bit differently, just emits affected for everyone it might affect, when the only thing is connecting to affected(x,y)
    bool justAffected = (m_acceleration == &m_nullVector
        && m_velocity == &m_nullVector
        && m_position == &m_nullVector
        && isAffectedConnected());
    if (!isAffectConnected() && !justAffected) {
        QQuickParticleAffector::affectSystem(dt);
        return;
    }
    if (!m_enabled)
        return;
    updateOffsets();

    QList<QQuickParticleData*> toAffect;
    foreach (QQuickParticleGroupData* gd, m_system->groupData) {
        if (activeGroup(gd->index)) {
            foreach (QQuickParticleData* d, gd->data) {
                if (shouldAffect(d)) {
                    toAffect << d;
                }
            }
        }
    }

    if (toAffect.isEmpty())
        return;

    if (justAffected) {
        foreach (QQuickParticleData* d, toAffect) {//Not postAffect to avoid saying the particle changed
            if (m_onceOff)
                m_onceOffed << qMakePair(d->groupId, d->index);
            emit affected(d->curX(m_system), d->curY(m_system));
        }
        return;
    }

    if (m_onceOff)
        dt = 1.0;

    QQmlEngine *qmlEngine = ::qmlEngine(this);
    QV4::ExecutionEngine *v4 = qmlEngine->handle();

    QV4::Scope scope(v4);
    QV4::ScopedArrayObject array(scope, v4->newArrayObject(toAffect.size()));
    QV4::ScopedValue v(scope);
    for (int i=0; i<toAffect.size(); i++)
        array->put(i, (v = toAffect[i]->v4Value(m_system)));

    const auto doAffect = [&](qreal dt) {
        affectProperties(toAffect, dt);
        QJSValue particles;
        QJSValuePrivate::setValue(&particles, v4, array);
        emit affectParticles(particles, dt);
    };

    if (dt >= simulationCutoff || dt <= simulationDelta) {
        doAffect(dt);
    } else {
        int realTime = m_system->timeInt;
        m_system->timeInt -= dt * 1000.0;
        while (dt > simulationDelta) {
            m_system->timeInt += simulationDelta * 1000.0;
            dt -= simulationDelta;
            doAffect(simulationDelta);
        }
        m_system->timeInt = realTime;
        if (dt > 0.0)
            doAffect(dt);
    }

    foreach (QQuickParticleData* d, toAffect)
        if (d->update == 1.0)
            postAffect(d);
}

bool QQuickCustomAffector::affectParticle(QQuickParticleData *d, qreal dt)
{
    //This does the property based affecting, called by superclass if signal isn't hooked up.
    bool changed = false;
    QPointF curPos(d->curX(m_system), d->curY(m_system));

    if (m_acceleration != &m_nullVector){
        QPointF pos = m_acceleration->sample(curPos);
        QPointF curAcc = QPointF(d->curAX(), d->curAY());
        if (m_relative) {
            pos *= dt;
            pos += curAcc;
        }
        if (pos != curAcc) {
            d->setInstantaneousAX(pos.x(), m_system);
            d->setInstantaneousAY(pos.y(), m_system);
            changed = true;
        }
    }

    if (m_velocity != &m_nullVector){
        QPointF pos = m_velocity->sample(curPos);
        QPointF curVel = QPointF(d->curVX(m_system), d->curVY(m_system));
        if (m_relative) {
            pos *= dt;
            pos += curVel;
        }
        if (pos != curVel) {
            d->setInstantaneousVX(pos.x(), m_system);
            d->setInstantaneousVY(pos.y(), m_system);
            changed = true;
        }
    }

    if (m_position != &m_nullVector){
        QPointF pos = m_position->sample(curPos);
        if (m_relative) {
            pos *= dt;
            pos += curPos;
        }
        if (pos != curPos) {
            d->setInstantaneousX(pos.x(), m_system);
            d->setInstantaneousY(pos.y(), m_system);
            changed = true;
        }
    }

    return changed;
}

void QQuickCustomAffector::affectProperties(const QList<QQuickParticleData*> &particles, qreal dt)
{
    foreach (QQuickParticleData* d, particles)
        if ( affectParticle(d, dt) )
            d->update = 1.0;
}

QT_END_NAMESPACE

#include "moc_qquickcustomaffector_p.cpp"
