/*  This file is part of the KDE project.

Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 or 3 of the License.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <QResource>
#include <QUrl>

#include "abstractmediaplayer.h"
#include "defs.h"
#include "mediaobject.h"
#include "utils.h"
#include <cdbcols.h>
#include <cdblen.h>
#include <commdb.h>

QT_BEGIN_NAMESPACE

using namespace Phonon;
using namespace Phonon::MMF;

/*! \class MMF::AbstractMediaPlayer
  \internal
*/

//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------

const int       NullMaxVolume = -1;
const int       BufferStatusTimerInterval = 100; // ms


//-----------------------------------------------------------------------------
// Constructor / destructor
//-----------------------------------------------------------------------------

MMF::AbstractMediaPlayer::AbstractMediaPlayer
    (MediaObject *parent, const AbstractPlayer *player)
        :   AbstractPlayer(player)
        ,   m_parent(parent)
        ,   m_pending(NothingPending)
        ,   m_positionTimer(new QTimer(this))
        ,   m_position(0)
        ,   m_bufferStatusTimer(new QTimer(this))
        ,   m_mmfMaxVolume(NullMaxVolume)
        ,   m_prefinishMarkSent(false)
        ,   m_aboutToFinishSent(false)
#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
        ,   m_download(0)
        ,   m_downloadStalled(false)
#endif
{
    connect(m_positionTimer.data(), SIGNAL(timeout()), this, SLOT(positionTick()));
    connect(m_bufferStatusTimer.data(), SIGNAL(timeout()), this, SLOT(bufferStatusTick()));
}

//-----------------------------------------------------------------------------
// MediaObjectInterface
//-----------------------------------------------------------------------------

void MMF::AbstractMediaPlayer::play()
{
    TRACE_CONTEXT(AbstractMediaPlayer::play, EAudioApi);
    TRACE_ENTRY("state %d", privateState());

    switch (privateState()) {
    case GroundState:
        setError(tr("Not ready to play"));
        break;

    case LoadingState:
        setPending(PlayPending);
        break;

    case StoppedState:
    case PausedState:
        startPlayback();
        break;

    case PlayingState:
    case BufferingState:
    case ErrorState:
        // Do nothing
        break;

        // Protection against adding new states and forgetting to update this switch
    default:
        TRACE_PANIC(InvalidStatePanic);
    }

    TRACE_EXIT("state %d", privateState());
}

void MMF::AbstractMediaPlayer::pause()
{
    TRACE_CONTEXT(AbstractMediaPlayer::pause, EAudioApi);
    TRACE_ENTRY("state %d", privateState());

    stopTimers();

    switch (privateState()) {
    case GroundState:
    case LoadingState:
    case StoppedState:
        setPending(PausePending);
        break;

    case PausedState:
        // Do nothing
        break;

    case PlayingState:
    case BufferingState:
        changeState(PausedState);
        // Fall through
    case ErrorState:
        doPause();
        break;

        // Protection against adding new states and forgetting to update this switch
    default:
        TRACE_PANIC(InvalidStatePanic);
    }

    TRACE_EXIT("state %d", privateState());
}

void MMF::AbstractMediaPlayer::stop()
{
    TRACE_CONTEXT(AbstractMediaPlayer::stop, EAudioApi);
    TRACE_ENTRY("state %d", privateState());

    setPending(NothingPending);
    stopTimers();

    switch (privateState()) {
    case GroundState:
    case LoadingState:
    case StoppedState:
    case ErrorState:
        // Do nothing
        break;

    case PlayingState:
    case BufferingState:
    case PausedState:
        doStop();
        changeState(StoppedState);
        break;

        // Protection against adding new states and forgetting to update this switch
    default:
        TRACE_PANIC(InvalidStatePanic);
    }

    TRACE_EXIT("state %d", privateState());
}

void MMF::AbstractMediaPlayer::seek(qint64 ms)
{
    TRACE_CONTEXT(AbstractMediaPlayer::seek, EAudioApi);
    TRACE_ENTRY("state %d pos %Ld", state(), ms);

    switch (privateState()) {
    // Fallthrough all these
    case GroundState:
    case StoppedState:
    case PausedState:
    case PlayingState:
    case LoadingState:
    {
        bool wasPlaying = false;
        if (state() == PlayingState) {
            stopPositionTimer();
            doPause();
            wasPlaying = true;
        }

        doSeek(ms);
        m_position = ms;
        resetMarksIfRewound();

        if(wasPlaying && state() != ErrorState) {
            doPlay();
            startPositionTimer();
        }

        break;
    }
    case BufferingState:
    // Fallthrough
    case ErrorState:
        // Do nothing
        break;
    }

    TRACE_EXIT_0();
}

bool MMF::AbstractMediaPlayer::isSeekable() const
{
    return true;
}

qint64 MMF::AbstractMediaPlayer::currentTime() const
{
    return m_position;
}

void MMF::AbstractMediaPlayer::doSetTickInterval(qint32 interval)
{
    TRACE_CONTEXT(AbstractMediaPlayer::doSetTickInterval, EAudioApi);
    TRACE_ENTRY("state %d m_interval %d interval %d", privateState(), tickInterval(), interval);

    m_positionTimer->setInterval(interval);

    TRACE_EXIT_0();
}

void MMF::AbstractMediaPlayer::open()
{
    TRACE_CONTEXT(AbstractMediaPlayer::open, EAudioApi);
    const MediaSource source = m_parent->source();
    TRACE_ENTRY("state %d source.type %d", privateState(), source.type());

    close();
    changeState(GroundState);

    TInt symbianErr = KErrNone;
    QString errorMessage;

    switch (source.type()) {
    case MediaSource::LocalFile: {
        RFile *const file = m_parent->file();
        Q_ASSERT(file);
        symbianErr = openFile(*file);
        if (KErrNone != symbianErr)
            errorMessage = tr("Error opening file");
        break;
    }

    case MediaSource::Url: {
        const QUrl url(source.url());
        if (url.scheme() == QLatin1String("file")) {
            RFile *const file = m_parent->file();
            Q_ASSERT(file);
            symbianErr = openFile(*file);
            if (KErrNone != symbianErr)
                errorMessage = tr("Error opening file");
        }
#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
        else if (url.scheme() == QLatin1String("http")) {
            Q_ASSERT(!m_download);
            m_download = new Download(url, this);
            connect(m_download, SIGNAL(lengthChanged(qint64)),
                    this, SLOT(downloadLengthChanged(qint64)));
            connect(m_download, SIGNAL(stateChanged(Download::State)),
                    this, SLOT(downloadStateChanged(Download::State)));
            int iap = m_parent->currentIAP();
            TRACE("HTTP Url: Using IAP %d", iap);
            m_download->start(iap);
        }
#endif
        else {
            int iap = m_parent->currentIAP();
            TRACE("Using IAP %d", iap);
            symbianErr = openUrl(url.toString(), iap);
            if (KErrNone != symbianErr)
                errorMessage = tr("Error opening URL");
        }

        break;
    }

    case MediaSource::Stream: {
        QResource *const resource = m_parent->resource();
        if (resource) {
            m_buffer.Set(resource->data(), resource->size());
            symbianErr = openDescriptor(m_buffer);
            if (KErrNone != symbianErr)
                errorMessage = tr("Error opening resource");
        } else {
            errorMessage = tr("Error opening source: resource not opened");
        }
        break;
    }

    // Other source types are handled in MediaObject::createPlayer

    // Protection against adding new media types and forgetting to update this switch
    default:
        TRACE_PANIC(InvalidMediaTypePanic);
    }

    if (errorMessage.isEmpty()) {
        changeState(LoadingState);
    } else {
        if (symbianErr)
            setError(errorMessage, symbianErr);
        else
            setError(errorMessage);
    }

    TRACE_EXIT_0();
}

void MMF::AbstractMediaPlayer::close()
{
    doClose();
#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
    delete m_download;
    m_download = 0;
#endif
    m_position = 0;
}

void MMF::AbstractMediaPlayer::volumeChanged(qreal volume)
{
    TRACE_CONTEXT(AbstractMediaPlayer::volumeChanged, EAudioInternal);
    TRACE_ENTRY("state %d", privateState());

    AbstractPlayer::volumeChanged(volume);
    doVolumeChanged();

    TRACE_EXIT_0();
}

//-----------------------------------------------------------------------------
// Private functions
//-----------------------------------------------------------------------------

void MMF::AbstractMediaPlayer::startPositionTimer()
{
    m_positionTimer->start(tickInterval());
}

void MMF::AbstractMediaPlayer::stopPositionTimer()
{
    m_positionTimer->stop();
}

void MMF::AbstractMediaPlayer::startBufferStatusTimer()
{
    m_bufferStatusTimer->start(BufferStatusTimerInterval);
}

void MMF::AbstractMediaPlayer::stopBufferStatusTimer()
{
    m_bufferStatusTimer->stop();
}

void MMF::AbstractMediaPlayer::stopTimers()
{
    stopPositionTimer();
    stopBufferStatusTimer();
}

void MMF::AbstractMediaPlayer::doVolumeChanged()
{
    switch (privateState()) {
    case GroundState:
    case LoadingState:
    case ErrorState:
        // Do nothing
        break;

    case StoppedState:
    case PausedState:
    case PlayingState:
    case BufferingState: {
        const qreal volume = (m_volume * m_mmfMaxVolume) + 0.5;
        const int err = setDeviceVolume(volume);

        if (KErrNone != err) {
            setError(tr("Setting volume failed"), err);
        }
        break;
    }

    // Protection against adding new states and forgetting to update this
    // switch
    default:
        Utils::panic(InvalidStatePanic);
    }
}

//-----------------------------------------------------------------------------
// Protected functions
//-----------------------------------------------------------------------------

void MMF::AbstractMediaPlayer::bufferingStarted()
{
    m_stateBeforeBuffering = privateState();
    changeState(BufferingState);
    bufferStatusTick();
    startBufferStatusTimer();
}

void MMF::AbstractMediaPlayer::bufferingComplete()
{
    stopBufferStatusTimer();
    emit MMF::AbstractPlayer::bufferStatus(100);
    if (!progressiveDownloadStalled())
        changeState(m_stateBeforeBuffering);
}

void MMF::AbstractMediaPlayer::maxVolumeChanged(int mmfMaxVolume)
{
    m_mmfMaxVolume = mmfMaxVolume;
    doVolumeChanged();
}

void MMF::AbstractMediaPlayer::loadingComplete(int error)
{
    TRACE_CONTEXT(AbstractMediaPlayer::loadingComplete, EAudioApi);
    TRACE_ENTRY("state %d error %d", state(), error);
    if (progressiveDownloadStalled()) {
        Q_ASSERT(Phonon::BufferingState == state());
        if (KErrNone == error) {
            bufferingComplete();
            doSeek(m_position);
            startPlayback();
#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
            m_downloadStalled = false;
#endif
        }
    } else {
        Q_ASSERT(Phonon::LoadingState == state());
        if (KErrNone == error) {
            updateMetaData();
            changeState(StoppedState);
        } else {
            if (isProgressiveDownload() && KErrCorrupt == error) {
                setProgressiveDownloadStalled();
            } else {
                setError(tr("Loading clip failed"), error);
            }
        }
    }
}

void MMF::AbstractMediaPlayer::playbackComplete(int error)
{
    stopTimers();

    if (KErrNone == error && !m_aboutToFinishSent) {
        const qint64 total = totalTime();
        emit MMF::AbstractPlayer::tick(total);
        m_aboutToFinishSent = true;
        emit aboutToFinish();
    }

    if (KErrNone == error) {
        changeState(PausedState);

        // MediaObject::switchToNextSource deletes the current player, so we
        // call it via delayed slot invokation to ensure that this object does
        // not get deleted during execution of a member function.
        QMetaObject::invokeMethod(m_parent, "switchToNextSource", Qt::QueuedConnection);
    }
    else {
        if (isProgressiveDownload() && KErrCorrupt == error) {
            setProgressiveDownloadStalled();
        } else {
            setError(tr("Playback complete"), error);
            emit finished();
        }
    }
}

qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds &in)
{
    return in.Int64() / 1000;
}

bool MMF::AbstractMediaPlayer::isProgressiveDownload() const
{
#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
    return (0 != m_download);
#else
    return false;
#endif
}

bool MMF::AbstractMediaPlayer::progressiveDownloadStalled() const
{
#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
    return m_downloadStalled;
#else
    return false;
#endif
}

//-----------------------------------------------------------------------------
// Slots
//-----------------------------------------------------------------------------

void MMF::AbstractMediaPlayer::positionTick()
{
    const qint64 pos = getCurrentTime();
    if (pos > m_position) {
        m_position = pos;
        emitMarksIfReached(m_position);
        emit MMF::AbstractPlayer::tick(m_position);
    }
}

void MMF::AbstractMediaPlayer::emitMarksIfReached(qint64 current)
{
    const qint64 total = totalTime();
    const qint64 remaining = total - current;

    if (prefinishMark() && !m_prefinishMarkSent) {
        if (remaining < (prefinishMark() + tickInterval()/2)) {
            m_prefinishMarkSent = true;
            emit prefinishMarkReached(remaining);
        }
    }

    if (!m_aboutToFinishSent) {
        if (remaining < tickInterval()) {
            m_aboutToFinishSent = true;
            emit aboutToFinish();
        }
    }
}

void MMF::AbstractMediaPlayer::resetMarksIfRewound()
{
    const qint64 current = getCurrentTime();
    const qint64 total = totalTime();
    const qint64 remaining = total - current;

    if (prefinishMark() && m_prefinishMarkSent)
        if (remaining >= (prefinishMark() + tickInterval()/2))
            m_prefinishMarkSent = false;

    if (m_aboutToFinishSent)
        if (remaining >= tickInterval())
            m_aboutToFinishSent = false;
}

void MMF::AbstractMediaPlayer::setPending(Pending pending)
{
    const Phonon::State oldState = state();
    m_pending = pending;
    const Phonon::State newState = state();
    if (newState != oldState)
        emit stateChanged(newState, oldState);
}

void MMF::AbstractMediaPlayer::startPlayback()
{
    doPlay();
    startPositionTimer();
    changeState(PlayingState);
}

void MMF::AbstractMediaPlayer::setProgressiveDownloadStalled()
{
#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
    TRACE_CONTEXT(AbstractMediaPlayer::setProgressiveDownloadStalled, EAudioApi);
    TRACE_ENTRY("state %d", state());
    Q_ASSERT(isProgressiveDownload());
    m_downloadStalled = true;
    doClose();
    bufferingStarted();
    // Video player loses window handle when closed - need to reapply it here
    videoOutputChanged();
    m_download->resume();
#endif
}

void MMF::AbstractMediaPlayer::bufferStatusTick()
{
    // During progressive download, there is no way to detect the buffering status.
    // Phonon does not support a "buffering; amount unknown" signal, therefore we
    // return a buffering status of zero.
    const int status = progressiveDownloadStalled() ? 0 : bufferStatus();
    emit MMF::AbstractPlayer::bufferStatus(status);
}

#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
void MMF::AbstractMediaPlayer::downloadLengthChanged(qint64 length)
{
    TRACE_CONTEXT(AbstractMediaPlayer::downloadLengthChanged, EAudioApi);
    TRACE_ENTRY("length %Ld", length);
    Q_UNUSED(length)
    if (m_downloadStalled) {
        bufferingComplete();
        int err = m_parent->openFileHandle(m_download->targetFileName());
        if (KErrNone == err)
            err = openFile(*m_parent->file());
        if (KErrNone != err)
            setError(tr("Error opening file"));
    }
}

void MMF::AbstractMediaPlayer::downloadStateChanged(Download::State state)
{
    TRACE_CONTEXT(AbstractMediaPlayer::downloadStateChanged, EAudioApi);
    TRACE_ENTRY("state %d", state);
    switch (state) {
    case Download::Idle:
    case Download::Initializing:
        break;
    case Download::Downloading:
        {
        int err = m_parent->openFileHandle(m_download->targetFileName());
        if (KErrNone == err)
            err = openFile(*m_parent->file());
        else if (KErrCorrupt == err)
            // Insufficient data downloaded - enter Buffering state
            setProgressiveDownloadStalled();
        if (KErrNone != err)
            setError(tr("Error opening file"));
        }
        break;
    case Download::Complete:
        break;
    case Download::Error:
        setError(tr("Download error"));
        break;
    }
}
#endif // PHONON_MMF_PROGRESSIVE_DOWNLOAD

Phonon::State MMF::AbstractMediaPlayer::phononState(PrivateState state) const
{
    Phonon::State result = AbstractPlayer::phononState(state);

    if (PausePending == m_pending) {
        Q_ASSERT(Phonon::StoppedState == result || Phonon::LoadingState == result);
        result = Phonon::PausedState;
    }

    return result;
}

void MMF::AbstractMediaPlayer::changeState(PrivateState newState)
{
    TRACE_CONTEXT(AbstractMediaPlayer::changeState, EAudioInternal);

    const Phonon::State oldPhononState = phononState(privateState());
    const Phonon::State newPhononState = phononState(newState);

    if (LoadingState == oldPhononState && StoppedState == newPhononState) {
        switch (m_pending) {
        case NothingPending:
            AbstractPlayer::changeState(newState);
            break;

        case PlayPending:
            changeState(PlayingState); // necessary in order to apply initial volume
            doVolumeChanged();
            startPlayback();
            break;

        case PausePending:
            AbstractPlayer::changeState(PausedState);
            break;
        }

        setPending(NothingPending);
    } else {
        AbstractPlayer::changeState(newState);
    }
}

void MMF::AbstractMediaPlayer::updateMetaData()
{
    TRACE_CONTEXT(AbstractMediaPlayer::updateMetaData, EAudioInternal);
    TRACE_ENTRY_0();

    m_metaData.clear();

    const int numberOfEntries = numberOfMetaDataEntries();
    for(int i=0; i<numberOfEntries; ++i) {
        const QPair<QString, QString> entry = metaDataEntry(i);

        // Note that we capitalize the key, as required by the Ogg Vorbis
        // metadata standard to which Phonon adheres:
        // http://xiph.org/vorbis/doc/v-comment.html
        m_metaData.insert(entry.first.toUpper(), entry.second);
    }

    emit metaDataChanged(m_metaData);

    TRACE_EXIT_0();
}

QT_END_NAMESPACE

