/*
*/

#include <gst/gst.h>
#include <gst-phonon/gst-phonon.h>
#include "backend.h"
#include "mediaobject.h"
#include "mediaqueue.h"
#include "avcapture.h"
#include "bytestream.h"
#include "audiopath.h"
#include "audioeffect.h"
#include "audiooutput.h"
#include "audiodataoutput.h"
#include "visualization.h"
#include "videopath.h"
#include "videoeffect.h"
#include "brightnesscontrol.h"

#include <kgenericfactory.h>
#include "volumefadereffect.h"
#include <QSet>
#include "videodataoutput.h"
#include <QVariant>

typedef KGenericFactory<Phonon::Gst::Backend, Phonon::Gst::Backend> GstBackendFactory;
K_EXPORT_COMPONENT_FACTORY( phonon_gst, GstBackendFactory( "gstbackend" ) )

namespace Phonon
{
namespace Gst
{

Backend::Backend( QObject* parent, const QStringList& )
	: QObject( parent )
{ 
//	gpho_init(NULL, NULL); /* XXX: that should work.. */
	gst_init(NULL, NULL);
//	object = gpho_backend_new();
}

Backend::~Backend()
{
	//gst_object_unref(object);
}

QObject* Backend::createObject0(BackendInterface::Class0 c, QObject *parent)
{
    switch (c) {
        case MediaObjectClass:
            return new MediaObject(parent);
        case MediaQueueClass:
            return new MediaQueue(parent);
        case AvCaptureClass:
            return new AvCapture(parent);
        case ByteStreamClass:
            return new ByteStream(parent);
        case AudioPathClass:
            return new AudioPath(parent);
        case VolumeFaderEffectClass:
            return new VolumeFaderEffect(parent);
        case AudioOutputClass:
            {
                AudioOutput *ao = new AudioOutput(parent);
                m_audioOutputs.append(ao);
                return ao;
            }
        case AudioDataOutputClass:
            return new AudioDataOutput(parent);
        case VisualizationClass:
            return new Visualization(parent);
        case VideoPathClass:
            return new VideoPath(parent);
        case BrightnessControlClass:
            return new BrightnessControl(parent);
        case VideoDataOutputClass:
            return new VideoDataOutput(parent);
		case DeinterlaceFilterClass:
			return 0; /* XXX */
    }
    return 0;
}

QObject* Backend::createObject1(BackendInterface::Class1 c, QObject *parent, QVariant arg1)
{
    switch (c) {
        case AudioEffectClass:
            return new AudioEffect(arg1.toInt(), parent);
        case VideoEffectClass:
            return new VideoEffect(arg1.toInt(), parent);
    }
    return 0;
}

bool Backend::supportsVideo() const
{
	return true;
}

bool Backend::supportsOSD() const
{
	return false;
}

bool Backend::supportsFourcc( quint32 fourcc ) const
{
	switch( fourcc )
	{
		case 0x00000000:
			return true;
		default:
			return false;
	}
}

bool Backend::supportsSubtitles() const
{
	return false;
}

QStringList Backend::knownMimeTypes() const
{
	if( m_supportedMimeTypes.isEmpty() )
		const_cast<Backend*>( this )->m_supportedMimeTypes
			<< QLatin1String( "audio/vorbis" )
			//<< QLatin1String( "audio/x-mp3" )
			<< QLatin1String( "audio/x-wav" )
			<< QLatin1String( "video/x-ogm" );
	return m_supportedMimeTypes;
}

QSet<int> Backend::objectDescriptionIndexes( ObjectDescriptionType type ) const
{
	QSet<int> set;
	switch( type )
	{
		case Phonon::AudioOutputDeviceType:
			set << 10000 << 10001;
			break;
		case Phonon::AudioCaptureDeviceType:
			set << 20000 << 20001;
			break;
		case Phonon::VideoOutputDeviceType:
			set << 40000 << 40001 << 40002 << 40003;
			break;
		case Phonon::VideoCaptureDeviceType:
			set << 30000 << 30001;
			break;
		case Phonon::VisualizationType:
		case Phonon::AudioCodecType:
		case Phonon::VideoCodecType:
		case Phonon::ContainerFormatType:
			break;
		case Phonon::AudioEffectType:
			set << 0x7F000001;
			break;
		case Phonon::VideoEffectType:
			set << 0x7E000001;
			break;
	}
	return set;
}

QHash<QByteArray, QVariant> Backend::objectDescriptionProperties(ObjectDescriptionType type, int index) const
{
    QHash<QByteArray, QVariant> ret;
    switch (type) {
        case Phonon::AudioOutputDeviceType:
            switch (index) {
                case 10000:
                    ret.insert("name", QLatin1String("internal Soundcard"));
                    break;
                case 10001:
                    ret.insert("name", QLatin1String("USB Headset"));
                    break;
            }
            break;
        case Phonon::AudioCaptureDeviceType:
            switch (index) {
                case 20000:
                    ret.insert("name", QLatin1String("Soundcard"));
                    ret.insert("description", QLatin1String("first description"));
                    break;
                case 20001:
                    ret.insert("name", QLatin1String("DV"));
                    ret.insert("description", QLatin1String("second description"));
                    break;
            }
            break;
        case Phonon::VideoOutputDeviceType:
            switch (index) {
                case 40000:
                    ret.insert("name", QLatin1String("XVideo"));
                    break;
                case 40001:
                    ret.insert("name", QLatin1String("XShm"));
                    break;
                case 40002:
                    ret.insert("name", QLatin1String("X11"));
                    break;
                case 40003:
                    ret.insert("name", QLatin1String("SDL"));
                    break;
            }
            break;
        case Phonon::VideoCaptureDeviceType:
            switch (index) {
                case 30000:
                    ret.insert("name", QLatin1String("USB Webcam"));
                    ret.insert("description", QLatin1String("first description"));
                    break;
                case 30001:
                    ret.insert("name", QLatin1String("DV"));
                    ret.insert("description", QLatin1String("second description"));
                    break;
            }
            break;
        case Phonon::VisualizationType:
            break;
        case Phonon::AudioCodecType:
            break;
        case Phonon::VideoCodecType:
            break;
        case Phonon::ContainerFormatType:
            break;
        case Phonon::AudioEffectType:
            switch (index) {
                case 0x7F000001:
                    ret.insert("name", QLatin1String("Delay"));
                    ret.insert("description", QLatin1String("Simple delay effect with time, feedback and level controls."));
                    break;
            }
            break;
        case Phonon::VideoEffectType:
            switch (index) {
                case 0x7E000001:
                    ret.insert("name", QLatin1String("VideoEffect1"));
                    ret.insert("description", QLatin1String("Description 1"));
                    break;
            }
            break;
    }
    return ret;
}

char const* Backend::uiLibrary() const
{
	//return "phonon_gstui";
	return NULL; /* XXX */
}

void Backend::freeSoundcardDevices()
{
	foreach( QPointer<AudioOutput> ao, m_audioOutputs )
		if( ao )
			ao->closeDevice();
}

}}

#include "backend.moc"

// vim: sw=4 ts=4
