#include "global.h"
#ifdef SOUNDS
#include "commands.h"
#include "socket.h"

#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: sounds.c,v 1.10 1996/12/23 20:37:36 root Exp $";
#endif

struct sounds {
	const char *name;		/* name of the sound */
	char *cmd;			/* command to be executed to produce the sound */
	const char *description;	/* description of what the sound is for */
	struct sounds *next;		/* linked list */
};

#define NULLSOUND ((struct sounds *)0)

static struct sounds *snds = NULLSOUND;


static void showsound (struct sounds *s);
static struct sounds *findsound (const char *name);
static struct sounds *newsound (const char *name);
int dosounddefine (int argc,char *argv[],void *p);
static int dosoundplay (int argc,char *argv[],void *p);
static int dosoundlist (int argc,char *argv[],void *p);
static int dosounddelete (int argc,char *argv[],void *p);


/* sounds subcommand table */
static struct cmds SOUNDtab[] = {
	{ "define",		dosounddefine,		0, 0, NULLCHAR },
	{ "delete",		dosounddelete,		0, 2, "sounds delete \"soundname\"" },
	{ "list",		dosoundlist,		0, 0, NULLCHAR },
	{ "play",		dosoundplay,		0, 2, "sounds play \"soundname\"" },
	{ NULLCHAR,		NULL,			0, 0, NULLCHAR }
};


int
dosounds(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	return subcmd(SOUNDtab,argc,argv,p);
}


static void
showsound (s)
struct sounds *s;
{
	tprintf ("UNIX Command %s: %s\n     \"%s\"\n",
		(s->description) ? s->description : "for sound",
		s->name, (s->cmd == NULLCHAR || !*s->cmd) ?
		"(none)" : s->cmd);
}


int
dosounddefine(argc,argv,p)
int argc;
char *argv[];
void *p OPTIONAL;
{
struct sounds *s;

	if (argc > 4 || argc < 2)	{
		tprintf ("Usage: sounds define \"soundname\" [\"soundcommand\" [\"sounddescription\"]]\n");
		return 0;
	}
	
	s = findsound (argv[1]);

	if (argc < 3 && s == NULLSOUND)	{
		tprintf ("Sound '%s' not defined!\n", argv[1]);
		return 0;
	}

	if (s == NULLSOUND)
		s = newsound (argv[1]);

	if (argc == 2)	{
		showsound (s);
		return 0;
	}
	
	if (s->cmd != NULLCHAR)
		free (s->cmd);
	s->cmd = strdup (argv[2]);

	if (argc > 3)	{
		if (s->description != NULLCHAR)
			free (s->description);
		s->description = strdup (argv[3]);
	}
	return 0;
}


static int
dosoundplay(argc,argv,p)
int argc OPTIONAL;
char *argv[];
void *p OPTIONAL;
{
	if (!playsound (argv[1]))
		tprintf ("Sound '%s' not defined!\n", argv[1]);
	return 0;
}


static int
dosoundlist(argc,argv,p)
int argc OPTIONAL;
char *argv[] OPTIONAL;
void *p OPTIONAL;
{
struct sounds *s;

	for (s = snds; s; s = s->next)
		showsound (s);
	return 0;
}


static int
dosounddelete(argc,argv,p)
int argc OPTIONAL;
char *argv[];
void *p OPTIONAL;
{
struct sounds *s = snds, *tmp = NULLSOUND;

	if (s && !stricmp (s->name, argv[1]))	{
		tmp = s;
		snds = s->next;
	} else for (; s && s->next; s = s->next)	{
		if (!stricmp (s->next->name, argv[1]))	{
			tmp = s->next;
			s->next = tmp->next;
			break;
		}
	}

	if (tmp)	{
		if (tmp->name)
			free (tmp->name);
		if (tmp->cmd)
			free (tmp->cmd);
		if (tmp->description)
			free (tmp->description);
		tprintf ("Sound '%s' Deleted!\n", argv[1]);
	}
	return 0;
}


static struct sounds *
findsound (name)
const char *name;
{
struct sounds *s;

	if (name && *name)	{
		for (s = snds; s; s = s->next)	{
			if (!strnicmp (name, s->name, strlen (name)))
				return s;
		}
	}
	return NULLSOUND;
}


static struct sounds *
newsound (name)
const char *name;
{
struct sounds *s;

	s = callocw (1, sizeof(struct sounds));
	s->next = snds;
	snds = s;
	s->name = strdup (name);
	return s;
}


int
playsound (name)
const char *name;
{
char *buf;
struct sounds *s;

	if ((s = findsound (name)) != NULLSOUND)	{
		if (s->cmd == NULLCHAR || !*s->cmd)
			return 0;
		buf = mallocw (strlen(s->cmd) + 18);
		sprintf (buf, "(%s &) 2>/dev/null", s->cmd);
		(void) system (buf);
		return 1;
	} else
		return 0;
}


int
setsoundstr(argc,argv,sound)
int argc;
char *argv[];
char **sound;
{
	if(argc < 2)	{
		if (*sound)
			tprintf ("%s\n", *sound);
	} else {
		if (*sound)
			free (*sound);
		*sound = strdup (argv[1]);
	}
	return 0;
}

#endif /* SOUNDS */
