/* 
*/
#ifndef Phonon_GST_ABSTRACTMEDIAPRODUCER_H
#define Phonon_GST_ABSTRACTMEDIAPRODUCER_H

#include <QObject>
#include <QTime>
#include <QList>
#include <phonon/phononnamespace.h>
#include "audiopath.h"
#include "videopath.h"
#include <QHash>
#include <phonon/mediaproducerinterface.h>
#include <QMultiMap>

class QTimer;


namespace Phonon
{
	class VideoFrame;

namespace Gst
{
	class AbstractMediaProducer;
	struct callback_signal_tick {
		AbstractMediaProducer *itself;
		GPhoMediaObject *obj;
	};
	struct callback_signal_metadata_changed {
		AbstractMediaProducer *itself;
		GPhoMediaObject *obj;
	};
	struct callback_signal_state_changed {
		AbstractMediaProducer *itself;
		GPhoMediaObject *obj;
	};

	class KDE_EXPORT AbstractMediaProducer : public QObject, public Phonon::MediaProducerInterface
	{
		Q_OBJECT
		Q_INTERFACES( Phonon::MediaProducerInterface )
		public:
			AbstractMediaProducer( QObject* parent );
			~AbstractMediaProducer();
			bool addVideoPath( QObject* videoPath );
			bool addAudioPath( QObject* audioPath );
			void removeVideoPath( QObject* videoPath );
			void removeAudioPath( QObject* audioPath );
			Phonon::State state() const;
			bool hasVideo() const;
			bool isSeekable() const;
			qint64 currentTime() const;
			qint32 tickInterval() const;

			QStringList availableAudioStreams() const;
			QStringList availableVideoStreams() const;
			QStringList availableSubtitleStreams() const;

			QString selectedAudioStream( const QObject* audioPath ) const;
			QString selectedVideoStream( const QObject* videoPath ) const;
			QString selectedSubtitleStream( const QObject* videoPath ) const;

			void selectAudioStream( const QString& streamName, const QObject* audioPath );
			void selectVideoStream( const QString& streamName, const QObject* videoPath );
			void selectSubtitleStream( const QString& streamName, const QObject* videoPath );

			void setTickInterval( qint32 newTickInterval );
			void play();
			void pause();
			void stop();
			void seek( qint64 time );

            QString errorString() const;
            Phonon::ErrorType errorType() const;

			void setBufferSize( int size );
			GPhoMediaObject *object;
			static void wrapper_signal_tick(callback_signal_tick * cb, guint64 time);
			static void wrapper_signal_metadata_changed(callback_signal_metadata_changed * cb);
			static void wrapper_signal_state_changed(callback_signal_state_changed * cb, State newstate, State oldstate);

		Q_SIGNALS:
			void tick( qint64 time );
			void stateChanged( Phonon::State newstate, Phonon::State oldstate );
			void metaDataChanged( QMultiMap<QString, QString> );
            void seekableChanged(bool);

		protected:
			void fillBuffer( QVector<float>* buffer );
			void fillFrameData( Phonon::VideoFrame* frame );
			void setState( State );

		protected Q_SLOTS:
			//virtual void emitTick();

		private:
			struct callback_signal_tick *cb_signal_tick;
			struct callback_signal_metadata_changed *cb_signal_metadata_changed;
			struct callback_signal_state_changed *cb_signal_state_changed;
			#if 0
			State m_state;
			QTimer* m_tickTimer;
			qint32 m_tickInterval;
			QTime m_startTime, m_pauseTime;
			int m_bufferSize;
			QList<AudioPath*> m_audioPathList;
			QList<VideoPath*> m_videoPathList;
			int m_lastSamplesMissing;

			// for sound synthesis
			float m_position, m_frequency;

			QHash<const QObject*, QString> m_selectedAudioStream;
			QHash<const QObject*, QString> m_selectedVideoStream;
			QHash<const QObject*, QString> m_selectedSubtitleStream;
			#endif
	};
}} //namespace Phonon::Gst

// vim: sw=4 ts=4 tw=80
#endif // Phonon_GST_ABSTRACTMEDIAPRODUCER_H
