/****************************************************************************
**
** 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 "qquickspriteengine_p.h"
#include "qquicksprite_p.h"
#include <qqmlinfo.h>
#include <qqml.h>
#include <QDebug>
#include <QPainter>
#include <QRandomGenerator>
#include <QSet>
#include <QtGui/qopengl.h>
#include <QOpenGLFunctions>

QT_BEGIN_NAMESPACE

/*
    \internal Stochastic/Sprite engine implementation docs

    Nomenclature: 'thing' refers to an instance of a running sprite or state. It could be renamed.
    States and Transitions are referred to in the state machine sense here, NOT in the QML sense.

    The Stochastic State engine takes states with stochastic state transitions defined and transitions them.
    When a state is started, it's added to a list of pending updates sorted by their time they want to update.
    An external driver calls the update function with an elapsed time, which becomes the new time offset.
    The pending update stack is popped until all entries are past the current time, which simulates all intervening time.

    The Sprite Engine subclass has two major differences. Firstly all states are sprites (and there's a new vector with them
    cast to sprite). Secondly, it chops up images and states to fit a texture friendly format.
    Before the Sprite Engine starts running, its user requests a texture assembled from all the sprite images. This
    texture is made by pasting the sprites into one image, with one sprite animation per row (in the future it is planned to have
    arbitrary X/Y start ends, but they will still be assembled and recorded here and still have to be contiguous lines).
    This cut-up allows the users to calcuate frame positions with a texture percentage width and elapsed time.
    It also means that large sprites cover multiple lines to fit inside the texture memory limit (which is a square).

    Large sprites covering multiple lines breaks this simple interface for the users, so each line is treated as a pseudostate
    and it's mostly hidden from the spriteengine users (except that they'll get advanced signals where the state is the same
    but the visual parameters changed). These are not real states because that would get very complex with bindings. Instead,
    when sprite attributes are requested from a sprite that has multiple pseudostates, it returns the values for the psuedostate
    it is in. State advancement is intercepted and hollow for pseudostates, except the last one. The last one transitions as the
    state normally does.
*/

static const int NINF = -1000000;//magic number for random start time - should be more negative than a single realistic animation duration
//#define SPRITE_IMAGE_DEBUG
#ifdef SPRITE_IMAGE_DEBUG
#include <QFile>
#include <QDir>
#endif
/* TODO:
   make sharable?
   solve the state data initialization/transfer issue so as to not need to make friends
*/

QQuickStochasticEngine::QQuickStochasticEngine(QObject *parent) :
    QObject(parent), m_timeOffset(0), m_addAdvance(false)
{
    //Default size 1
    setCount(1);
}

QQuickStochasticEngine::QQuickStochasticEngine(const QList<QQuickStochasticState *> &states, QObject *parent) :
    QObject(parent), m_states(states), m_timeOffset(0), m_addAdvance(false)
{
    //Default size 1
    setCount(1);
}

QQuickStochasticEngine::~QQuickStochasticEngine()
{
}

QQuickSpriteEngine::QQuickSpriteEngine(QObject *parent)
    : QQuickStochasticEngine(parent), m_startedImageAssembly(false), m_loaded(false)
{
}

QQuickSpriteEngine::QQuickSpriteEngine(const QList<QQuickSprite *> &sprites, QObject *parent)
    : QQuickSpriteEngine(parent)
{
    for (QQuickSprite* sprite : sprites)
        m_states << (QQuickStochasticState*)sprite;
}

QQuickSpriteEngine::~QQuickSpriteEngine()
{
}


int QQuickSpriteEngine::maxFrames() const
{
    return m_maxFrames;
}

/* States too large to fit in one row are split into multiple rows
   This is more efficient for the implementation, but should remain an implementation detail (invisible from QML)
   Therefore the below functions abstract sprite from the viewpoint of classes that pass the details onto shaders
   But States maintain their listed index for internal structures
TODO: All these calculations should be pre-calculated and cached during initialization for a significant performance boost
TODO: Above idea needs to have the varying duration offset added to it
*/
//TODO: Should these be adding advanceTime as well? But only if advanceTime was added to your startTime...
/*
    To get these working with duration=-1, m_startTimes will be messed with should duration=-1
    m_startTimes will be set in advance/restart to 0->(m_framesPerRow-1) and can be used directly as extra.
    This makes it 'frame' instead, but is more memory efficient than two arrays and less hideous than a vector of unions.
*/
int QQuickSpriteEngine::pseudospriteProgress(int sprite, int state, int* rowDuration) const
{
    int myRowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow / m_sprites[state]->m_frames;
    if (rowDuration)
        *rowDuration = myRowDuration;

    if (m_sprites[state]->reverse()) //shift start-time back by the amount of time the first frame is smaller than rowDuration
        return (m_timeOffset - (m_startTimes[sprite] - (myRowDuration - (m_duration[sprite] % myRowDuration))) )
                    / myRowDuration;
    else
        return (m_timeOffset - m_startTimes[sprite]) / myRowDuration;
}

int QQuickSpriteEngine::spriteState(int sprite) const
{
    if (!m_loaded)
        return 0;
    int state = m_things[sprite];
    if (!m_sprites[state]->m_generatedCount)
        return state;

    int extra;
    if (m_sprites[state]->frameSync())
        extra = m_startTimes[sprite];
    else if (!m_duration[sprite])
        return state;
    else
        extra = pseudospriteProgress(sprite, state);
    if (m_sprites[state]->reverse())
        extra = (m_sprites[state]->m_generatedCount - 1) - extra;

    return state + extra;
}

int QQuickSpriteEngine::spriteStart(int sprite) const
{
    if (!m_duration[sprite] || !m_loaded)
        return m_timeOffset;
    int state = m_things[sprite];
    if (!m_sprites[state]->m_generatedCount)
        return m_startTimes[sprite];
    int rowDuration;
    int extra = pseudospriteProgress(sprite, state, &rowDuration);
    if (m_sprites[state]->reverse())
        return m_startTimes[sprite] + (extra ? (extra - 1)*rowDuration + (m_duration[sprite] % rowDuration) : 0);
    return m_startTimes[sprite] + extra*rowDuration;
}

int QQuickSpriteEngine::spriteFrames(int sprite) const
{
    if (!m_loaded)
        return 1;
    int state = m_things[sprite];
    if (!m_sprites[state]->m_generatedCount)
        return m_sprites[state]->frames();

    int extra;
    if (m_sprites[state]->frameSync())
        extra = m_startTimes[sprite];
    else if (!m_duration[sprite])
        return m_sprites[state]->frames();
    else
        extra = pseudospriteProgress(sprite, state);
    if (m_sprites[state]->reverse())
        extra = (m_sprites[state]->m_generatedCount - 1) - extra;


    if (extra == m_sprites[state]->m_generatedCount - 1) {//last state
        const int framesRemaining = m_sprites[state]->frames() % m_sprites[state]->m_framesPerRow;
        if (framesRemaining > 0)
            return framesRemaining;
    }
    return m_sprites[state]->m_framesPerRow;
}

int QQuickSpriteEngine::spriteDuration(int sprite) const //Full duration, not per frame
{
    if (!m_duration[sprite] || !m_loaded)
        return m_duration[sprite];
    int state = m_things[sprite];
    if (!m_sprites[state]->m_generatedCount)
        return m_duration[sprite];
    int rowDuration;
    int extra = pseudospriteProgress(sprite, state, &rowDuration);
    if (m_sprites[state]->reverse())
        extra = (m_sprites[state]->m_generatedCount - 1) - extra;

    if (extra == m_sprites[state]->m_generatedCount - 1) {//last state
        const int durationRemaining = m_duration[sprite] % rowDuration;
        if (durationRemaining > 0)
            return durationRemaining;
    }
    return rowDuration;
}

int QQuickSpriteEngine::spriteY(int sprite) const
{
    if (!m_loaded)
        return 0;
    int state = m_things[sprite];
    if (!m_sprites[state]->m_generatedCount)
        return m_sprites[state]->m_rowY;

    int extra;
    if (m_sprites[state]->frameSync())
        extra = m_startTimes[sprite];
    else if (!m_duration[sprite])
        return m_sprites[state]->m_rowY;
    else
        extra = pseudospriteProgress(sprite, state);
    if (m_sprites[state]->reverse())
        extra = (m_sprites[state]->m_generatedCount - 1) - extra;


    return m_sprites[state]->m_rowY + m_sprites[state]->m_frameHeight * extra;
}

int QQuickSpriteEngine::spriteX(int sprite) const
{
    if (!m_loaded)
        return 0;
    int state = m_things[sprite];
    if (!m_sprites[state]->m_generatedCount)
        return m_sprites[state]->m_rowStartX;

    int extra;
    if (m_sprites[state]->frameSync())
        extra = m_startTimes[sprite];
    else if (!m_duration[sprite])
        return m_sprites[state]->m_rowStartX;
    else
        extra = pseudospriteProgress(sprite, state);
    if (m_sprites[state]->reverse())
        extra = (m_sprites[state]->m_generatedCount - 1) - extra;

    if (extra)
        return 0;
    return m_sprites[state]->m_rowStartX;
}

QQuickSprite* QQuickSpriteEngine::sprite(int sprite) const
{
    return m_sprites[m_things[sprite]];
}

int QQuickSpriteEngine::spriteWidth(int sprite) const
{
    int state = m_things[sprite];
    return m_sprites[state]->m_frameWidth;
}

int QQuickSpriteEngine::spriteHeight(int sprite) const
{
    int state = m_things[sprite];
    return m_sprites[state]->m_frameHeight;
}

int QQuickSpriteEngine::spriteCount() const //TODO: Actually image state count, need to rename these things to make sense together
{
    return m_imageStateCount;
}

void QQuickStochasticEngine::setGoal(int state, int sprite, bool jump)
{
    if (sprite >= m_things.count() || state >= m_states.count()
            || sprite < 0 || state < 0)
        return;
    if (!jump){
        m_goals[sprite] = state;
        return;
    }

    if (m_things.at(sprite) == state)
        return;//Already there
    m_things[sprite] = state;
    m_duration[sprite] = m_states.at(state)->variedDuration();
    m_goals[sprite] = -1;
    restart(sprite);
    emit stateChanged(sprite);
    emit m_states.at(state)->entered();
    return;
}

QQuickPixmap::Status QQuickSpriteEngine::status() const //Composed status of all Sprites
{
    if (!m_startedImageAssembly)
        return QQuickPixmap::Null;
    int null, loading, ready;
    null = loading = ready = 0;
    for (QQuickSprite* s : m_sprites) {
        switch (s->m_pix.status()) {
            // ### Maybe add an error message here, because this null shouldn't be reached but when it does, the image fails without an error message.
            case QQuickPixmap::Null : null++; break;
            case QQuickPixmap::Loading : loading++; break;
            case QQuickPixmap::Error : return QQuickPixmap::Error;
            case QQuickPixmap::Ready : ready++; break;
        }
    }
    if (null)
        return QQuickPixmap::Null;
    if (loading)
        return QQuickPixmap::Loading;
    if (ready)
        return QQuickPixmap::Ready;
    return QQuickPixmap::Null;
}

void QQuickSpriteEngine::startAssemblingImage()
{
    if (m_startedImageAssembly)
        return;
    m_loaded = false;
    m_errorsPrinted = false;

    //This could also trigger the start of the image loading in Sprites, however that currently happens in Sprite::setSource

    QList<QQuickStochasticState*> removals;

    for (QQuickStochasticState* s : qAsConst(m_states)) {
        QQuickSprite* sprite = qobject_cast<QQuickSprite*>(s);
        if (sprite) {
            m_sprites << sprite;
        } else {
            removals << s;
            qDebug() << "Error: Non-sprite in QQuickSpriteEngine";
        }
    }
    for (QQuickStochasticState* s : qAsConst(removals))
        m_states.removeAll(s);
    m_startedImageAssembly = true;
}

QImage QQuickSpriteEngine::assembledImage(int maxSize)
{
    QQuickPixmap::Status stat = status();
    if (!m_errorsPrinted && stat == QQuickPixmap::Error) {
        for (QQuickSprite* s : qAsConst(m_sprites))
            if (s->m_pix.isError())
                qmlWarning(s) << s->m_pix.error();
        m_errorsPrinted = true;
    }

    if (stat != QQuickPixmap::Ready)
        return QImage();

    int h = 0;
    int w = 0;
    m_maxFrames = 0;
    m_imageStateCount = 0;
    qreal pixelRatio = 1.0;

    for (QQuickSprite* state : qAsConst(m_sprites)) {
        if (state->frames() > m_maxFrames)
            m_maxFrames = state->frames();

        QImage img = state->m_pix.image();

        {
            const QSize frameSize(state->m_frameWidth, state->m_frameHeight);
            if (!(img.size() - frameSize).isValid()) {
                qmlWarning(state).nospace() << "SpriteEngine: Invalid frame size " << frameSize << "."
                                            " It's bigger than image size " << img.size() << ".";
                return QImage();
            }
        }

        //Check that the frame sizes are the same within one sprite
        if (!state->m_frameWidth)
            state->m_frameWidth = img.width() / state->frames();

        if (!state->m_frameHeight)
            state->m_frameHeight = img.height();

        pixelRatio = qMax(pixelRatio, state->devicePixelRatio());

        if (state->frames() * state->frameWidth() > maxSize){
            struct helper{
                static int divRoundUp(int a, int b){return (a+b-1)/b;}
            };
            int rowsNeeded = helper::divRoundUp(state->frames(), (maxSize / state->frameWidth()));
            if (h + rowsNeeded * state->frameHeight() > maxSize){
                if (rowsNeeded * state->frameHeight() > maxSize)
                    qmlWarning(state) << "SpriteEngine: Animation too large to fit in one texture:" << state->source().toLocalFile();
                else
                    qmlWarning(state) << "SpriteEngine: Animations too large to fit in one texture, pushed over the edge by:" << state->source().toLocalFile();
                qmlWarning(state) << "SpriteEngine: Your texture max size today is " << maxSize;
                return QImage();
            }
            state->m_generatedCount = rowsNeeded;
            h += state->frameHeight() * rowsNeeded;
            w = qMax(w, ((int)(maxSize / state->frameWidth())) * state->frameWidth());
            m_imageStateCount += rowsNeeded;
        }else{
            h += state->frameHeight();
            w = qMax(w, state->frameWidth() * state->frames());
            m_imageStateCount++;
        }
    }

    if (h > maxSize){
        qWarning() << "SpriteEngine: Too many animations to fit in one texture...";
        qWarning() << "SpriteEngine: Your texture max size today is " << maxSize;
        return QImage();
    }

    //maxFrames is max number in a line of the texture
    QImage image(w * pixelRatio, h * pixelRatio, QImage::Format_ARGB32_Premultiplied);
    image.setDevicePixelRatio(pixelRatio);
    image.fill(0);
    QPainter p(&image);
    int y = 0;
    for (QQuickSprite* state : qAsConst(m_sprites)) {
        QImage img(state->m_pix.image());
        const int frameWidth = state->m_frameWidth;
        const int frameHeight = state->m_frameHeight;
        const int imgHeight = img.height() / img.devicePixelRatioF();
        const int imgWidth = img.width() / img.devicePixelRatioF();
        if (imgHeight == frameHeight && imgWidth <  maxSize){ //Simple case
            p.drawImage(QRect(0, y, state->m_frames * frameWidth, frameHeight),
                        img,
                        QRect(state->m_frameX * img.devicePixelRatioF(), 0, state->m_frames * frameWidth * img.devicePixelRatioF(), frameHeight * img.devicePixelRatioF()));
            state->m_rowStartX = 0;
            state->m_rowY = y;
            y += frameHeight;
        } else { //Chopping up image case
            state->m_framesPerRow = w/frameWidth;
            state->m_rowY = y;
            int x = 0;
            int curX = state->m_frameX;
            int curY = state->m_frameY;
            int framesLeft = state->frames();
            while (framesLeft > 0){
                if (w - x + curX <= imgWidth){//finish a row in image (dest)
                    int copied = w - x;
                    framesLeft -= copied/frameWidth;
                    p.drawImage(QRect(x, y, copied, frameHeight),
                                img,
                                QRect(curX * img.devicePixelRatioF(), curY * img.devicePixelRatioF(), copied * img.devicePixelRatioF(), frameHeight * img.devicePixelRatioF()));
                    y += frameHeight;
                    curX += copied;
                    x = 0;
                    if (curX == imgWidth){
                        curX = 0;
                        curY += frameHeight;
                    }
                }else{//finish a row in img (src)
                    int copied = imgWidth - curX;
                    framesLeft -= copied/frameWidth;
                    p.drawImage(QRect(x, y, copied, frameHeight),
                                img,
                                QRect(curX * img.devicePixelRatioF(), curY * img.devicePixelRatioF(), copied * img.devicePixelRatioF(), frameHeight * img.devicePixelRatioF()));
                    curY += frameHeight;
                    x += copied;
                    curX = 0;
                }
            }
            if (x)
                y += frameHeight;
        }
    }

#ifdef SPRITE_IMAGE_DEBUG
    QString fPath = QDir::tempPath() + "/SpriteImage.%1.png";
    int acc = 0;
    while (QFile::exists(fPath.arg(acc))) acc++;
    image.save(fPath.arg(acc), "PNG");
    qDebug() << "Assembled image output to: " << fPath.arg(acc);
#endif

    m_loaded = true;
    m_startedImageAssembly = false;
    return image;
}

//TODO: Add a reset() function, for completeness in the case of a SpriteEngine being restarted from 0
void QQuickStochasticEngine::setCount(int c)
{
    m_things.resize(c);
    m_goals.resize(c);
    m_duration.resize(c);
    m_startTimes.resize(c);
}

void QQuickStochasticEngine::start(int index, int state)
{
    if (index >= m_things.count())
        return;
    m_things[index] = state;
    m_duration[index] = m_states.at(state)->variedDuration();
    if (m_states.at(state)->randomStart())
        m_startTimes[index] = NINF;
    else
        m_startTimes[index] = 0;
    m_goals[index] = -1;
    m_addAdvance = false;
    restart(index);
    m_addAdvance = true;
}

void QQuickStochasticEngine::stop(int index)
{
    if (index >= m_things.count())
        return;
    //Will never change until start is called again with a new state (or manually advanced) - this is not a 'pause'
    for (int i=0; i<m_stateUpdates.count(); i++)
        m_stateUpdates[i].second.removeAll(index);
}

void QQuickStochasticEngine::restart(int index)
{
    bool randomStart = (m_startTimes.at(index) == NINF);
    m_startTimes[index] = m_timeOffset;
    if (m_addAdvance)
        m_startTimes[index] += m_advanceTimer.elapsed();
    if (randomStart)
        m_startTimes[index] -= QRandomGenerator::global()->bounded(m_duration.at(index));
    int time = m_duration.at(index) + m_startTimes.at(index);
    for (int i=0; i<m_stateUpdates.count(); i++)
        m_stateUpdates[i].second.removeAll(index);
    if (m_duration.at(index) >= 0)
        addToUpdateList(time, index);
}

void QQuickSpriteEngine::restart(int index) //Reimplemented to recognize and handle pseudostates
{
    bool randomStart = (m_startTimes.at(index) == NINF);
    if (m_loaded && m_sprites.at(m_things.at(index))->frameSync()) {//Manually advanced
        m_startTimes[index] = 0;
        if (randomStart && m_sprites.at(m_things.at(index))->m_generatedCount)
            m_startTimes[index] += QRandomGenerator::global()->bounded(m_sprites.at(m_things.at(index))->m_generatedCount);
    } else {
        m_startTimes[index] = m_timeOffset;
        if (m_addAdvance)
            m_startTimes[index] += m_advanceTimer.elapsed();
        if (randomStart)
            m_startTimes[index] -= QRandomGenerator::global()->bounded(m_duration.at(index));
        int time = spriteDuration(index) + m_startTimes.at(index);
        if (randomStart) {
            int curTime = m_timeOffset + (m_addAdvance ? m_advanceTimer.elapsed() : 0);
            while (time < curTime) //Fast forward through psuedostates as needed
                time += spriteDuration(index);
        }

        for (int i=0; i<m_stateUpdates.count(); i++)
            m_stateUpdates[i].second.removeAll(index);
        addToUpdateList(time, index);
    }
}

void QQuickStochasticEngine::advance(int idx)
{
    if (idx >= m_things.count())
        return;//TODO: Proper fix(because this has happened and I just ignored it)
    int nextIdx = nextState(m_things.at(idx), idx);
    m_things[idx] = nextIdx;
    m_duration[idx] = m_states.at(nextIdx)->variedDuration();
    restart(idx);
    emit m_states.at(nextIdx)->entered();
    emit stateChanged(idx);
}

void QQuickSpriteEngine::advance(int idx) //Reimplemented to recognize and handle pseudostates
{
    if (!m_loaded) {
        qWarning() << QLatin1String("QQuickSpriteEngine: Trying to advance sprites before sprites finish loading. Ignoring directive");
        return;
    }

    if (idx >= m_things.count())
        return;//TODO: Proper fix(because this has happened and I just ignored it)
    if (m_duration.at(idx) == 0) {
        if (m_sprites.at(m_things.at(idx))->frameSync()) {
            //Manually called, advance inner substate count
            m_startTimes[idx]++;
            if (m_startTimes.at(idx) < m_sprites.at(m_things.at(idx))->m_generatedCount) {
                //only a pseudostate ended
                emit stateChanged(idx);
                return;
            }
        }
        //just go past the pseudostate logic
    } else if (m_startTimes.at(idx) + m_duration.at(idx)
            > int(m_timeOffset + (m_addAdvance ? m_advanceTimer.elapsed() : 0))) {
        //only a pseduostate ended
        emit stateChanged(idx);
        addToUpdateList(spriteStart(idx) + spriteDuration(idx) + (m_addAdvance ? m_advanceTimer.elapsed() : 0), idx);
        return;
    }
    int nextIdx = nextState(m_things.at(idx), idx);
    m_things[idx] = nextIdx;
    m_duration[idx] = m_states.at(nextIdx)->variedDuration();
    restart(idx);
    emit m_states.at(nextIdx)->entered();
    emit stateChanged(idx);
}

int QQuickStochasticEngine::nextState(int curState, int curThing)
{
    int nextIdx = -1;
    int goalPath = goalSeek(curState, curThing);
    if (goalPath == -1){//Random
        qreal r = QRandomGenerator::global()->generateDouble();
        qreal total = 0.0;
        for (QVariantMap::const_iterator iter=m_states.at(curState)->m_to.constBegin();
            iter!=m_states.at(curState)->m_to.constEnd(); ++iter)
            total += (*iter).toReal();
        r*=total;
        for (QVariantMap::const_iterator iter= m_states.at(curState)->m_to.constBegin();
                iter!=m_states.at(curState)->m_to.constEnd(); ++iter){
            if (r < (*iter).toReal()){
                bool superBreak = false;
                for (int i=0; i<m_states.count(); i++){
                    if (m_states.at(i)->name() == iter.key()){
                        nextIdx = i;
                        superBreak = true;
                        break;
                    }
                }
                if (superBreak)
                    break;
            }
            r -= (*iter).toReal();
        }
    }else{//Random out of shortest paths to goal
        nextIdx = goalPath;
    }
    if (nextIdx == -1)//No 'to' states means stay here
        nextIdx = curState;
    return nextIdx;
}

uint QQuickStochasticEngine::updateSprites(uint time)//### would returning a list of changed idxs be faster than signals?
{
    //Sprite State Update;
    m_timeOffset = time;
    m_addAdvance = false;
    int i = 0;
    for (; i < m_stateUpdates.count() && time >= m_stateUpdates.at(i).first; ++i) {
        const auto copy = m_stateUpdates.at(i).second;
        for (int idx : copy)
            advance(idx);
    }

    m_stateUpdates.remove(0, i);
    m_advanceTimer.start();
    m_addAdvance = true;
    if (m_stateUpdates.isEmpty())
        return uint(-1);
    return m_stateUpdates.constFirst().first;
}

int QQuickStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
{
    QString goalName;
    if (m_goals.at(spriteIdx) != -1)
        goalName = m_states.at(m_goals.at(spriteIdx))->name();
    else
        goalName = m_globalGoal;
    if (goalName.isEmpty())
        return -1;
    //TODO: caching instead of excessively redoing iterative deepening (which was chosen arbitrarily anyways)
    // Paraphrased - implement in an *efficient* manner
    for (int i=0; i<m_states.count(); i++)
        if (m_states.at(curIdx)->name() == goalName)
            return curIdx;
    if (dist < 0)
        dist = m_states.count();
    QQuickStochasticState* curState = m_states.at(curIdx);
    for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
        iter!=curState->m_to.constEnd(); ++iter){
        if (iter.key() == goalName)
            for (int i=0; i<m_states.count(); i++)
                if (m_states.at(i)->name() == goalName)
                    return i;
    }
    QSet<int> options;
    for (int i=1; i<dist; i++){
        for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
            iter!=curState->m_to.constEnd(); ++iter){
            int option = -1;
            for (int j=0; j<m_states.count(); j++)//One place that could be a lot more efficient...
                if (m_states.at(j)->name() == iter.key())
                    if (goalSeek(j, spriteIdx, i) != -1)
                        option = j;
            if (option != -1)
                options << option;
        }
        if (!options.isEmpty()){
            if (options.count()==1)
                return *(options.begin());
            int option = -1;
            qreal r = QRandomGenerator::global()->generateDouble();
            qreal total = 0;
            for (QSet<int>::const_iterator iter=options.constBegin();
                iter!=options.constEnd(); ++iter)
                total += curState->m_to.value(m_states.at((*iter))->name()).toReal();
            r *= total;
            for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
                iter!=curState->m_to.constEnd(); ++iter){
                bool superContinue = true;
                for (int j=0; j<m_states.count(); j++)
                    if (m_states.at(j)->name() == iter.key())
                        if (options.contains(j))
                            superContinue = false;
                if (superContinue)
                    continue;
                if (r < (*iter).toReal()){
                    bool superBreak = false;
                    for (int j=0; j<m_states.count(); j++){
                        if (m_states.at(j)->name() == iter.key()){
                            option = j;
                            superBreak = true;
                            break;
                        }
                    }
                    if (superBreak)
                        break;
                }
                r-=(*iter).toReal();
            }
            return option;
        }
    }
    return -1;
}

void QQuickStochasticEngine::addToUpdateList(uint t, int idx)
{
    for (int i=0; i<m_stateUpdates.count(); i++){
        if (m_stateUpdates.at(i).first == t){
            m_stateUpdates[i].second << idx;
            return;
        } else if (m_stateUpdates.at(i).first > t) {
            QVector<int> tmpList;
            tmpList << idx;
            m_stateUpdates.insert(i, qMakePair(t, tmpList));
            return;
        }
    }
    QVector<int> tmpList;
    tmpList << idx;
    m_stateUpdates << qMakePair(t, tmpList);
}

QT_END_NAMESPACE

#include "moc_qquickspriteengine_p.cpp"
