/*  This file is part of the KDE project
    Copyright (C) 2007 Matthias Kretz <kretz@kde.org>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) version 3.

    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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

*/

#include "mediaobject.h"

namespace Phonon
{
namespace Proxy
{

MediaObject::MediaObject(QObject *parent)
    : QObject(parent)
{
    createProxiedObject(BackendInterface::MediaObjectClass);
}

MediaObject::~MediaObject()
{
    send(Destructor);
    receive(Destructor);
}

void MediaObject::handleSignal(SignalId sig, QDataStream &stream) const
{
    switch (sig) {
    case MediaObjectAboutToFinish:             //
        emit aboutToFinish();
        break;
    case MediaObjectFinished:                  //
        emit finished();
        break;
    case MediaObjectPrefinishMarkReached:      // qint32 msec
        {
            qint32 msec;
            stream >> msec;
            emit prefinishMarkReached(msec);
        }
        break;
    case MediaObjectTotalTimeChanged:          // qint64 length
        {
            qint64 length;
            stream >> length;
            emit totalTimeChanged(length);
        }
        break;
    case MediaObjectStateChanged:              // Phonon::State newstate, Phonon::State oldstate
        {
            quint32 newstate, oldstate;
            stream >> newstate >> oldstate;
            emit stateChanged(static_cast<State>(newstate), static_cast<State>(oldstate));
        }
        break;
    case MediaObjectTick:                      // qint64 time
        {
            qint64 time;
            stream >> time;
            emit tick(time);
        }
        break;
    case MediaObjectMetaDataChanged:           // const QMultiMap<QString, QString> &
        {
            QMultiMap<QString, QString> m;
            stream >> m;
            emit metaDataChanged(m);
        }
        break;
    case MediaObjectSeekableChanged:           // bool
        {
            bool b;
            stream >> b;
            emit seekableChanged(b);
        }
        break;
    case MediaObjectHasVideoChanged:           // bool
        {
            bool b;
            stream >> b;
            emit hasVideoChanged(b);
        }
        break;
    case MediaObjectBufferStatus:              // int
        {
            int i;
            stream >> i;
            emit bufferStatus(i);
        }
        break;
    case MediaObjectAvailableTitlesChanged:    // int
        {
            int i;
            stream >> i;
            emit availableTitlesChanged(i);
        }
        break;
    case MediaObjectTitleChanged:              // int
        {
            int i;
            stream >> i;
            emit titleChanged(i);
        }
        break;
    case MediaObjectAvailableChaptersChanged:  // int
        {
            int i;
            stream >> i;
            emit availableChaptersChanged(i);
        }
        break;
    case MediaObjectChapterChanged:            // int
        {
            int i;
            stream >> i;
            emit chapterChanged(i);
        }
        break;
    case MediaObjectAvailableAnglesChanged:    // int
        {
            int i;
            stream >> i;
            emit availableAnglesChanged(i);
        }
        break;
    case MediaObjectAngleChanged:              // int
        {
            int i;
            stream >> i;
            emit angleChanged(i);
        }
        break;
    default:
        ProxyObject::handleSignal(sig, stream);
        break;
    }
}

#define FUNCTION_0(rettype, func, funcId) \
rettype MediaObject::func \
{ \
    send(funcId); \
    rettype r; \
    receive(funcId) >> r; \
    return r; \
}

#define FUNCTION_1(rettype, funcName, type1, funcId) \
rettype MediaObject::funcName(type1 a) const \
{ \
    send(funcId) << a; \
    rettype r; \
    receive(funcId) >> r; \
    return r; \
}

#define PROCEDURE_0(funcName, funcId) \
void MediaObject::funcName() \
{ \
    send(funcId); \
    receive(funcId); \
}

#define PROCEDURE_1(type1, funcName, funcId) \
void MediaObject::funcName(type1 a) \
{ \
    send(funcId) << a; \
    receive(funcId); \
}

State MediaObject::state() const
{
    send(MediaObjectState);
    quint32 r;
    receive(MediaObjectState) >> r;
    return static_cast<State>(r);
}

FUNCTION_0(bool, hasVideo() const, MediaObjectHasVideo)
FUNCTION_0(bool, isSeekable() const, MediaObjectIsSeekable)
FUNCTION_0(qint64, currentTime() const, MediaObjectCurrentTime)
FUNCTION_0(qint64, totalTime() const, MediaObjectTotalTime)
FUNCTION_0(qint64, remainingTime() const, MediaObjectRemainingTime)
FUNCTION_0(qint32, tickInterval() const, MediaObjectTickInterval)
PROCEDURE_1(qint32, setTickInterval, MediaObjectSetTickInterval)
PROCEDURE_0(play, MediaObjectPlay)
PROCEDURE_0(pause, MediaObjectPause)
PROCEDURE_0(stop, MediaObjectStop)
PROCEDURE_1(qint64, seek, MediaObjectSeek)
FUNCTION_0(QString, errorString() const, MediaObjectErrorString)

ErrorType MediaObject::errorType() const
{
    send(MediaObjectErrorType);
    quint32 r;
    receive(MediaObjectErrorType) >> r;
    return static_cast<ErrorType>(r);
}

FUNCTION_1(bool, hasInterface, Interface, MediaObjectHasInterface)
FUNCTION_0(qint32, prefinishMark() const, MediaObjectPrefinishMark)
PROCEDURE_1(qint32, setPrefinishMark, MediaObjectSetPrefinishMark)
FUNCTION_0(qint32, transitionTime() const, MediaObjectTransitionTime)
PROCEDURE_1(qint32, setTransitionTime, MediaObjectSetTransitionTime)
FUNCTION_0(MediaSource, source() const, MediaObjectSource)
PROCEDURE_1(const MediaSource &, setSource, MediaObjectSetSource)
PROCEDURE_1(const MediaSource &, setNextSource, MediaObjectSetNextSource)

QVariant MediaObject::interfaceCall(Interface interface, int command, const QList<QVariant> &arguments)
{
    send(MediaObjectInterfaceCall) << interface << command << arguments;
    QVariant r;
    receive(MediaObjectInterfaceCall) >> r;
    return r;
}

}}
