/*

*/

#include <gst/gst.h>
#include <gst-phonon/gst-phonon.h>
#include "abstractmediaproducer.h"
#include "videopath.h"
#include "audiopath.h"
#include <kdebug.h>
#include <cmath>
#include <QStringList>


namespace Phonon
{
namespace Gst
{
void AbstractMediaProducer::wrapper_signal_metadata_changed(callback_signal_metadata_changed *cb)
{
	QMultiMap<QString, QString> metaDataMap;
	metaDataMap.insert(QLatin1String("TITLE"),
			QString::fromUtf8(gpho_media_producer_meta_data_item(GPHO_MEDIA_PRODUCER(cb->obj), "title")));
	metaDataMap.insert(QLatin1String("ARTIST"),
			QString::fromUtf8(gpho_media_producer_meta_data_item(GPHO_MEDIA_PRODUCER(cb->obj), "artist")));
	metaDataMap.insert(QLatin1String("GENRE"),
			QString::fromUtf8(gpho_media_producer_meta_data_item(GPHO_MEDIA_PRODUCER(cb->obj), "genre")));
	metaDataMap.insert(QLatin1String("ALBUM"),
			QString::fromUtf8(gpho_media_producer_meta_data_item(GPHO_MEDIA_PRODUCER(cb->obj), "album")));
	metaDataMap.insert(QLatin1String("DATE"),
			QString::fromUtf8(gpho_media_producer_meta_data_item(GPHO_MEDIA_PRODUCER(cb->obj), "date")));
	metaDataMap.insert(QLatin1String("TRACKNUMBER"),
			QString::fromUtf8(gpho_media_producer_meta_data_item(GPHO_MEDIA_PRODUCER(cb->obj), "tracknumber")));
	metaDataMap.insert(QLatin1String("DESCRIPTION"),
			QString::fromUtf8(gpho_media_producer_meta_data_item(GPHO_MEDIA_PRODUCER(cb->obj), "description")));

	emit cb->itself->metaDataChanged(metaDataMap);
}


void AbstractMediaProducer::wrapper_signal_tick(callback_signal_tick * cb, guint64 time)
{
	emit cb->itself->tick((qint64)time);
}

void AbstractMediaProducer::wrapper_signal_state_changed(callback_signal_state_changed * cb, State newstate, State oldstate)
{
	emit cb->itself->stateChanged(newstate, oldstate);
}

AbstractMediaProducer::AbstractMediaProducer( QObject* parent )
	: QObject( parent )
{
	kDebug( 611 ) << k_funcinfo << endl;
	object = gpho_media_object_new();

	cb_signal_tick = new callback_signal_tick;
	cb_signal_tick->itself = this;
	cb_signal_tick->obj = object;
	g_signal_connect(object, "tick", G_CALLBACK(wrapper_signal_tick), &cb_signal_tick);

	cb_signal_metadata_changed = new callback_signal_metadata_changed;
	cb_signal_metadata_changed->itself = this;
	cb_signal_metadata_changed->obj = object;
	g_signal_connect(object, "metadata-changed", G_CALLBACK(wrapper_signal_metadata_changed), &cb_signal_metadata_changed);

	cb_signal_state_changed = new callback_signal_state_changed;
	cb_signal_state_changed->itself = this;
	cb_signal_state_changed->obj = object;
	g_signal_connect(object, "state-changed", G_CALLBACK(wrapper_signal_state_changed), &cb_signal_state_changed);
}

AbstractMediaProducer::~AbstractMediaProducer()
{
	kDebug( 611 ) << k_funcinfo << endl;
	gst_object_unref(object);

	delete cb_signal_tick;
}

void AbstractMediaProducer::setBufferSize( int size )
{
	/* XXX: wtf.. */
}

bool AbstractMediaProducer::addVideoPath( QObject* videoPath )
{
	kDebug( 611 ) << k_funcinfo << endl;
	#if 0
	Q_ASSERT( videoPath );
	VideoPath* vp = qobject_cast<VideoPath*>( videoPath );
	Q_ASSERT( vp );
	Q_ASSERT( !m_videoPathList.contains( vp ) );
	m_videoPathList.append( vp );
	#endif
	return true;
}

bool AbstractMediaProducer::addAudioPath( QObject* audioPath )
{
	kDebug( 611 ) << k_funcinfo << endl;
	Q_ASSERT( audioPath );
	#if 0
	AudioPath* ap = qobject_cast<AudioPath*>( audioPath );
	Q_ASSERT( ap );
	Q_ASSERT( !m_audioPathList.contains( ap ) );
	m_audioPathList.append( ap );
	#endif
	/* XXX: how do I retreive the gstobject from the qobject? */
	gpho_media_producer_add_audio_path(GPHO_MEDIA_PRODUCER(object), ((AudioPath *)audioPath)->object);
	return true;
}

void AbstractMediaProducer::removeVideoPath( QObject* videoPath )
{
	#if 0
	Q_ASSERT( videoPath );
	VideoPath* vp = qobject_cast<VideoPath*>( videoPath );
	Q_ASSERT( vp );
	Q_ASSERT( m_videoPathList.contains( vp ) );
	m_videoPathList.removeAll( vp );
	#endif
}

void AbstractMediaProducer::removeAudioPath( QObject* audioPath )
{
	#if 0
	Q_ASSERT( audioPath );
	AudioPath* ap = qobject_cast<AudioPath*>( audioPath );
	Q_ASSERT( ap );
	Q_ASSERT( m_audioPathList.contains( ap ) );
	m_audioPathList.removeAll( ap );
	#endif
}

State AbstractMediaProducer::state() const
{
	kDebug( 611 ) << k_funcinfo << endl;
	return ((State)gpho_media_producer_get_state(GPHO_MEDIA_PRODUCER(object)));
}

bool AbstractMediaProducer::hasVideo() const
{
	kDebug( 611 ) << k_funcinfo << endl;
	return false;
}

bool AbstractMediaProducer::isSeekable() const
{
	kDebug( 611 ) << k_funcinfo << endl;
	return (gpho_media_producer_is_seekable(GPHO_MEDIA_PRODUCER(object)));
}

qint64 AbstractMediaProducer::currentTime() const
{
	kDebug( 611 ) << k_funcinfo << endl;
	return (gpho_media_producer_get_current_time(GPHO_MEDIA_PRODUCER(object)));
}

qint32 AbstractMediaProducer::tickInterval() const
{
	kDebug( 611 ) << k_funcinfo << endl;
	return (gpho_media_producer_get_tick_interval(GPHO_MEDIA_PRODUCER(object)));
}

void AbstractMediaProducer::setTickInterval( qint32 newTickInterval )
{
	kDebug( 600 ) << k_funcinfo << endl;
	gpho_media_producer_set_tick_interval(GPHO_MEDIA_PRODUCER(object), newTickInterval);
}

QStringList AbstractMediaProducer::availableAudioStreams() const
{
	QStringList ret;
	ret << QLatin1String( "en" ) << QLatin1String( "de" );
	return ret;
}

QStringList AbstractMediaProducer::availableVideoStreams() const
{
	QStringList ret;
	ret << QLatin1String( "en" ) << QLatin1String( "de" );
	return ret;
}

QStringList AbstractMediaProducer::availableSubtitleStreams() const
{
	QStringList ret;
	ret << QLatin1String( "en" ) << QLatin1String( "de" );
	return ret;
}

QString AbstractMediaProducer::selectedAudioStream( const QObject* audioPath ) const
{
	return (QLatin1String("en")); /* XXX */
}

QString AbstractMediaProducer::selectedVideoStream( const QObject* videoPath ) const
{
	return (QLatin1String("en")); /* XXX */
}

QString AbstractMediaProducer::selectedSubtitleStream( const QObject* videoPath ) const
{
	return (QLatin1String("en")); /* XXX */
}

void AbstractMediaProducer::selectAudioStream( const QString& streamName, const QObject* audioPath )
{
	/* XXX */
}

void AbstractMediaProducer::selectVideoStream( const QString& streamName, const QObject* videoPath )
{
	/* XXX */
}

void AbstractMediaProducer::selectSubtitleStream( const QString& streamName, const QObject* videoPath )
{
	/* XXX */
}

void AbstractMediaProducer::play()
{
	kDebug( 611 ) << k_funcinfo << endl;
	gpho_media_producer_play(GPHO_MEDIA_PRODUCER(object));
}

void AbstractMediaProducer::pause()
{
    kDebug(611) << k_funcinfo << endl;
	gpho_media_producer_pause(GPHO_MEDIA_PRODUCER(object));
}

void AbstractMediaProducer::stop()
{
	kDebug( 611 ) << k_funcinfo << endl;
	gpho_media_producer_stop(GPHO_MEDIA_PRODUCER(object));
}

void AbstractMediaProducer::seek( qint64 time )
{
	kDebug( 611 ) << k_funcinfo << endl;
	gpho_media_producer_seek(GPHO_MEDIA_PRODUCER(object), time);
}

QString AbstractMediaProducer::errorString() const
{
    return QString();
}

Phonon::ErrorType AbstractMediaProducer::errorType() const
{
    return Phonon::NoError;
}

void AbstractMediaProducer::setState( State newstate )
{
	kDebug(611) << k_funcinfo << endl;
	gpho_media_producer_set_state(GPHO_MEDIA_PRODUCER(object), (GPhoState)newstate);
	//kDebug( 611 ) << "emit stateChanged( " << newstate << ", " << oldstate << " )" << endl;
}

void AbstractMediaProducer::fillBuffer( QVector<float>* buffer )
{
	/* XXX */
}

void AbstractMediaProducer::fillFrameData( Phonon::VideoFrame* frame )
{
	/* XXX */
}

}}
#include "abstractmediaproducer.moc"
// vim: sw=4 ts=4
