/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part 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 "qmediaplaylistnavigator_p.h"
#include "qmediaplaylistprovider_p.h"
#include "qmediaplaylist.h"
#include "qmediaobject_p.h"

#include <QtCore/qdebug.h>
#include <QtCore/qrandom.h>

QT_BEGIN_NAMESPACE

class QMediaPlaylistNullProvider : public QMediaPlaylistProvider
{
public:
    QMediaPlaylistNullProvider() :QMediaPlaylistProvider() {}
    ~QMediaPlaylistNullProvider() {}
    int mediaCount() const override {return 0;}
    QMediaContent media(int) const override { return QMediaContent(); }
};

Q_GLOBAL_STATIC(QMediaPlaylistNullProvider, _q_nullMediaPlaylist)

class QMediaPlaylistNavigatorPrivate
{
    Q_DECLARE_NON_CONST_PUBLIC(QMediaPlaylistNavigator)
public:
    QMediaPlaylistNavigatorPrivate()
        :playlist(nullptr),
        currentPos(-1),
        lastValidPos(-1),
        playbackMode(QMediaPlaylist::Sequential),
        randomPositionsOffset(-1)
    {
    }

    QMediaPlaylistProvider *playlist;
    int currentPos;
    int lastValidPos; //to be used with CurrentItemOnce playback mode
    QMediaPlaylist::PlaybackMode playbackMode;
    QMediaContent currentItem;

    mutable QList<int> randomModePositions;
    mutable int randomPositionsOffset;

    int nextItemPos(int steps = 1) const;
    int previousItemPos(int steps = 1) const;

    void _q_mediaInserted(int start, int end);
    void _q_mediaRemoved(int start, int end);
    void _q_mediaChanged(int start, int end);

    QMediaPlaylistNavigator *q_ptr;
};


int QMediaPlaylistNavigatorPrivate::nextItemPos(int steps) const
{
    if (playlist->mediaCount() == 0)
        return -1;

    if (steps == 0)
        return currentPos;

    switch (playbackMode) {
        case QMediaPlaylist::CurrentItemOnce:
            return /*currentPos == -1 ? lastValidPos :*/ -1;
        case QMediaPlaylist::CurrentItemInLoop:
            return currentPos;
        case QMediaPlaylist::Sequential:
            {
                int nextPos = currentPos+steps;
                return nextPos < playlist->mediaCount() ? nextPos : -1;
            }
        case QMediaPlaylist::Loop:
            return (currentPos+steps) % playlist->mediaCount();
        case QMediaPlaylist::Random:
            {
                //TODO: limit the history size

                if (randomPositionsOffset == -1) {
                    randomModePositions.clear();
                    randomModePositions.append(currentPos);
                    randomPositionsOffset = 0;
                }

                while (randomModePositions.size() < randomPositionsOffset+steps+1)
                    randomModePositions.append(-1);
                int res = randomModePositions[randomPositionsOffset+steps];
                if (res<0 || res >= playlist->mediaCount()) {
                    res = QRandomGenerator::global()->bounded(playlist->mediaCount());
                    randomModePositions[randomPositionsOffset+steps] = res;
                }

                return res;
            }
    }

    return -1;
}

int QMediaPlaylistNavigatorPrivate::previousItemPos(int steps) const
{
    if (playlist->mediaCount() == 0)
        return -1;

    if (steps == 0)
        return currentPos;

    switch (playbackMode) {
        case QMediaPlaylist::CurrentItemOnce:
            return /*currentPos == -1 ? lastValidPos :*/ -1;
        case QMediaPlaylist::CurrentItemInLoop:
            return currentPos;
        case QMediaPlaylist::Sequential:
            {
                int prevPos = currentPos == -1 ? playlist->mediaCount() - steps : currentPos - steps;
                return prevPos>=0 ? prevPos : -1;
            }
        case QMediaPlaylist::Loop:
            {
                int prevPos = currentPos - steps;
                while (prevPos<0)
                    prevPos += playlist->mediaCount();
                return prevPos;
            }
        case QMediaPlaylist::Random:
            {
                //TODO: limit the history size

                if (randomPositionsOffset == -1) {
                    randomModePositions.clear();
                    randomModePositions.append(currentPos);
                    randomPositionsOffset = 0;
                }

                while (randomPositionsOffset-steps < 0) {
                    randomModePositions.prepend(-1);
                    randomPositionsOffset++;
                }

                int res = randomModePositions[randomPositionsOffset-steps];
                if (res<0 || res >= playlist->mediaCount()) {
                    res = QRandomGenerator::global()->bounded(playlist->mediaCount());
                    randomModePositions[randomPositionsOffset-steps] = res;
                }

                return res;
            }
    }

    return -1;
}

/*!
    \class QMediaPlaylistNavigator
    \internal

    \brief The QMediaPlaylistNavigator class provides navigation for a media playlist.
    \inmodule QtMultimedia
    \ingroup multimedia
    \ingroup multimedia_playback

    \sa QMediaPlaylist, QMediaPlaylistProvider
*/


/*!
    Constructs a media playlist navigator for a \a playlist.

    The \a parent is passed to QObject.
 */
QMediaPlaylistNavigator::QMediaPlaylistNavigator(QMediaPlaylistProvider *playlist, QObject *parent)
    : QObject(parent)
    , d_ptr(new QMediaPlaylistNavigatorPrivate)
{
    d_ptr->q_ptr = this;

    setPlaylist(playlist ? playlist : _q_nullMediaPlaylist());
}

/*!
    Destroys a media playlist navigator.
 */

QMediaPlaylistNavigator::~QMediaPlaylistNavigator()
{
    delete d_ptr;
}


/*! \property QMediaPlaylistNavigator::playbackMode
    Contains the playback mode.
 */
QMediaPlaylist::PlaybackMode QMediaPlaylistNavigator::playbackMode() const
{
    return d_func()->playbackMode;
}

/*!
    Sets the playback \a mode.
 */
void QMediaPlaylistNavigator::setPlaybackMode(QMediaPlaylist::PlaybackMode mode)
{
    Q_D(QMediaPlaylistNavigator);
    if (d->playbackMode == mode)
        return;

    if (mode == QMediaPlaylist::Random) {
        d->randomPositionsOffset = 0;
        d->randomModePositions.append(d->currentPos);
    } else if (d->playbackMode == QMediaPlaylist::Random) {
        d->randomPositionsOffset = -1;
        d->randomModePositions.clear();
    }

    d->playbackMode = mode;

    emit playbackModeChanged(mode);
    emit surroundingItemsChanged();
}

/*!
    Returns the playlist being navigated.
*/

QMediaPlaylistProvider *QMediaPlaylistNavigator::playlist() const
{
    return d_func()->playlist;
}

/*!
    Sets the \a playlist to navigate.
*/
void QMediaPlaylistNavigator::setPlaylist(QMediaPlaylistProvider *playlist)
{
    Q_D(QMediaPlaylistNavigator);

    if (d->playlist == playlist)
        return;

    if (d->playlist) {
        d->playlist->disconnect(this);
    }

    if (playlist) {
        d->playlist = playlist;
    } else {
        //assign to shared readonly null playlist
        d->playlist = _q_nullMediaPlaylist();
    }

    connect(d->playlist, SIGNAL(mediaInserted(int,int)), SLOT(_q_mediaInserted(int,int)));
    connect(d->playlist, SIGNAL(mediaRemoved(int,int)), SLOT(_q_mediaRemoved(int,int)));
    connect(d->playlist, SIGNAL(mediaChanged(int,int)), SLOT(_q_mediaChanged(int,int)));

    d->randomPositionsOffset = -1;
    d->randomModePositions.clear();

    if (d->currentPos != -1) {
        d->currentPos = -1;
        emit currentIndexChanged(-1);
    }

    if (!d->currentItem.isNull()) {
        d->currentItem = QMediaContent();
        emit activated(d->currentItem); //stop playback
    }
}

/*! \property QMediaPlaylistNavigator::currentItem

  Contains the media at the current position in the playlist.

  \sa currentIndex()
*/

QMediaContent QMediaPlaylistNavigator::currentItem() const
{
    return itemAt(d_func()->currentPos);
}

/*! \fn QMediaContent QMediaPlaylistNavigator::nextItem(int steps) const

  Returns the media that is \a steps positions ahead of the current
  position in the playlist.

  \sa nextIndex()
*/
QMediaContent QMediaPlaylistNavigator::nextItem(int steps) const
{
    return itemAt(nextIndex(steps));
}

/*!
  Returns the media that is \a steps positions behind the current
  position in the playlist.

  \sa previousIndex()
 */
QMediaContent QMediaPlaylistNavigator::previousItem(int steps) const
{
    return itemAt(previousIndex(steps));
}

/*!
    Returns the media at a \a position in the playlist.
 */
QMediaContent QMediaPlaylistNavigator::itemAt(int position) const
{
    return d_func()->playlist->media(position);
}

/*! \property QMediaPlaylistNavigator::currentIndex

  Contains the position of the current media.

  If no media is current, the property contains -1.

  \sa nextIndex(), previousIndex()
*/

int QMediaPlaylistNavigator::currentIndex() const
{
    return d_func()->currentPos;
}

/*!
  Returns a position \a steps ahead of the current position
  accounting for the playbackMode().

  If the position is beyond the end of the playlist, this value
  returned is -1.

  \sa currentIndex(), previousIndex(), playbackMode()
*/

int QMediaPlaylistNavigator::nextIndex(int steps) const
{
    return d_func()->nextItemPos(steps);
}

/*!

  Returns a position \a steps behind the current position accounting
  for the playbackMode().

  If the position is prior to the beginning of the playlist this will
  return -1.

  \sa currentIndex(), nextIndex(), playbackMode()
*/
int QMediaPlaylistNavigator::previousIndex(int steps) const
{
    return d_func()->previousItemPos(steps);
}

/*!
  Advances to the next item in the playlist.

  \sa previous(), jump(), playbackMode()
 */
void QMediaPlaylistNavigator::next()
{
    Q_D(QMediaPlaylistNavigator);

    int nextPos = d->nextItemPos();

    if ( playbackMode() == QMediaPlaylist::Random )
            d->randomPositionsOffset++;

    jump(nextPos);
}

/*!
  Returns to the previous item in the playlist,

  \sa next(), jump(), playbackMode()
 */
void QMediaPlaylistNavigator::previous()
{
    Q_D(QMediaPlaylistNavigator);

    int prevPos = d->previousItemPos();
    if ( playbackMode() == QMediaPlaylist::Random )
        d->randomPositionsOffset--;

    jump(prevPos);
}

/*!
  Jumps to a new \a position in the playlist.
 */
void QMediaPlaylistNavigator::jump(int position)
{
    Q_D(QMediaPlaylistNavigator);

    if (position < -1 || position >= d->playlist->mediaCount())
        position = -1;

    if (position != -1)
        d->lastValidPos = position;

    if (playbackMode() == QMediaPlaylist::Random) {
        if (d->randomModePositions[d->randomPositionsOffset] != position) {
            d->randomModePositions.clear();
            d->randomModePositions.append(position);
            d->randomPositionsOffset = 0;
        }
    }

    if (position != -1)
        d->currentItem = d->playlist->media(position);
    else
        d->currentItem = QMediaContent();

    if (position != d->currentPos) {
        d->currentPos = position;
        emit currentIndexChanged(d->currentPos);
        emit surroundingItemsChanged();
    }

    emit activated(d->currentItem);
}

/*!
    \internal
*/
void QMediaPlaylistNavigatorPrivate::_q_mediaInserted(int start, int end)
{
    Q_Q(QMediaPlaylistNavigator);

    if (currentPos >= start) {
        currentPos = end-start+1;
        q->jump(currentPos);
    }

    //TODO: check if they really changed
    emit q->surroundingItemsChanged();
}

/*!
    \internal
*/
void QMediaPlaylistNavigatorPrivate::_q_mediaRemoved(int start, int end)
{
    Q_Q(QMediaPlaylistNavigator);

    if (currentPos > end) {
        currentPos = currentPos - end-start+1;
        q->jump(currentPos);
    } else if (currentPos >= start) {
        //current item was removed
        currentPos = qMin(start, playlist->mediaCount()-1);
        q->jump(currentPos);
    }

    //TODO: check if they really changed
    emit q->surroundingItemsChanged();
}

/*!
    \internal
*/
void QMediaPlaylistNavigatorPrivate::_q_mediaChanged(int start, int end)
{
    Q_Q(QMediaPlaylistNavigator);

    if (currentPos >= start && currentPos<=end) {
        QMediaContent src = playlist->media(currentPos);
        if (src != currentItem) {
            currentItem = src;
            emit q->activated(src);
        }
    }

    //TODO: check if they really changed
    emit q->surroundingItemsChanged();
}

/*!
    \fn QMediaPlaylistNavigator::activated(const QMediaContent &media)

    Signals that the current \a media has changed.
*/

/*!
    \fn QMediaPlaylistNavigator::currentIndexChanged(int position)

    Signals the \a position of the current media has changed.
*/

/*!
    \fn QMediaPlaylistNavigator::playbackModeChanged(QMediaPlaylist::PlaybackMode mode)

    Signals that the playback \a mode has changed.
*/

/*!
    \fn QMediaPlaylistNavigator::surroundingItemsChanged()

    Signals that media immediately surrounding the current position has changed.
*/

QT_END_NAMESPACE

#include "moc_qmediaplaylistnavigator_p.cpp"
