/*
 *	wav_frontend.c
 *	4.6.99 tn
 *
 *
 *  Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
 *
 *  This file is part of xcdroast.
 *
 *  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.
 *
 *  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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

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

#include "largefile.h"

#include <locale.h>
#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, mixhdl;
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 gchar playing_track[MAXLINE];
static gboolean inpause;

static void read_wav_exit(GPid pid, gint status, gpointer data);
static gboolean read_wav_out(GIOChannel *source, GIOCondition cond, gpointer data);
static gint draw_ticks (gpointer data);


/*
 * updates the text-window
 */
static void update_text(gchar *txt) {
GtkTextBuffer *buffer;
GtkTextIter start, end;

	/* delete text-window first */
        buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(wavplay_text));
        gtk_text_buffer_get_bounds(buffer, &start, &end);
        gtk_text_buffer_delete(buffer, &start, &end);

	append_to_text_view(wavplay_text, txt);
}


/*
 * 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];
GIOChannel *gio;
GPid pid;

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

	/* have we got an audiodevice? */
	if (strcmp(setupdata.dsp_device,"") == 0) {
		update_text(_("Warning: No Audio-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 */
	pid = (GPid)full_dpl_pipe_shell(&wav_out,&wav_in,cmd);

	/* catch output of child */
        gio = g_io_channel_unix_new(wav_out);
        g_io_channel_set_encoding(gio, NULL, NULL);
        callback_tag = g_io_add_watch(gio, G_IO_IN,
                read_wav_out, NULL);

	/* check termination of child */
	g_child_watch_add(pid, read_wav_exit, (gpointer)gio);	
}


/*
 * 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 */
	g_source_remove(callback_tag);
	wav_out = -1;
	wav_in = -1;
	maxseconds = 60;
	maxpixels = 1;
	curseconds = 0;

	/* update screen */
	if (wavplay_quit == 0) 
		ptimer=g_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);
	}

    /* did we change the track selection? */
    if (strcmp(tmp, playing_track) != 0) {
        /* quit playing current track */
	    gtk_button_clicked(GTK_BUTTON(wav_quit_button));

	    /* now wait until we are really finished */
	    while (wav_in != -1) {
		    wait_and_process_events();
	    }
    } 
    
	/* got a valid selection? start play it */
	if (strcmp(tmp,"") != 0) {
		strncpy(playing_track, tmp, MAXLINE);
		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");
	}
    inpause = FALSE;
}

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");
	}
    inpause = FALSE;
}

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

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

    /* already paused? Toggle play */
    if (inpause) {
	    gtk_button_clicked(GTK_BUTTON(playb));
        return;
    }

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

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) {
		g_source_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 the wavplay child terminated
 */
static void read_wav_exit(GPid pid, gint status, gpointer data) {

	dodebug(10, "wavplay terminated with status: %d\n", status);

	/* cleanup */ 
	g_io_channel_unref((GIOChannel *)data);

    strcpy(playing_track, "");
	gtk_label_set_text(GTK_LABEL(timer_label),"0:00");	

	close(wav_out);
	close(wav_in);
	stop_play();
}

/*
 * called when new data from stdout of child is available
 */
static gboolean read_wav_out(GIOChannel *source, GIOCondition cond, gpointer data) {
gint n;
gchar line[MAXLINE];
gchar cmd[MAXLINE];
gchar tmp[MAXLINE];
gint tsec;

	n = read(wav_out, line, MAXLINE);
	if (n < 0) {
		g_warning("read error from pipe\n");
		return (FALSE);
	}
	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 Audio-device.\nBusy by another program?"));
		return (TRUE);
	}

	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);

	return (TRUE);
}



/*
 * 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_view_new();
	wavplay_text = text;
        gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
	gtk_widget_set_size_request(text, -1, 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_image_new_from_pixmap(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_image_new_from_pixmap(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_image_new_from_pixmap(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_image_new_from_pixmap(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_image_new_from_pixmap(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_image_new_from_pixmap(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_image_new_from_pixmap(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);	
	mixhdl = gtk_signal_connect(GTK_OBJECT(adj), "value_changed",
		GTK_SIGNAL_FUNC(vol_changed), NULL);
	define_tooltip(slider, _("Change the volume of playback."));

	gtk_signal_handler_block(GTK_OBJECT(adj), mixhdl);
	gtk_adjustment_set_value(GTK_ADJUSTMENT(adj), (gfloat) def_mix_val);
	gtk_signal_handler_unblock(GTK_OBJECT(adj), mixhdl);
}


/*
 * 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;
    inpause = FALSE;
    strcpy(playing_track, "");

	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=g_timeout_add (100, draw_ticks, drawa); 
}

