/*
	wav_frontend.c
	4.6.99 tn
*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "largefile.h"

#if HAVE_LOCALE_H
#include <locale.h>
#else
# define setlocale(Category, Locale) 
#endif
#include "gettext.h"

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

#if ENABLE_NLS
# define _(String) gettext (String)
# define N_(String) gettext_noop (String)
#else
# define _(String) (String)
# define N_(String) (String)
#endif
#define GTK_ENABLE_BROKEN

#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "xcdrdata.h"
#include "xcdroast.h"
#include "main.h"
#include "../xpms/snd_play.xpm"
#include "../xpms/snd_stop.xpm"
#include "../xpms/snd_pause.xpm"
#include "../xpms/snd_next.xpm"
#include "../xpms/snd_prev.xpm"
#include "../xpms/snd_quit.xpm"
#include "../xpms/snd_mixer.xpm"


extern GtkCList *play_clist;
extern setup_data_t setupdata;
extern GList *imagelist;
extern gchar sharedir[MAXLINE];

gint wav_in, wavplay_quit;
GtkWidget *wav_quit_button;
static GtkWidget *drawa, *timer_label, *wavplay_text;
static GtkWidget *playb, *stopb, *nextb;
static gint playhdl, stophdl, nexthdl, prevhdl;
static GdkPixmap *pixmap = NULL;
static gint wav_out;
static gint maxseconds;
static gint curseconds;
static gint maxpixels;
static gint ptimer;
static gint callback_tag;
static gint error_flag;

static void read_wav_out(gpointer data, gint source, GdkInputCondition cond);
static gint draw_ticks (gpointer data);


/* updates the text-window */

static void update_text(gchar *txt) {
gchar tmp[MAXLINE];

	strncpy(tmp, txt, MAXLINE);
	convert_for_gtk2_textwidget(tmp);

	/* delete text-window first */
	gtk_text_backward_delete(GTK_TEXT(wavplay_text),
		gtk_text_get_length(GTK_TEXT(wavplay_text)));
        gtk_text_insert(GTK_TEXT(wavplay_text),
                NULL,NULL,NULL, tmp, strlen(tmp));
}


/* draw the text-info for current playing track */ 

static void trackinfo_text(gchar *file) {
GList *loop;
image_files_t *entry;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gint count;

	strcpy(tmp,"");

	/* search current file in imagelist */
	count = 1;
	loop = g_list_first(imagelist);
	while (loop) {
		entry = loop->data;
		if (entry->type == 1) {
			if (strcmp(entry->path,file) == 0) {
				/* found match */
				convert_frames2minstring(
					(gint)((off_t)entry->size/CDDAFRAME), tmp2);
				if (entry->title && entry->artist &&
				    strcmp(entry->title,"") &&
				    strcmp(entry->artist,"")) {
					g_snprintf(tmp,MAXLINE,
					   "%d. %s / %s [%s]",
					   count, entry->title, 
					   entry->artist, tmp2);
				} else 
				if (entry->title && 
				    strcmp(entry->title,"")) {
					g_snprintf(tmp,MAXLINE,
					   "%d. %s [%s]",
					   count, entry->title, tmp2);
				} else
				if (entry->cddb_ttitle && 
				    strcmp(entry->cddb_ttitle,"")) {
					g_snprintf(tmp,MAXLINE,
					   "%d. %s [%s]",
					   count, entry->cddb_ttitle, tmp2);
				} else {
					g_snprintf(tmp,MAXLINE,"%d. %s [%s]",
					   count, file, tmp2);
				}
				break;
			}
			count++;		
		}
		loop = loop->next;
	}
	update_text(tmp);	
}


/* loads a wav-file and starts playing */

static void start_play(gchar *filename) {
gchar cmd[MAXLINE];
gchar tmptmp[MAXLINE];

	/* already playing? */
	if (wav_in != -1) {
		return;
	}

	/* have we got an audiodevice? */
	if (strcmp(setupdata.dsp_device,"") == 0) {
		update_text(_("Warning: No DSP-device configured."));	
		return;
	}

	strcpy(tmptmp,filename);
	g_snprintf(cmd,MAXLINE,"%s/%s -g -d \"%s\" \"%s\" 2>&1", sharedir, WAVPLAY, 
			setupdata.dsp_device, convert_escape(tmptmp));

	dodebug(1, "spawning shell: %s\n",cmd);
	dolog(3, "Executing: %s\n", cmd);

	/* start child and get new fds */
	full_dpl_pipe_shell(&wav_out,&wav_in,cmd);

	/* catch output of child */
	callback_tag = gdk_input_add(wav_out, GDK_INPUT_READ, 
		(GdkInputFunction) read_wav_out, NULL);

}


/* ends the wavplay-process and cleans up */

static void stop_play() {

	if (wav_in == -1) {
		/* we are not playing right now */
		return;
	}

	dodebug(8,"wavplay: stop_play\n");

	/* ok, at this point the child terminated */
	gtk_input_remove(callback_tag);
	wav_out = -1;
	wav_in = -1;
	maxseconds = 60;
	maxpixels = 1;
	curseconds = 0;

	/* update screen */
	if (wavplay_quit == 0) 
		ptimer=gtk_timeout_add (100, draw_ticks, drawa);
	
	/* if no error-condition, clear up text-window */
	if (error_flag == 0) {
		update_text("");
	} else {
		error_flag = 0;
	}
}


/* get current selected track-name */

static void get_sel_trackname(gchar *tname) {
GList *sel;
gint row;
gchar *text;

	sel = play_clist->selection;
	if (sel != NULL) {
		row = GPOINTER_TO_INT(sel->data);
		gtk_clist_get_text(play_clist,row,4, &text);
		strncpy(tname,text,MAXLINE);
		return;
	}
	strcpy(tname,"");
	return;
}


/* autoselect next track */

static void select_next_track() {
gint rows;
gint row;
GList *sel;

	/* get data from clist */
	row = -1;
	rows = play_clist->rows;
	sel = play_clist->selection;
	if (sel != NULL) {
		row = GPOINTER_TO_INT(sel->data);
	}
	/* nothing selected? */
	if (row == -1) {
		row = 0;
	} else {
		row++;
		if (row >= rows) row = 0; 
	}
	gtk_clist_select_row(play_clist,row,0);
}


/* autoselect prev track */

static void select_prev_track() {
gint rows;
gint row;
GList *sel;

	/* get data from clist */
	row = -1;
	rows = play_clist->rows;
	sel = play_clist->selection;
	if (sel != NULL) {
		row = GPOINTER_TO_INT(sel->data);
	}
	/* nothing selected? */
	if (row == -1) {
		row = rows-1;
	} else {
		row--;
		if (row < 0) row = rows-1; 
	}
	gtk_clist_select_row(play_clist,row,0);
}


/* Create a new backing pixmap of the appropriate size */

static gint configure_event (GtkWidget *widget, GdkEventConfigure *event) {

         if (pixmap)
           gdk_pixmap_unref(pixmap);

         pixmap = gdk_pixmap_new(widget->window,
                                 widget->allocation.width,
                                 widget->allocation.height,
                                 -1);

	/* set background to white */
	gdk_draw_rectangle (pixmap,
			widget->style->white_gc,
			TRUE,
			0, 0,
			widget->allocation.width,
			widget->allocation.height);

         return TRUE;
}


/* Redraw the screen from the backing pixmap */

static gint expose_event (GtkWidget *widget, GdkEventExpose *event) {

         gdk_draw_pixmap(widget->window,
                         widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
                         pixmap,
                         event->area.x, event->area.y,
                         event->area.x, event->area.y,
                         event->area.width, event->area.height);

         return FALSE;
}


/* catch a click on the drawarea */
 
static gint button_press_event (GtkWidget *widget, GdkEventButton *event) {
gint sec;
gchar tmp[MAXLINE];

  	if (event->button == 1 && pixmap != NULL) {
		sec = (((gint) event->x)-5)*maxseconds/maxpixels;
		if (sec < 0) sec = 0;
		if (sec > maxseconds) sec = maxseconds;

		/* pipes not yet set up */
		if (wav_in == -1) return TRUE;

		g_snprintf(tmp,MAXLINE,"set%d\n",sec);
		dodebug(8,"wavplay: sending command %s\n", tmp);
		if (write(wav_in, tmp, strlen(tmp)) != strlen(tmp)) {
			g_warning("write error to pipe\n");
		}
	}

  	return TRUE;
}


/* button callbacks */

static void doplay(GtkWidget *widget, gpointer data) {
gchar tmp[MAXLINE];

	/* get trackname from selection */
	get_sel_trackname(tmp);

	/* if nothing selected force select first row */
	if (strcmp(tmp,"") == 0) {
		gtk_clist_select_row(play_clist,0,0);
		get_sel_trackname(tmp);
	}
	
	/* got a valid selection? start play it */
	if (strcmp(tmp,"") != 0) {
		start_play(tmp);
	}

	/* pipes not yet set up */
	if (wav_in == -1) {
		/* detoggle button */
		gtk_signal_handler_block(GTK_OBJECT(playb),playhdl);
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(playb),0);
		gtk_signal_handler_unblock(GTK_OBJECT(playb),playhdl);
		return;
	}

	/* draw text-info */
	trackinfo_text(tmp);

	dodebug(8,"wavplay: sending command play\n");
	if (write(wav_in, "play\n", 5) != 5) {
		g_warning("write error to pipe\n");
	}
}

static void dostop(GtkWidget *widget, gpointer data) {

	/* pipes not yet set up */
	if (wav_in == -1) {
		/* detoggle button */
		gtk_signal_handler_block(GTK_OBJECT(stopb),stophdl);
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stopb),0);
		gtk_signal_handler_unblock(GTK_OBJECT(stopb),stophdl);
		return;
	}

	dodebug(8,"wavplay: sending command stop\n");
	if (write(wav_in, "stop\n", 5) != 5) {
		g_warning("write error to pipe\n");
	}
}

static void dopause(GtkWidget *widget, gpointer data) {

	/* pipes not yet set up */
	if (wav_in == -1) return;

	dodebug(8,"wavplay: sending command pause\n");
	if (write(wav_in, "pause\n", 6) != 6) {
		g_warning("write error to pipe\n");
	}
}

static void doquit(GtkWidget *widget, gpointer data) {

	/* pipes not yet set up */
	if (wav_in == -1) return;

	dodebug(8,"wavplay: sending command quit\n");
	if (write(wav_in, "quit\n", 5) != 5) {
		g_warning("write error to pipe\n");
	}

	/* clean up will be done automatically when child quits */
}

static void doprev(GtkWidget *widget, gpointer data) {

	/* lock button as long its doing it work */
	gtk_signal_handler_block(GTK_OBJECT(widget),prevhdl);

	select_prev_track();
	
	/* ok..stop play current track and play previous */
	gtk_button_clicked(GTK_BUTTON(wav_quit_button));

	/* now wait until we are really finished */
	while (wav_in != -1) {
		wait_and_process_events();
	}
	gtk_button_clicked(GTK_BUTTON(playb));

	gtk_signal_handler_unblock(GTK_OBJECT(widget),prevhdl);
}

static void donext(GtkWidget *widget, gpointer data) {

	/* lock button as long its doing it work */
	gtk_signal_handler_block(GTK_OBJECT(widget),nexthdl);

	select_next_track();

	/* ok..stop play current track and play next */
	gtk_button_clicked(GTK_BUTTON(wav_quit_button));

	/* now wait until we are really finished */
	while (wav_in != -1) {
		wait_and_process_events();
	}
	gtk_button_clicked(GTK_BUTTON(playb));

	gtk_signal_handler_unblock(GTK_OBJECT(widget),nexthdl);
}


/* called on double-click in the clist */

void wavplay_dodouble() {

	gtk_button_clicked(GTK_BUTTON(wav_quit_button));

	/* now wait until we are really finished */
	while (wav_in != -1) {
		wait_and_process_events();
	}
	gtk_button_clicked(GTK_BUTTON(playb));
}


/* volume changed */

static void vol_changed(GtkAdjustment *adj, GtkWidget *label) {

	set_mixer((gint)adj->value);
}


/* paint the tick-display */

static gint draw_ticks (gpointer data) {
GtkWidget *dr;
GdkRectangle update_rect;
GdkPoint marker[4];
gint mx,my,dx;
gint i;

	/* this is a workaround to force gtk to display my drawing area */
	/* it is called once and then removed */
	if (ptimer != -1) {
		gtk_timeout_remove(ptimer); 
		/* detoggle play/stop button */
		gtk_signal_handler_block(GTK_OBJECT(playb),playhdl);
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(playb),0);
		gtk_signal_handler_unblock(GTK_OBJECT(playb),playhdl);
		gtk_signal_handler_block(GTK_OBJECT(stopb),stophdl);
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stopb),0);
		gtk_signal_handler_unblock(GTK_OBJECT(stopb),stophdl);
		ptimer = -1;
	}

	dr = (GtkWidget *)data;
	mx = dr->allocation.width;
	my = dr->allocation.height;
	maxpixels = mx-10;

	/* clear background */
	gdk_draw_rectangle (pixmap, dr->style->white_gc,TRUE,0,0,mx,my);

	/* do your job here */
	gdk_draw_line(pixmap, dr->style->black_gc, 
		5,my/2, mx-5,my/2);
	gdk_draw_line(pixmap, dr->style->black_gc,
		5,my/2-12,5,my/2+12);
	gdk_draw_line(pixmap, dr->style->black_gc,
		mx-5,my/2-12,mx-5,my/2+12);

	/* draw the 5/10/60 sec ticks */
	for (i = 0; i < maxseconds; i+=5) {

		dx = (i*maxpixels/maxseconds)+5;
		if (i%60 == 0) {
			/* draw 60 sec tick */
			gdk_draw_line(pixmap, dr->style->black_gc,
				dx,my/2-8,dx,my/2+8);	
		} else if (i%10 == 0) {
			/* draw 10 sec tick */
			gdk_draw_line(pixmap, dr->style->black_gc,
				dx,my/2-8,dx,my/2);	
		} else {
			/* draw 5 sec tick */
			gdk_draw_line(pixmap, dr->style->black_gc,
				dx,my/2-4,dx,my/2);	
		}
	}

	/* draw the current play-position */
	dx = (curseconds*maxpixels/maxseconds)+5;
	marker[0].x = dx;
	marker[0].y = my/2+1;
	marker[1].x = dx-6;
	marker[1].y = my/2+8;
	marker[2].x = dx+6;
	marker[2].y = my/2+8;
	marker[3].x = dx;
	marker[3].y = my/2+1;
	gdk_draw_polygon(pixmap, dr->style->black_gc,
		TRUE,marker,4);
	
	/* copy pixmap to screen */
	update_rect.x = 0;
	update_rect.y = 0;
	update_rect.width = mx;
	update_rect.height = my;

	/* this calls expose */
	gtk_widget_draw (dr, &update_rect);

	return(TRUE);
}


/* called when new data from stdout of child is available */

static void read_wav_out(gpointer data, gint source, GdkInputCondition cond) {
gint n;
gchar line[MAXLINE];
gchar cmd[MAXLINE];
gchar tmp[MAXLINE];
gint tsec;
gint ret;

	n = read(wav_out, line, MAXLINE);
	if (n < 0) {
		g_warning("read error from pipe\n");
		return;
	}
	if (n == 0) {
		/* ok, there is no longer a child */
		/* get return status of child */
		wait(&ret);
		close(wav_out);
		close(wav_in);
		stop_play();
		return;
	}
	line[n] = '\0';

	dodebug(10,"wavplay: %s", line);

	/* warning found - device busy? */
	if (strncmp(line,"\n**",3) == 0) {
		error_flag = 1;
		update_text(_("Error accessing DSP-device.\nBusy by another program?"));
		return;
	}

	strncpy(cmd,line,4);
	cmd[4] = '\0';
	tsec = atoi(line+4);
	
	if (strncmp(cmd,"secs",4) == 0) {
		/* start marker found */
		if (tsec == 0) {
			/* empty wav-file */
			tsec = 60; /* dummy value */
			gtk_button_clicked(GTK_BUTTON(wav_quit_button));
		}

		maxseconds = tsec;
		curseconds = 0;
	} else {
		curseconds = tsec;
		g_snprintf(tmp,MAXLINE,"%d:%02d",tsec/60,tsec%60);
		gtk_label_set_text(GTK_LABEL(timer_label),tmp);	
		
		/* toggle stop and play button */
		if (strncmp(cmd,"play",4) == 0) {
			gtk_signal_handler_block(GTK_OBJECT(playb),playhdl);
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(playb),1);
			gtk_signal_handler_unblock(GTK_OBJECT(playb),playhdl);
			gtk_signal_handler_block(GTK_OBJECT(stopb),stophdl);
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stopb),0);
			gtk_signal_handler_unblock(GTK_OBJECT(stopb),stophdl);
		} else {
			gtk_signal_handler_block(GTK_OBJECT(playb),playhdl);
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(playb),0);
			gtk_signal_handler_unblock(GTK_OBJECT(playb),playhdl);
			gtk_signal_handler_block(GTK_OBJECT(stopb),stophdl);
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stopb),1);
			gtk_signal_handler_unblock(GTK_OBJECT(stopb),stophdl);

			if (strncmp(cmd,"done",4) == 0) {
				/* end of track reached */
				/* simulate click on next button */
				gtk_button_clicked(GTK_BUTTON(nextb));
			} 
		}
	}
	
	draw_ticks(drawa);
}



/* create layout for wav-player */

static void wavmenu(GtkWidget *w, gint def_mix_val) {
GtkWidget *vb;
GtkWidget *text;
GtkWidget *tbl1, *tbl2;
GtkWidget *dr, *f1, *f2;
GtkWidget *b1, *b2, *b3, *b4, *b5, *b6;
GtkWidget *b1_xpm, *b2_xpm, *b3_xpm, *b4_xpm, *b5_xpm, *b6_xpm, *mix_xpm;
GdkPixmap *pmap;
GdkBitmap *mask;
GtkStyle *style;
GtkObject *adj;
GtkWidget *slider;

	vb = gtk_vbox_new(FALSE,5);
	gtk_container_set_border_width (GTK_CONTAINER(vb),10);
	gtk_container_add(GTK_CONTAINER(w),vb);
	gtk_widget_show(vb);

	text = gtk_text_new(NULL,NULL);
	wavplay_text = text;
	gtk_text_set_editable(GTK_TEXT(text),FALSE);
	gtk_text_set_word_wrap(GTK_TEXT(text),TRUE);
	gtk_widget_set_usize(text,0,tbf(40));
	gtk_box_pack_start(GTK_BOX(vb),text,FALSE,FALSE,0);
	gtk_widget_show(text);

	tbl1 = gtk_table_new (1,20,TRUE);
	gtk_table_set_col_spacings(GTK_TABLE(tbl1),5);
	gtk_box_pack_start(GTK_BOX(vb),tbl1,TRUE,TRUE,0);
	gtk_widget_show(tbl1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_table_attach_defaults(GTK_TABLE(tbl1),f1,0,17,0,1);
	gtk_widget_show(f1);

	dr = gtk_drawing_area_new();
	drawa = dr;
	gtk_widget_set_events (dr, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
	gtk_drawing_area_size(GTK_DRAWING_AREA(dr),0,32); 
	gtk_container_add(GTK_CONTAINER(f1),dr);
	gtk_widget_show(dr);

	gtk_signal_connect(GTK_OBJECT(dr), "expose_event",
		GTK_SIGNAL_FUNC(expose_event), NULL);
	gtk_signal_connect(GTK_OBJECT(dr), "configure_event",
		GTK_SIGNAL_FUNC(configure_event), NULL);
	gtk_signal_connect (GTK_OBJECT (dr), "button_press_event",
                      (GtkSignalFunc) button_press_event, NULL);

	f2 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f2),GTK_SHADOW_IN);
	gtk_table_attach_defaults(GTK_TABLE(tbl1),f2,17,20,0,1);
	gtk_widget_show(f2);

	timer_label = gtk_label_new("0:00");
	gtk_container_add(GTK_CONTAINER(f2), timer_label);
	gtk_widget_show(timer_label);
	
	tbl2 = gtk_table_new (1,20,TRUE);
	gtk_table_set_col_spacings(GTK_TABLE(tbl2),5);
	gtk_box_pack_start(GTK_BOX(vb),tbl2,FALSE,FALSE,0);
	gtk_widget_show(tbl2);

	gtk_widget_realize(tbl2);
	style = gtk_widget_get_style(w);

	b1 = gtk_toggle_button_new();
	playb = b1;
	gtk_table_attach_defaults(GTK_TABLE(tbl2),b1,0,2,0,1);
	gtk_widget_show(b1);
	playhdl = gtk_signal_connect (GTK_OBJECT (b1),"clicked",
		GTK_SIGNAL_FUNC(doplay),NULL);

	pmap = gdk_pixmap_create_from_xpm_d(w->window, &mask,
		&style->bg[GTK_STATE_NORMAL], (gchar **) snd_play);
	b1_xpm = gtk_pixmap_new(pmap,mask);

	gtk_container_add(GTK_CONTAINER(b1),b1_xpm);
	gtk_widget_show(b1_xpm);
	define_tooltip(b1, _("Play first or currently selected Track."));

	b2 = gtk_button_new();
	gtk_table_attach_defaults(GTK_TABLE(tbl2),b2,2,4,0,1);
	gtk_widget_show(b2);
	gtk_signal_connect (GTK_OBJECT (b2),"clicked",
		GTK_SIGNAL_FUNC(dopause),NULL);

	pmap = gdk_pixmap_create_from_xpm_d(w->window, &mask,
		&style->bg[GTK_STATE_NORMAL], (gchar **) snd_pause);
	b2_xpm = gtk_pixmap_new(pmap,mask);
	define_tooltip(b2, _("Pauses or continue playing."));

	gtk_container_add(GTK_CONTAINER(b2),b2_xpm);
	gtk_widget_show(b2_xpm);

	b3 = gtk_toggle_button_new();
	stopb = b3;
	gtk_table_attach_defaults(GTK_TABLE(tbl2),b3,4,6,0,1);
	gtk_widget_show(b3);
	stophdl = gtk_signal_connect (GTK_OBJECT (b3),"clicked",
		GTK_SIGNAL_FUNC(dostop),NULL);

	pmap = gdk_pixmap_create_from_xpm_d(w->window, &mask,
		&style->bg[GTK_STATE_NORMAL], (gchar **) snd_stop);
	b3_xpm = gtk_pixmap_new(pmap,mask);
	define_tooltip(b3, _("Stops playback."));

	gtk_container_add(GTK_CONTAINER(b3),b3_xpm);
	gtk_widget_show(b3_xpm);

	b4 = gtk_button_new();
	gtk_table_attach_defaults(GTK_TABLE(tbl2),b4,6,8,0,1);
	gtk_widget_show(b4);
	prevhdl = gtk_signal_connect (GTK_OBJECT (b4),"clicked",
		GTK_SIGNAL_FUNC(doprev),NULL);

	pmap = gdk_pixmap_create_from_xpm_d(w->window, &mask,
		&style->bg[GTK_STATE_NORMAL], (gchar **) snd_prev);
	b4_xpm = gtk_pixmap_new(pmap,mask);
	define_tooltip(b4, _("Begin to playback the previous track."));

	gtk_container_add(GTK_CONTAINER(b4),b4_xpm);
	gtk_widget_show(b4_xpm);

	b5 = gtk_button_new();
	nextb = b5;
	gtk_table_attach_defaults(GTK_TABLE(tbl2),b5,8,10,0,1);
	gtk_widget_show(b5);
	nexthdl = gtk_signal_connect (GTK_OBJECT (b5),"clicked",
		GTK_SIGNAL_FUNC(donext),NULL);

	pmap = gdk_pixmap_create_from_xpm_d(w->window, &mask,
		&style->bg[GTK_STATE_NORMAL], (gchar **) snd_next);
	b5_xpm = gtk_pixmap_new(pmap,mask);
	define_tooltip(b5, _("Begin to playback the next track."));

	gtk_container_add(GTK_CONTAINER(b5),b5_xpm);
	gtk_widget_show(b5_xpm);

	b6 = gtk_button_new();
	wav_quit_button = b6;
	gtk_table_attach_defaults(GTK_TABLE(tbl2),b6,10,12,0,1);
	gtk_widget_show(b6);
	gtk_signal_connect (GTK_OBJECT (b6),"clicked",
		GTK_SIGNAL_FUNC(doquit),NULL);

	pmap = gdk_pixmap_create_from_xpm_d(w->window, &mask,
		&style->bg[GTK_STATE_NORMAL], (gchar **) snd_quit);
	b6_xpm = gtk_pixmap_new(pmap,mask);
	define_tooltip(b6, _("Ends the playback completely."));

	gtk_container_add(GTK_CONTAINER(b6),b6_xpm);
	gtk_widget_show(b6_xpm);

	/* disable slide when mixer not working */
	if (def_mix_val == -1) {
		return;
	}

	/* only reached when we got a mixer */
	pmap = gdk_pixmap_create_from_xpm_d(w->window, &mask,
		&style->bg[GTK_STATE_NORMAL], (gchar **) snd_mixer);
	mix_xpm = gtk_pixmap_new(pmap,mask);
	gtk_table_attach_defaults(GTK_TABLE(tbl2),mix_xpm,14,15,0,1);
	gtk_widget_show(mix_xpm);

	adj = gtk_adjustment_new(0.0,0.0,101.0,1.0,1.0,1.0);
	slider = gtk_hscale_new(GTK_ADJUSTMENT(adj));
	gtk_scale_set_value_pos (GTK_SCALE(slider), GTK_POS_LEFT);
	gtk_scale_set_digits(GTK_SCALE(slider),0);
	gtk_scale_set_draw_value(GTK_SCALE(slider),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl2),slider,15,20,0,1);
	gtk_widget_show(slider);	
	gtk_signal_connect(GTK_OBJECT(adj), "value_changed",
		GTK_SIGNAL_FUNC(vol_changed), NULL);
	define_tooltip(slider, _("Change the volume of playback."));

	gtk_adjustment_set_value(GTK_ADJUSTMENT(adj), (gfloat) def_mix_val);
}


/* draw the wav-control-panel */

void wavplay_frontend(GtkWidget *widget) {
GtkWidget *f1;
gint mixval;

	maxseconds = 60; /* dummy value */
	maxpixels = 1;
	curseconds = 0;
	wav_in = -1; wav_out = -1;
	error_flag = 0;
	wavplay_quit = 0;

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_container_border_width(GTK_CONTAINER(f1),5);
	gtk_box_pack_start(GTK_BOX(widget),f1,FALSE,FALSE,0);

	mixval = query_mixer();
	wavmenu(f1,mixval);
	gtk_widget_show(f1);

	/* we need this so that the drawing area is updated */
	ptimer=gtk_timeout_add (100, draw_ticks, drawa); 
}

