/*  This file is part of the KDE project
    Copyright (C) 2004-2006 Matthias Kretz <kretz@kde.org>
    Copyright (C) 2006-2007 Tim Beaulen <tbscope@gmail.com>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

    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.
*/

#ifndef PHONON_GSTREAMER_BACKEND_H
#define PHONON_GSTREAMER_BACKEND_H

#include <QList>
#include <QPointer>
#include <QStringList>
#include <QObject>
#include <QMetaType>

#include <phonon/objectdescription.h>
#include <phonon/backendinterface.h>

#include <kdemacros.h>

#include "qbtgstreamer/qbtgstreamer.h"
#include "qbtgstreamer/qbtgstreamerelement.h"
#include "qbtgstreamer/qbtgstreamerpipeline.h"
#include "qbtgstreamer/qbtgstreamercapabilities.h"
#include "qbtgstreamer/coreplugins/qbtgstreamertypefindelement.h"

#include "phonongstreamerbackenddebuggerdbusiface_p.h"
#include "backendprivate.h"

//#include "playbin.h"

/* Detailed description:

   1. Every new backend creates a new GStreamer pipeline
   2. Every backend consists out of mediaobjects, filters and audio outputs.
   3. Each of these contain a GStreamer bin.
   4. Each GStreamer bin can contain pads, etc...
   5. A connection between a phonon "bin" is the same as connecting the sink and src of the respective gstreamer bins.
   6. For complex paths, a tee might might need to be inserted.
   7. For multiple threads, for example when an effect runs in its own thread, connect an audiooutput directly in that thread or not?


   Example "pipeline" (abstract, for an mp3 file)

   Legend:    === Phonon
              --- GStreamer
               #  Source
               @  Sink
              ¢X¢X¢X link



    +=====================================+      +========================+
    | Mediaobject_1                       |      | AudioOutput_1          |
    |  +------------------------------+   |      |  +------------------+  |
    |  | MediaobjectBin_1             |   |      |  | AudioOutputBin_1 |  |
    |  | +------------+   +-------+   |   |      |  |  +------------+  |  |
    |  | | FileSrc_1  |   | Mad_1 |   |   |      |  |  | AlsaSink_1 |  |  |
    |  | |            #¢X¢X¢X@       #¢X¢X¢X¢X¢X¢X¢X¢X¢X¢X¢X¢X¢X¢X¢X¢X¢X¢X¢X¢X@            |  |  |
    |  | |            |   |       |   |   |      |  |  |            |  |  |
    |  | +------------+   +-------+   |   |      |  |  +------------+  |  |
    |  |                              |   |      |  |                  |  |
    |  +------------------------------+   |      |  +------------------+  |
    |                                     |      |                        |
    +=====================================+      +========================+
 
*/

namespace Phonon
{
namespace GStreamer
{
    class AudioOutput;
    //class GstBackendPrivate;

    class Backend : public QObject, public BackendInterface
    {
        Q_OBJECT
        Q_INTERFACES(Phonon::BackendInterface)

        public:
            Backend(QObject *parent, const QVariantList &args);
            virtual ~Backend();

            QObject *createObject(BackendInterface::Class, QObject *parent, const QList<QVariant> &args);

            Q_INVOKABLE bool supportsVideo() const;
            Q_INVOKABLE bool supportsOSD() const;
            Q_INVOKABLE bool supportsFourcc(quint32 fourcc) const;
            Q_INVOKABLE bool supportsSubtitles() const;
            //Q_INVOKABLE QStringList knownMimeTypes() const;

            Q_INVOKABLE void freeSoundcardDevices();

            QSet<int> objectDescriptionIndexes(ObjectDescriptionType) const;
            QHash<QByteArray, QVariant> objectDescriptionProperties(ObjectDescriptionType, int) const;

            bool startConnectionChange(QSet<QObject *>);
            bool connectNodes(QObject *, QObject *);
            bool disconnectNodes(QObject *, QObject *);
            bool endConnectionChange(QSet<QObject *>);

            QbtGStreamerPipeline *gstreamerPipeline();

            // Debug functions
            void debugmessage(int type, int lever, const QString &objname, const QString &message);

        public slots:
            QStringList availableMimeTypes() const;

        private:
            GstBackendPrivate *d;
            PhononGStreamerBackendDebuggerDBusIface *m_phononGStreamerBackendDebuggerDBusIface;                                    

            mutable QStringList m_supportedMimeTypes;
            QStringList m_supportedAudioOutputDevices;
            QList<QPointer<AudioOutput> > m_audioOutputs;
            QbtGStreamerElement *m_sourceElement;
            QbtGStreamerElement *m_audioSink;
            QbtGStreamerTypeFindElement *m_typefindElement;
            QbtGStreamerElement *m_play;
            //void tryToPlug(QbtGStreamerPad *, QbtGStreamerCapabilities *);
    };
}} // namespace Phonon::GStreamer

// vim: sw=4 ts=4 et tw=80
#endif // PHONON_GSTREAMER_BACKEND_H
