/* NMM - Network-Integrated Multimedia Middleware
 *
 * Copyright (C) 2006
 *               Motama GmbH, Saarbruecken, Germany
 *
 * Maintainer: Bernhard Fuchshumer <fub@motama.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2
 * of the License only.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 */

#ifndef Phonon_NMM_ABSTRACTMEDIAPRODUCER_H
#define Phonon_NMM_ABSTRACTMEDIAPRODUCER_H


//nmm includes
#include "nmm/base/NMMApplication.hpp"
#include "nmm/base/registry/GraphDescription.hpp"
#include "nmm/base/graph/GraphHandler.hpp"
#include "nmm/base/sync/MultiAudioVideoSynchronizer.hpp"
using namespace NMM;

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

#include <phonon/mediaproducerinterface.h>
//#include "configproxy.h"


namespace Phonon
{
namespace nmm
{
	class Backend;
	class AbstractMediaProducer : public QObject, public MediaProducerInterface
	{
		Q_OBJECT
		Q_INTERFACES( Phonon::MediaProducerInterface )
		public:
			AbstractMediaProducer( Backend* backend, 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;
			void setTickInterval( qint32 newTickInterval );
			void play();
			void pause();
			void stop();
			void seek( qint64 time );

			qint32 aboutToFinishTime() const;
			void setAboutToFinishTime( qint32 newAboutToFinishTime );
			qint64 totalTime() 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 );

			//TODO
			virtual QString errorString() const { return QString(); }
			virtual Phonon::ErrorType errorType() const { return Phonon::NoError; }

		Q_SIGNALS:
			void stateChanged( Phonon::State newstate, Phonon::State oldstate );
			void tick( qint64 time );
			void length( qint64 length );
			virtual void finished();
			void aboutToFinish( qint32 msec );
			// TODO
			//void seekableChanged(bool);

		protected:
			void setState( Phonon::State );
			virtual void setTrackDuration(qint64 duration );
			virtual void setUrl(const KUrl& url);
			virtual KUrl url();
			void internalStop();

			//ConfigProxy* m_config;

			QList<AudioPath*> m_audioPathList;
			QList<VideoPath*> m_videoPathList;

			bool addVideoPaths();
			bool addAudioPaths();
			void stage1Reached();

			//nmm specific
			virtual void registerEventHandler();
			void initGraphHandler();
			void deinitGraphHandler();
			
			GraphHandler* m_graphHandler;
			MultiAudioVideoSynchronizer m_avSync;
			bool m_eventHandlerRegistered;
			CompositeNode* m_cnode;
			qint64 m_trackDuration;
			qint64 m_currentTime;

			qint32 m_aboutToFinishTime;
			bool m_aboutToFinishNotEmitted;
			bool m_eod;
			string m_url;
			bool m_stage1Reached;


		protected Q_SLOTS:
			Result endTrack(); //this will be called by the nmm, when the endTrack event occurs

		private:
			Phonon::State m_state;
			qint32 m_tickInterval;
			qint64 m_lastSeek;

			QHash<const AudioPath*, QString> m_selectedAudioStream;
			QHash<const VideoPath*, QString> m_selectedVideoStream;
			QHash<const VideoPath*, QString> m_selectedSubtitleStream;

			void setupGraph(); //this will cause the EventListeners to be registered and the composite node to be set.
			TEDObject1<AbstractMediaProducer, Interval> m_trackDurationListener;
			TEDObject1<AbstractMediaProducer, Time> m_timeProgressListener;
			Result trackDuration(Interval& i);
			Result setTimeProgress(Time& current);

			Backend* m_backend;
			int m_endTrackReceived;
	};
}} //namespace Phonon::nmm

#endif // Phonon_NMM_ABSTRACTMEDIAPRODUCER_H
// vim: sw=4 ts=4 tw=80 noet
