/*  This file is part of the KDE project
    Copyright (C) 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_PLAYBIN_H
#define PHONON_GSTREAMER_PLAYBIN_H

#include <QHash>
#include <QList>
#include <QObject>
#include <QPointer>
#include <QSet>
#include <QString>
#include <QStringList>

#include <phonon/objectdescription.h>

#include <ksharedconfig.h>
#include <kdemacros.h>

#include "qbtgstreamer/qbtgstreamer.h"
#include "qbtgstreamer/qbtgstreamerelement.h"
#include "qbtgstreamer/qbtgstreamerpipeline.h"
#include "qbtgstreamer/qbtgstreamercapabilities.h"
#include "qbtgstreamer/qbtgstreamerpluginfeature.h"
#include "qbtgstreamer/qbtgstreamerregistry.h"
#include "qbtgstreamer/qbtgstreamerdatapointer.h"
#include "qbtgstreamer/qbtgstreamerelementfactory.h"
#include "qbtgstreamer/qbtgstreamerbus.h"
#include "qbtgstreamer/qbtgstreamermessage.h"
#include "qbtgstreamer/qbtgstreamerstructure.h"
#include "qbtgstreamer/qbtgstreamererror.h"
#include "qbtgstreamer/coreplugins/qbtgstreamertypefindelement.h"

#include "playbasebin.h"

class KUrl;

namespace Phonon
{
    class AudioDevice;

namespace GStreamer
{
    class mimeTypeRegistry : public QbtGStreamerRegistry
    {
        public:
            mimeTypeRegistry();
            ~mimeTypeRegistry();

            virtual bool featureFilter(QbtGStreamerPluginFeature *feature, QbtGStreamerDataPointer *data);
    };

    class findFeature : public QbtGStreamerRegistry
    {
        public:
            findFeature(const QString &feature);
            ~findFeature();

            virtual bool featureFilter(QbtGStreamerPluginFeature *feature, QbtGStreamerDataPointer *data);

        private:
            QString m_feature;
    };

    class PlayBin : public PlayBaseBin
    {
        Q_OBJECT

        public:
            PlayBin();
            ~PlayBin();

            void setUrl(const KUrl &url);

            void play();
            void pause();
            void stop();

            void setVolume(float volume);
            float volume();

            qint64 duration();

            void seek(qint64 pos);

            QStringList supportedMimeTypes();
            //QStringList supportedAudioOutputDevices();
            QStringList supportedFileExtensions();

            void setConfig(const KSharedConfigPtr &cfg); 
            QSet<int> audioOutputIndexes();

            QString audioOutputName(int audioDevice);
            QString audioOutputDescription(int audioDevice);
            QString audioOutputIcon(int audioDevice);
            bool audioOutputAvailable(int audioDevice);

        /*private slots:
            void slotMessage(QbtGStreamerMessage* msg, QbtGStreamerDataPointer* data);*/

        private:
            //void init();
        
            void checkAudioOutputs();

            struct AudioOutputInfo
            {
                AudioOutputInfo(int idx, const QString &n, const QString &desc, const QString &ic, const QString &dr, const QStringList &dev)
                    : available(false), index(idx), name(n), description(desc), icon(ic), driver(dr), devices(dev)
                {}
                bool available;
                int index;
                QString name;
                QString description;
                QString icon;
                QString driver;
                QStringList devices;
                bool operator==(const AudioOutputInfo &rhs) { return name == rhs.name && driver == rhs.driver; }
            };

            QList<AudioOutputInfo> m_audioOutputInfos;
            KSharedConfigPtr m_config;
            void addAudioOutput(AudioDevice dev, QString driver);
            void addAudioOutput(int index, const QString &name, const QString &description, const QString &icon, const QString &driver, const QStringList &deviceIds);

            QbtGStreamerElement *m_play;

            //QbtGStreamerBus *m_bus;

            QbtGStreamerElement *m_fakeSink;
            QbtGStreamerElement *m_audioSink;
            QbtGStreamerElement *m_videoSink;
            QbtGStreamerElement *m_visualisation;
            QbtGStreamerElement *m_pendingVisualisation;
            QbtGStreamerElement *m_volumeElement;
            QbtGStreamerElement *m_textoverlayElement;

            float m_volume;

            /* these are the currently active sinks */
            QList<QbtGStreamerElement*> m_sinks;

            /* the last captured frame for snapshots */
            //QbtGStreamerBuffer* m_frame;

            /* our cache for the sinks */
            //QHash m_cache;

            /* font description */
            QString m_fontDesc;

            /* connection speed in bits/sec (0 = unknown) */
            uint m_connectionSpeed;
    };

}}

#endif
