/*
 * Archimedes sound handler code
 * Graham Biswell <graham@tarka.demon.co.uk>
 * patches by Thomas Pundt <pundtt@ESCHER.UNI-MUENSTER.DE>
 * NAS support by Warren Stockton <wns@knysna.slc.unisys.com>
 *
 * Patched and modified by Gennady B. Sorokopud <gena@netvision.net.il>
 */

/*******************************************************************************
 *   This program is part of a library used by the Archimedes email client     * 
 *                                                                             *
 *   Copyright : (C) 1995-1998 Gennady B. Sorokopud (gena@NetVision.net.il)    *
 *               (C) 1995 Ugen. J. S. Antsilevich (ugen@latte.worldbank.org)   *
 *               (C) 1998-2004 by the Archimedes Project                       *
 *                   http://sourceforge.net/projects/archimedes                *
 *                                                                             *
 *             --------------------------------------------                    *
 *                                                                             *
 *   This program is free software; you can redistribute it and/or modify      *
 *   it under the terms of the GNU Library General Public License as published *
 *   by the Free Software Foundation; either version 2 of the License, or      *
 *   (at your option) any later version.                                       *
 *                                                                             *
 *   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 Library General Public License for more details.                      *
 *                                                                             *
 *   You should have received a copy of the GNU Library 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.  *
 *                                                                             *
 ******************************************************************************/


#include <fmail.h>
#include <umail.h>
#include <cfgfile.h>

extern cfgfile Config;

#ifdef USE_ESOUND
#include <esd.h>

int esd_play_sound(char *soundfile) {
	string esd_host;

	if(Config.exist("esd_host")) {
		esd_host = Config.getCString("esd_host","localhost");
		#ifdef HAVE_SETENV
			setenv("ESPEAKER", esd_host.c_str(), 1);
		#else
		#ifdef HAVE_PUTENV
		if(esd_host.size()) {
			esd_host = "ESPEAKER=" + esd_host; 
			putenv(esd_host.c_str());
		}
		#else
		#error "No method available to set environment variables."
		#endif
		#endif
	}

	return esd_play_file("XFMail", soundfile, 1);
}
#endif

#ifdef NAS_SOUND
	#include <audio/audiolib.h>
	#include <audio/soundlib.h>

/*
 * play the audio file specified as soundfile, to the audio device AUDIO_DEVICE
 * with specified volume volume.
 * returns 0 on success, -1 on error
 */
int nas_play_sound(char *soundfile, int volume) {
	AuServer *aud;
	char *auservername = NULL;

	aud = AuOpenServer(auservername, 0, NULL, 0, NULL, NULL);
	if(!aud)
		return -1;
	if(!AuSoundPlaySynchronousFromFile(aud, soundfile, volume)) {
		AuCloseServer(aud);
		return 0;
	} else {
		AuCloseServer(aud);
		return -1;
	}
}
#endif


#ifdef USE_SOUND

/* This comes from some /etc/magic to check the .au file header */
#define AUDIO_DATA_SUN_BIG_ENDIAN   0x2e736e64
#define AUDIO_DATA_SUN_LITTLE_ENDIAN    0x646e732e

int sox_play_sound(char *soundfile, int volume) {
	int fd_snd, fd_audio, nb;
	int snd_buf[256];

	/* first open sound file */
	if((fd_snd = open(soundfile, O_RDONLY)) < 0) {
		display_msg(MSG_WARN, "play_sound", "Can not open %s", soundfile);
		return -1;
	}

	/* now open audio file */
	if((fd_audio = open(AUDIO_DEVICE, O_WRONLY|O_NONBLOCK)) < 0) {
		if(errno != EBUSY)
			display_msg(MSG_WARN, "play_sound", "Can not open %s", AUDIO_DEVICE);
		close(fd_snd);
		return -1;
	}

	/* now set device volume */
	/* this is not implemented yet */

	/* check if sound file is a valid audio file (SUN au file) */
	read(fd_snd, snd_buf, 24);
	if(snd_buf[0] != AUDIO_DATA_SUN_BIG_ENDIAN &&
	   snd_buf[0] != AUDIO_DATA_SUN_LITTLE_ENDIAN) {
		display_msg(MSG_WARN, "play_sound", "%s is not a vaild audio file", soundfile);
		close(fd_snd);
		close(fd_audio);
		return -1;
	}

	/*
	 * The Sox documentation says, that the header length is a multiple
	 * of 24, given in position 1 of the header.
	 */
	if(htonl(snd_buf[1]) > 24) {
		/* Skip the header */
		if(lseek(fd_snd, htonl(snd_buf[1]), SEEK_SET) == -1) {
			display_msg(MSG_WARN, "play_sound", "Invalid header length in audio file");
			close(fd_snd);
			close(fd_audio);
			return -1;
		}
	}

	/* now play sound file */
	while((nb = read(fd_snd, snd_buf, 256)) > 0) {
		if((write(fd_audio, snd_buf, nb)) < 0) {
			display_msg(MSG_WARN, "play_sound", "Write failed\n%s", AUDIO_DEVICE);
			close(fd_snd);
			close(fd_audio);
			return -1;
		}
	}

	/* tidy up & exit */
	close (fd_audio);
	close (fd_snd);
	return 0;
}
#endif


int play_sound(char *soundfile, int volume) {
#ifdef USE_SOUND
#ifdef USE_ESOUND
	if(Config.exist("use_esd")) {
		return esd_play_sound(soundfile);
	}
#endif

#ifdef NAS_SOUND
	if(Config.exist("use_nas")) {
		return nas_play_sound(soundfile, volume);
	}
#endif
	return sox_play_sound(soundfile, volume);
#else
	display_msg(MSG_WARN, "play_sound", "This program was not compiled with support for playing sound");
	return -1;
#endif  /* USE_SOUND */
}
