/***************************************************************************
                          audio.cpp  -  description
                             -------------------
    begin                : Mon Jan 7 2002
    copyright            : (C) 2003 by Troy Corbin Jr.
    email                : tcorbin@users.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "audio.h"
#include <arts/soundserver.h>
#include <arts/dispatcher.h>
#include <arts/flowsystem.h>
#include <arts/connect.h>
#include <ksimpleconfig.h>
#include <tdeio/netaccess.h>
#include <tqptrlist.h>
#include <tqfile.h>
#include <tqmap.h>

class audioPrivate
{
	public:
		bool														enabled;
		bool														firstTime;
		TQString													theme;
		Arts::Dispatcher								dispatcher;
		Arts::SoundServerV2							server;
		Arts::PlayObjectFactory					playObjectFactory;
		TQMap<int, Arts::PlayObject>			audioMap;
		TQPtrList<KTempFile>							fileRef;
};

audio::audio()
{
	a = new audioPrivate;
	a->server = Arts::Reference("global:Arts_SoundServerV2");
	a->fileRef.setAutoDelete( TRUE );
	if( a->server.isNull() )
	{
		a->enabled = FALSE;
		kdWarning() << "audio::audio: Can not create Arts::SoundServerV2" << endl;
	}
	else
	{
		a->enabled = TRUE;
		a->playObjectFactory = Arts::Reference("global:Arts_PlayObjectFactory");
	}
	a->firstTime = TRUE;
}
audio::~audio()
{
	a->audioMap.clear();
	a->fileRef.clear();
	delete a;
}
void audio::play( const int snd )
{
	if( a->firstTime || !enabled || !a->enabled )
		return;

	TQMap<int, Arts::PlayObject>::Iterator IT = a->audioMap.find( snd );

	if( IT == a->audioMap.end() )
	{
		return;
	}

	Arts::PlayObject* current = &IT.data();

	if( volume )
	{
		Arts::Synth_BUS_UPLINK uplink = Arts::DynamicCast( current->_getChild( "uplink" ) );
		uplink.stop();
		current->_node()->stop();
		Arts::disconnect( *current, "left", uplink, "left" );
		Arts::disconnect( *current, "right", uplink, "right" );
		Arts::StereoVolumeControl volumeControl = Arts::DynamicCast( a->server.createObject( "Arts::StereoVolumeControl" ) );
		current->_addChild( volumeControl, "volume" );
		uplink.start();
		volumeControl.start();
		current->_node()->start();
		Arts::connect( *current, "left", volumeControl, "inleft" );
		Arts::connect( *current, "right", volumeControl, "inright" );
		Arts::connect( volumeControl, "outleft", uplink, "left" );
		Arts::connect( volumeControl, "outright", uplink, "right" );
		volumeControl.scaleFactor( ( 100 - volume ) / 100.0 );
	}

	Arts::poTime time = current->currentTime();
	time.seconds = 0;
	time.ms = 0;
	current->seek( time );
	current->play();
}

void audio::setTheme( const TQString &newTheme )
{
	TQString configFile;
	KSimpleConfig *themeConfig;

	if( !enabled || !a->enabled )
		return;

	a->audioMap.clear();
	a->fileRef.clear();

	if( !TDEIO::NetAccess::download( newTheme + "theme.conf" , configFile ) )
	{
		kdWarning() << "audio::setTheme: Can not access theme.conf from " << newTheme << endl;
		return;
	}
	themeConfig = new KSimpleConfig( configFile, TRUE );

	/* Read the details about this theme */
	themeConfig->setGroup( "General" );
	themeHeader.name = themeConfig->readEntry( "Name", "Unknown" );
	themeHeader.version = themeConfig->readEntry( "Version", "Unknown" );
	themeHeader.author = themeConfig->readEntry( "Author", "Unknown" );
	themeHeader.authorEmail = themeConfig->readEntry( "AuthorEmail", "Unknown" );
	themeHeader.authorWWW = themeConfig->readEntry( "AuthorWWW", "Unknown" );
	themeHeader.notes = themeConfig->readEntry( "Notes", "Unknown" );

	/* Read the sounds */
	themeConfig->setGroup( "Audio" );
	a->theme = newTheme;
	prepFile( a->theme + themeConfig->readEntry("Select"), SND_SELECT );
	prepFile( a->theme + themeConfig->readEntry("Move"), SND_MOVE );
	prepFile( a->theme + themeConfig->readEntry("Check"), SND_CHECK );
	prepFile( a->theme + themeConfig->readEntry("MatchOver"), SND_MATCH_OVER );
	prepFile( a->theme + themeConfig->readEntry("Challenge"), SND_CHALLENGE );
	prepFile( a->theme + themeConfig->readEntry("Tell"), SND_TELL );
	prepFile( a->theme + themeConfig->readEntry("Notification"), SND_NOTIFICATION );
	prepFile( a->theme + themeConfig->readEntry("DrawOffer"), SND_DRAW_OFFER );
	prepFile( a->theme + themeConfig->readEntry("Say"), SND_SAY );
	prepFile( a->theme + themeConfig->readEntry("Promote"), SND_PROMOTE );
	a->firstTime = FALSE;

	delete themeConfig;
	TDEIO::NetAccess::removeTempFile( configFile );
}
void audio::prepFile( const TQString &source, const int &ref )
{
	Arts::PlayObject player;
	KTempFile *dest;
	TQString filename;
	if( source.isEmpty() )
		return;

	dest = new KTempFile( TQString(), source.right(4), 700 );
	dest->setAutoDelete( TRUE );
	filename = dest->name();

	if( !TDEIO::NetAccess::download( source, filename ) )
	{
		kdWarning() << "audio::prepFile: Can not download " << source << endl;
		delete dest;
		return;
	}
	player = a->playObjectFactory.createPlayObject( TQFile::encodeName( dest->name() ).data() );
	if( player.isNull() )
	{
		delete dest;
		return;
	}
	a->fileRef.append( dest );
	a->audioMap[ ref ] = player;
	return;
}
