/*
 *	duplicate.c
 *
 *	Duplicate Disc functions
 *	15.5.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 <stdlib.h>
#include <string.h>
#include <strings.h>

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

#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "xcdrdata.h"
#include "xcdroast.h"
#include "main.h"
#include "../xpms/minidata.xpm"
#include "../xpms/miniaudio.xpm"
#include "../xpms/mininodata.xpm"
#include "../xpms/mininoaudio.xpm"
#include "../xpms/minitoc.xpm"
#include "../xpms/disc_eject.xpm"
#include "../xpms/disc_load.xpm"

extern GtkWidget *toplevel;
extern GtkWidget *sidespace;
extern GtkWidget *workspace;

extern GList *imagelist;
extern writerreader_devices_t **writerreaderdevs;
extern track_read_set_t trackreadset;
extern GList *tocfiles;
extern setup_data_t setupdata;
extern current_set_t curset;
extern cd_info_t cdinfo;
extern track_info_t **trackinfo;
extern gint wav_in;
extern GtkWidget *wav_quit_button;
extern gint wavplay_quit;
extern gint submenu;
extern gchar sharedir[MAXLINE];
extern img_logo_t img;

GtkWidget *actionspace;
GtkCList *cdlist, *imglist, *play_clist;
GtkWidget *cdlist_l1, *cdlist_l2, *cdlist_l3, *cdlist_l4;
GtkWidget *vrylist_l1, *vrylist_l2, *vrylist_l3, *vrylist_l4;
GtkWidget *imglist_l1, *imglist_l2, *imglist_l3;
GtkWidget *dupl_cd_mode_omenu, *crea_cd_mode_omenu, *crea_cd_burnfree_check, *crea_cd_nofixate_check;
guint side_handlers2[8];
GtkWidget *side_widgets2[8];

static GtkWidget *write_toc_menu;
static GtkWidget *edit_cdtext_btn;
static GtkWidget *dupl_cd_burnfree_check;
static GtkWidget *rdr_spd_spin, *cdr_spd_spin;

/*
 * some stuff for the select-functions of the sidebar buttons
 */
static guint side_handlers[7];
static GtkWidget *side_widgets[7];
static GtkWidget *locked_button;

extern void fill_read_tracks(gint dontupdatecd);
extern void fill_verify_tracks(gint dontupdateimglist);
extern void fill_write_tracks();
extern void fill_master_write_menu();
extern void reset_duplicate_buttons2(GtkWidget *exclude, gint fromunlock);

static void reset_duplicate_buttons(GtkWidget *exclude);
static void fill_read_menu();
static void fill_verify_menu();
static void fill_write_menu();
static void fill_delete_menu();
static void tocwrite_selected(GtkWidget *item, gpointer val);
void set_image_prefix_callback(GtkWidget *widget, gpointer data);


/*
 * lock complete sidebar when doing stuff that takes a while (e.g. reload)
 */
void do_lock(gint plusgrab) {
int i;

	if (submenu == 1) {
		/* lock all and save currently selected button */
		for (i = 0; i < 7; i++) {
			gtk_signal_handler_block(GTK_OBJECT(side_widgets[i]),
				side_handlers[i]);
			if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
				side_widgets[i])) == 1) {
				locked_button = side_widgets[i];
			}
		}
	}
	if (submenu == 2) {
		/* lock all and save currently selected button */
		for (i = 0; i < 8; i++) {
			gtk_signal_handler_block(GTK_OBJECT(side_widgets2[i]),
				side_handlers2[i]);
			if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
				side_widgets2[i])) == 1) {
				locked_button = side_widgets2[i];
			}
		}
	}

	/* grab the button, so everything else is not active */
	if (plusgrab) {
		gtk_grab_add(locked_button);
	}
}


/*
 * free the lock after we are done
 */
void do_unlock(gint plusgrab) {
int i;

	if (plusgrab) {
		gtk_grab_remove(locked_button);
	}

	if (submenu == 1) {
		for (i = 0; i < 7; i++) {
			gtk_signal_handler_unblock(GTK_OBJECT(side_widgets[i]),
				side_handlers[i]);
		}
		reset_duplicate_buttons(locked_button);
	}
	if (submenu == 2) {
		for (i = 0; i < 8; i++) {
			gtk_signal_handler_unblock(GTK_OBJECT(side_widgets2[i]),
				side_handlers2[i]);
		}
		reset_duplicate_buttons2(locked_button, 1);
	}
}


/*
 * fill the disc-info-list with data
 */
void fill_cdlist() {
GtkStyle *style;
gchar *data[2];
GdkPixmap *pixmap1, *pixmap2;
GdkBitmap *mask1, *mask2;
gint i, lcount, disc_type;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];

	/* clean up first */
	gtk_clist_clear(cdlist);

	/* disc loaded? */
	if (cdinfo.nr_tracks == -1) {
		gtk_entry_set_text(GTK_ENTRY(cdlist_l1), _("No Disc loaded"));	
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2),"");	
		gtk_entry_set_text(GTK_ENTRY(cdlist_l3),"");	
		return;
	}
	if (cdinfo.nr_tracks == -2) {
		gtk_entry_set_text(GTK_ENTRY(cdlist_l1), return_media_type(curset.reader_devnr));	
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2),"");	
		gtk_entry_set_text(GTK_ENTRY(cdlist_l3),"");	
		return;
	}

	style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(cdlist)));
	pixmap1 = gdk_pixmap_create_from_xpm_d(cdlist->clist_window,
		&mask1, &style->bg[GTK_STATE_NORMAL],(gchar **)minidata_xpm);
	pixmap2 = gdk_pixmap_create_from_xpm_d(cdlist->clist_window,
		&mask2, &style->bg[GTK_STATE_NORMAL],(gchar **)miniaudio_xpm);

	data[0] = NULL;
	lcount = 0;

	for (i = 0; i < cdinfo.nr_tracks; i++) {
		if (trackinfo[i]->type == 0) {
			convert_frames2mbstring(trackinfo[i]->size,tmp2);
			g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
				trackinfo[i]->track_nr,
				_("data track"), tmp2);
			data[1] = convert_for_gtk2(tmp);
			gtk_clist_append(cdlist,data);
			gtk_clist_set_pixmap(cdlist,lcount,0,pixmap1,mask1);
			lcount++;
		} else {
			convert_frames2minstring(trackinfo[i]->size,tmp2);
			g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
				trackinfo[i]->track_nr,
				_("audio track"), tmp2);
			data[1] = convert_for_gtk2(tmp);
			gtk_clist_append(cdlist,data);
			gtk_clist_set_pixmap(cdlist,lcount,0,pixmap2,mask2);
			lcount++;
		}

		/* we have cd-text for this track? */
		if (setupdata.option_displaycdtext) {
			if (trackinfo[i]->title != NULL && 
			    trackinfo[i]->title[0] != '\0' ) {
				g_snprintf(tmp,MAXLINE,"  CD-Text: %s", 
					trackinfo[i]->title);
				data[1] = convert_for_gtk2(tmp);
				gtk_clist_append(cdlist,data);
				set_clist_row_font(cdlist,lcount, PANGO_ITALIC);
				lcount++;
			}
		}

		/* have we a cddb-title for this track? */
		if (trackinfo[i]->cddb_ttitle != NULL) {
			g_snprintf(tmp,MAXLINE,"     CDDB: %s", 
				trackinfo[i]->cddb_ttitle);
			data[1] = convert_for_gtk2(tmp);
			gtk_clist_append(cdlist,data);
			set_clist_row_font(cdlist,lcount, PANGO_ITALIC);
			lcount++;	
		} else
		if (trackinfo[i]->volname != NULL) {
			convert_kbytes2mbstring(trackinfo[i]->isosize*2,tmp2);
			g_snprintf(tmp,MAXLINE,"     ISO9660: %s [%s]", 
				trackinfo[i]->volname,tmp2);
			data[1] = convert_for_gtk2(tmp);
			gtk_clist_append(cdlist,data);
			set_clist_row_font(cdlist,lcount, PANGO_ITALIC);
			lcount++;	
		} 

	}

	/* get and display disc type */
	disc_type = determine_disc_type(tmp,0);
	gtk_entry_set_text(GTK_ENTRY(cdlist_l1), tmp);	

	/* display CD label */
	if (cdinfo.title && cdinfo.artist && 
		cdinfo.title[0] != '\0' && setupdata.option_displaycdtext) {
		g_snprintf(tmp,MAXLINE,"%s / %s", cdinfo.title, cdinfo.artist);
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2), tmp);
		gtk_entry_set_position(GTK_ENTRY(cdlist_l2),0);
	} else 
	if (cdinfo.cddb_dtitle != NULL) {
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2), cdinfo.cddb_dtitle);	
		gtk_entry_set_position(GTK_ENTRY(cdlist_l2),0);
	} else {
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2),"");	
	}

	/* display disc size */
	if (disc_type == 1 || disc_type == 2) { /* Audio or Mixed Mode CD */
		convert_frames2mbminstring(cdinfo.total_size, tmp);
	} else {                        /* Data CD/DVD/BD and CD Extra */
		convert_sectors2mbminstring(cdinfo.total_size, tmp);
	}
	gtk_entry_set_text(GTK_ENTRY(cdlist_l3), tmp);	
}


/*
 * fill the image-info-list with data
 */
void fill_imglist() {
GtkStyle *style;
gchar *data[2];
GdkPixmap *pixmap1, *pixmap2, *pixmap3, *pixmap4, *pixmap5;
GdkBitmap *mask1, *mask2, *mask3, *mask4, *mask5;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar basename[MAXLINE], oldbase[MAXLINE], fname[MAXLINE], *p;
GList *loop;
image_files_t *entry;
gint lcount, count;
gint sizecount;

	/* clean up first */
	gtk_clist_clear(imglist);

	style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(imglist)));
	pixmap1 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
		&mask1, &style->bg[GTK_STATE_NORMAL],(gchar **)minidata_xpm);
	pixmap2 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
		&mask2, &style->bg[GTK_STATE_NORMAL],(gchar **)miniaudio_xpm);
	pixmap3 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
		&mask3, &style->bg[GTK_STATE_NORMAL],(gchar **)mininodata_xpm);
	pixmap4 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
		&mask4, &style->bg[GTK_STATE_NORMAL],(gchar **)mininoaudio_xpm);
	pixmap5 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
		&mask5, &style->bg[GTK_STATE_NORMAL],(gchar **)minitoc_xpm);

	data[0] = NULL;
	strcpy(oldbase,"");
	lcount = 0;
	count = 1;
	sizecount = 0;

	loop = g_list_first(imagelist);
	while (loop) {
		entry = loop->data;

		/* get the base-dirname */
		strncpy(basename,entry->path,MAXLINE);	
		p = rindex(basename,'/');
		*p = '\0';
		if (strcmp(basename,"") == 0) {
			strcpy(basename,"/");
		}
		strcpy(fname,p+1);

		/* new path found? */
		if (strcmp(basename,oldbase) != 0) {
			g_snprintf(tmp,MAXLINE,"%s: %s",_("Path"), basename);
			data[1] = convert_for_gtk2(tmp);
			gtk_clist_append(imglist,data);
			set_clist_row_font(imglist,lcount, PANGO_BOLD);
			lcount++;
			strcpy(oldbase,basename);
		}

		/* iso9600-track/ unknown  */
		if (entry->type == 0 || entry->type == 3) {
			convert_frames2mbstring((gint)((off_t)entry->size/DATASECTORSIZE),
				tmp2);
			g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
				count, fname, tmp2);
			data[1] = convert_for_gtk2(tmp);
			gtk_clist_append(imglist,data);
			if (entry->readable == 1 && entry->type == 0) {
				gtk_clist_set_pixmap(imglist,lcount,0,pixmap1,mask1);	
			} else {
				gtk_clist_set_pixmap(imglist,lcount,0,pixmap3,mask3);	
			}
			lcount++;
			sizecount+=(gint)((off_t)entry->size >> 10);
			count++;
		}

		/* valid/invalid wav-file */
		if (entry->type == 1 || entry->type == 2) {
			convert_frames2minstring((gint)((off_t)entry->size/CDDAFRAME), tmp2);
			g_snprintf(tmp,MAXLINE,"%2d. %s [%s]",
				count, fname, tmp2);
			data[1] = convert_for_gtk2(tmp);
			gtk_clist_append(imglist,data);
			if (entry->readable == 1 && entry->type == 1) {
				gtk_clist_set_pixmap(imglist,lcount,0,pixmap2,mask2);	
			} else {
				gtk_clist_set_pixmap(imglist,lcount,0,pixmap4,mask4);	
			}
			lcount++;
			sizecount+=(gint)((off_t)entry->size >> 10);
			count++;
		}	

		/* toc-file */
		if (entry->type == 4) {
			g_snprintf(tmp,MAXLINE,"--. %s",fname);
			data[1] = convert_for_gtk2(tmp);
			gtk_clist_append(imglist,data);
			gtk_clist_set_pixmap(imglist,lcount,0,pixmap5, mask5);
			lcount++;
		}

		/* cd-text */
		if (entry->title && entry->artist && 
		    strcmp(entry->title,"") && strcmp(entry->artist,"")) {
			g_snprintf(tmp,MAXLINE,"     (%s / %s)",
				entry->title, entry->artist);
			data[1] = convert_for_gtk2(tmp);
			gtk_clist_append(imglist,data);
			set_clist_row_font(imglist,lcount, PANGO_ITALIC);
			lcount++;	
		} else 
		if (entry->title && strcmp(entry->title,"")) {
			g_snprintf(tmp,MAXLINE,"     (%s)",
				entry->title);
			data[1] = convert_for_gtk2(tmp);
			gtk_clist_append(imglist,data);
			set_clist_row_font(imglist,lcount, PANGO_ITALIC);
			lcount++;	
		} else 
		if (entry->cddb_ttitle && strcmp(entry->cddb_ttitle,"")) {
			g_snprintf(tmp,MAXLINE,"     (%s)",
				entry->cddb_ttitle);
			data[1] = convert_for_gtk2(tmp);
			gtk_clist_append(imglist,data);
			set_clist_row_font(imglist,lcount, PANGO_ITALIC);
			lcount++;	
		} else 
		if (entry->volname && strcmp(entry->volname,"")) {
			if (entry->next_session_start > 0) {
				g_snprintf(tmp,MAXLINE,
					"     (%s / ISO9660-multisession)",
					entry->volname);
			} else {
				g_snprintf(tmp,MAXLINE,"     (%s / ISO9660)",
					entry->volname);
			}
			data[1] = convert_for_gtk2(tmp);
			gtk_clist_append(imglist,data);
			set_clist_row_font(imglist,lcount, PANGO_ITALIC);
			lcount++;	
		} else 
		if (entry->type == 0 && entry->next_session_start > 0) {
			strcpy(tmp,"     (ISO9660-multisession)"); 
			data[1] = convert_for_gtk2(tmp);
			gtk_clist_append(imglist,data);
			set_clist_row_font(imglist,lcount, PANGO_ITALIC);
			lcount++;	
		}

		loop = loop->next;
	}

	/* total size of files */
	convert_kbytes2mbminstring(sizecount, tmp);
	gtk_entry_set_text(GTK_ENTRY(imglist_l1), tmp);	
}


/*
 * callbacks for button in info-screen
 */
static void cddb_clicked(GtkWidget *widget, gpointer data) {

	/* no disc loaded */
	if (cdinfo.nr_tracks < 0) {
		show_dialog(ICO_WARN,_("No Disc loaded in read device."),T_OK,NULL,NULL,0);
		return;
	}

	if (show_cddb_query(NULL, 0) == 0) {
		/* new data received - update display */
		fill_cdlist();
	}
}

void edit_cdtext_clicked(GtkWidget *widget, gpointer data) {
gint mode;

	mode = GPOINTER_TO_INT(data);

	if (mode == 0) 
		show_edit_cdtext(mode, NULL);
	else if (mode == 1) {
		if (strcmp(curset.tocfile,"-") == 0) {
			/* on-the-fly setting? */
			show_edit_cdtext(3, write_toc_menu);
		} else {
			show_edit_cdtext(1, write_toc_menu);
		}
	}
	else if (mode == 2) 
		show_edit_cdtext(mode, NULL);
}


static void update_clicked(GtkWidget *widget, gpointer data) {
GdkCursor *cursor;

	do_lock(1);
	/* change cursor to watch */
	cursor = gdk_cursor_new(GDK_WATCH);
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);

	while (gtk_events_pending())
		gtk_main_iteration();

	if (curset.reader_devnr != -1) {
		get_cd_toc_and_volid(curset.reader_devnr);
		fill_cdlist();
	}
	scan_imagedirs();
	fill_imglist();

	/* reset cursor */
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
	gdk_cursor_destroy (cursor);
	do_unlock(1);

}

/*
 * the update-button in the read menu
 */
static void update_readvrfy_clicked(GtkWidget *widget, gpointer read) {
GdkCursor *cursor;
gint isread;

	isread = GPOINTER_TO_INT(read);

	do_lock(1);
	/* change cursor to watch */
	cursor = gdk_cursor_new(GDK_WATCH);
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);

	while (gtk_events_pending())
		gtk_main_iteration();

	if (curset.reader_devnr != -1) {
		get_cd_toc_and_volid(curset.reader_devnr);
	}
	if (isread) {
		fill_read_menu();
	} else {
		fill_verify_menu();
	}
	/* reset cursor */
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
	gdk_cursor_destroy (cursor);
	do_unlock(1);
}


static void eject_clicked(GtkWidget *widget, gpointer load) {
GdkCursor *cursor;

	do_lock(1);
	/* change cursor to watch */
	cursor = gdk_cursor_new(GDK_WATCH);
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);

	while (gtk_events_pending())
		gtk_main_iteration();

	if (curset.reader_devnr != -1) {
		if (GPOINTER_TO_INT(load)) 
			load_cd(curset.reader_devnr);
		else
			eject_cd(curset.reader_devnr);
	}

	/* reset cursor */
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
	gdk_cursor_destroy (cursor);

	/*
	 * After we ejected or loaded automatically then update screen.
	 * In which menu are we right now?
	 * Info menu?
	 */
	if (submenu == 1 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets[0])) == 1) {
		update_clicked(widget,0);
	}
	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[0])) == 1) {
		update_clicked(widget,0);
	}
	do_unlock(1);
}


/*
 * callbacks for devices_setup_read
 */
static void readdev_selected(GtkWidget *item, gpointer devnr) {
GdkCursor *cursor;
gint i;

	do_lock(1);
	/* change cursor to watch */
	cursor = gdk_cursor_new(GDK_WATCH);
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);

	while (gtk_events_pending())
		gtk_main_iteration();

	curset.reader_devnr = GPOINTER_TO_INT(devnr);
	i = get_writerreaderdevs_index(curset.reader_devnr);

	/* update speed display */
	if (rdr_spd_spin) {
		gtk_spin_button_set_value(GTK_SPIN_BUTTON(rdr_spd_spin),
			(gfloat)writerreaderdevs[i]->audioread_speed);
	}
	if (curset.reader_devnr != -1) {
		get_cd_toc_and_volid(curset.reader_devnr);
	}

	/*
	 * In which menu are we right now?
	 * Info menu?
	 */
	if (submenu == 1 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets[0])) == 1) {
		fill_cdlist();
	}
	/* info menu 2? */
	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[0])) == 1) {
		fill_cdlist();
	}
	/* read menu? */
	if (submenu == 1 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets[1])) == 1) {
		fill_read_menu();
	}
	/* read menu 2? */
	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[1])) == 1) {
		fill_read_tracks(0);
	}
	/* verify menu? */
	if (submenu == 1 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets[2])) == 1) {
		fill_verify_menu();
	}
	/* verify menu2? */
	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[2])) == 1) {
		fill_verify_tracks(1);
	}
	/* write menu? */
	if (submenu == 1 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets[4])) == 1) {
		fill_write_menu();
	}
	/* write menu2? */
	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[5])) == 1) {
		fill_write_tracks();
	}

	/* reset cursor */
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
	gdk_cursor_destroy (cursor);
	do_unlock(1);
}


static void readdev_speed(GtkWidget *item, GtkSpinButton *spin) {
gint i;

	i = get_writerreaderdevs_index(curset.reader_devnr);
	writerreaderdevs[i]->audioread_speed = gtk_spin_button_get_value_as_int(spin);
}


/*
 * draw the device-setup-read line
 */
void devices_setup_read(gint row, GtkWidget *tbl, gint showspeed) {
GtkWidget *omenu;
GtkWidget *menu;
GtkWidget *menu_item;
GtkWidget *l1;
GtkWidget *eject_btn, *eject_xpm;
GtkWidget *load_btn, *load_xpm;
GdkPixmap *pmap;
GdkBitmap *mask;
GtkStyle *style;
gchar tmp[MAXLINE];
GtkWidget *speed1;
GtkObject *adj;
gint menuidx, menuhistory;
gint i;
	
	rdr_spd_spin = NULL;

	/* no reader so far selected? set default primary reader */
	if (curset.reader_devnr == -1) {
		curset.reader_devnr = setupdata.reader_devnr;
	}	

	/* device still valid? */
	if (get_writerreaderdevs_index(curset.reader_devnr) == -1) {
		/* invalid device, pick the first available instead */
		if (writerreaderdevs[0]) {
			curset.reader_devnr = writerreaderdevs[0]->devnr;
		}
	}

	/* read device */
	l1 = rightjust_gtk_label_new(_("Read Device:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4*4,row,row+1);
	gtk_widget_show(l1);

	omenu = gtk_option_menu_new ();
	menu = gtk_menu_new();
	menuidx = 0; menuhistory = -1;
	i = 0;

	while(writerreaderdevs[i] != NULL) {
		if (convert_devnr2devstring(writerreaderdevs[i]->devnr,tmp) == 0) {
                        menu_item = gtk_menu_item_new_with_label(tmp);
                        gtk_signal_connect(GTK_OBJECT(menu_item),
                                "activate", GTK_SIGNAL_FUNC(readdev_selected),
                                GINT_TO_POINTER(writerreaderdevs[i]->devnr));
	                gtk_menu_append (GTK_MENU (menu), menu_item);

                        if (curset.reader_devnr == writerreaderdevs[i]->devnr) { menuhistory = menuidx; }
                        menuidx++;
                        gtk_widget_show (menu_item);
                }
                i++;
        }

	gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
	if (menuhistory != -1) {
		gtk_option_menu_set_history(GTK_OPTION_MENU (omenu), menuhistory);
	} else {
		/*
		 * if we are here we have an invalid reader setting
		 * set to default
		 */
		curset.reader_devnr = setupdata.reader_devnr;
		gtk_option_menu_set_history(GTK_OPTION_MENU (omenu), 0);
	}
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,4*4,12*4,row,row+1);
	gtk_widget_show(omenu);
	define_tooltip(omenu, _("Select the device you want use now for all read-operations on Discs."));

	if (showspeed) { 
		l1 = rightjust_gtk_label_new(_("Speed:"));
		gtk_table_attach_defaults(GTK_TABLE(tbl),l1,12*4,15*4-1,row,row+1);
		gtk_widget_show(l1);

		adj = gtk_adjustment_new(0.0,0.0,64.0,1.0,1.0,0.0);
		speed1 = gtk_spin_button_new(GTK_ADJUSTMENT(adj),0,0);
		rdr_spd_spin = speed1; 
		gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
			GTK_SIGNAL_FUNC (readdev_speed),speed1);
		gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(speed1),1);
		gtk_table_attach_defaults(GTK_TABLE(tbl),speed1,15*4-1,16*4,row,row+1);
		i = get_writerreaderdevs_index(curset.reader_devnr);
		if (i >= 0) {
			gtk_spin_button_set_value(GTK_SPIN_BUTTON(speed1),
				(gfloat)writerreaderdevs[i]->audioread_speed);
		} else {
                	gtk_widget_set_sensitive(speed1,FALSE);
		}
		gtk_widget_show(speed1);
		define_tooltip(speed1, _("Select the speed which should be used for audio-extraction."));

        	if (!isroot() && !setupdata.root_option_change_readparam) {
                	gtk_widget_set_sensitive(speed1,FALSE);
		}
	} else {
		/* if not showing speed, show eject/load buttons */
		gtk_widget_realize(tbl);
		style = gtk_widget_get_style(tbl);

		pmap = gdk_pixmap_create_from_xpm_d(tbl->window, &mask,
			&style->bg[GTK_STATE_NORMAL], (gchar **) disc_eject);
		eject_xpm = gtk_image_new_from_pixmap(pmap,mask);
		eject_btn = gtk_button_new();
		gtk_signal_connect (GTK_OBJECT (eject_btn), "clicked",
			GTK_SIGNAL_FUNC (eject_clicked), GINT_TO_POINTER(0));
		gtk_table_attach_defaults(GTK_TABLE(tbl),eject_btn,
			14*4,15*4,row,row+1);
		gtk_widget_show(eject_btn);
		gtk_container_add(GTK_CONTAINER(eject_btn), eject_xpm);
		gtk_widget_show(eject_xpm);
		define_tooltip(eject_btn, _("Ejects a Disc from this device."));

		pmap = gdk_pixmap_create_from_xpm_d(tbl->window, &mask,
			&style->bg[GTK_STATE_NORMAL], (gchar **) disc_load);
		load_xpm = gtk_image_new_from_pixmap(pmap,mask);
		load_btn = gtk_button_new();
		gtk_signal_connect (GTK_OBJECT (load_btn), "clicked",
			GTK_SIGNAL_FUNC (eject_clicked), GINT_TO_POINTER(1));
		gtk_table_attach_defaults(GTK_TABLE(tbl),load_btn,
			15*4,16*4,row,row+1);
		gtk_widget_show(load_btn);
		gtk_container_add(GTK_CONTAINER(load_btn), load_xpm);
		gtk_widget_show(load_xpm);
		define_tooltip(load_btn, _("Loads a Disc in this device."));
	}
}


static void imagedir_selected(GtkWidget *item, gpointer val) {
GdkCursor *cursor;

	do_lock(1);
	/* change cursor to watch */
	cursor = gdk_cursor_new(GDK_WATCH);
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);

	while (gtk_events_pending())
		gtk_main_iteration();

	curset.image_index = GPOINTER_TO_INT(val);

	/* which sub-menu are we in? */
	/* read menu? */
	if (submenu == 1 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets[1])) == 1) {
		fill_read_menu();
	}
	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[1])) == 1) {
		fill_read_tracks(1);
	}
	/* verify menu? */
	if (submenu == 1 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets[2])) == 1) {
		fill_verify_menu();
	}
	/* verify menu2? */
	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[2])) == 1) {
		fill_verify_tracks(0);
	}
	/* write menu? */
	if (submenu == 1 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets[4])) == 1) {
		fill_write_menu();
	}
	/* write menu2? */
	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[5])) == 1) {
		fill_write_tracks();
	}
	/* delete menu? */
	if (submenu == 1 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets[5])) == 1) {
		fill_delete_menu();
	}
	/* delete menu2? */
	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[6])) == 1) {
		fill_delete_menu();
	}
	/* master menu */
	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[4])) == 1) {
		fill_master_write_menu();
	}
	/* reset cursor */
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
	gdk_cursor_destroy (cursor);
	do_unlock(1);
}


/*
 * draw the device-setup-image line
 */
void devices_setup_image(gint row, GtkWidget *tbl) {
GtkWidget *omenu;
GtkWidget *menu;
GtkWidget *menu_item;
GtkWidget *l1;
GList *loop;
gchar tmp[MAXLINE];
gint i, menuidx, menuhistory;

	/* default curset.image_index is -1...so we are fine here */

	/* image directory */
	l1 = rightjust_gtk_label_new(_("Image Directory:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4*4,row,row+1);
	gtk_widget_show(l1);

	omenu = gtk_option_menu_new ();
	menu = gtk_menu_new();

	/* automatic setting */
	menuidx = 0; menuhistory = -1;
	menu_item = gtk_menu_item_new_with_label(_("Automatic"));
	gtk_signal_connect(GTK_OBJECT(menu_item),
		"activate", GTK_SIGNAL_FUNC(imagedir_selected),
		GINT_TO_POINTER(-1));
	gtk_menu_append (GTK_MENU (menu), menu_item);
	if (curset.image_index == -1) { menuhistory = menuidx; }
	menuidx++;
	gtk_widget_show (menu_item);

	/* add image dirs */
	i = 0;
	loop = g_list_first(setupdata.image_dirs);
	while(loop) {
		strcpy(tmp,(gchar *)loop->data);

		menu_item = gtk_menu_item_new_with_label(tmp);
		gtk_signal_connect(GTK_OBJECT(menu_item),
			"activate", GTK_SIGNAL_FUNC(imagedir_selected),
			GINT_TO_POINTER(i));
		gtk_menu_append (GTK_MENU (menu), menu_item);
		if (curset.image_index == i) { menuhistory = menuidx; }
		menuidx++;
		gtk_widget_show (menu_item);

		loop = loop->next;
		i++;
	}

	gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
	if (menuhistory != -1) {
		gtk_option_menu_set_history(GTK_OPTION_MENU (omenu),menuhistory);
	} else {
		/* looks we got an invalid setting...set to default */
		curset.image_index = -1;
		gtk_option_menu_set_history(GTK_OPTION_MENU (omenu),0);

	}
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,4*4,12*4,row,row+1);
	gtk_widget_show(omenu);
	define_tooltip(omenu, _("The directory on the hard disk you want to store/read tracks from. The setting \"Automatic\" selects all available directories at once."));
}


/*
 * configure an option menu with write modes for a given device
 */
void preselect_write_mode_menu(GtkWidget *omenu, gint devnr) {
gint i,j;
GtkMenuShell *menu_shell;
GtkWidget *menuitem;
GList *loop;

	i = get_writerreaderdevs_index(devnr);

	if (i == -1) {
                gtk_widget_set_sensitive(omenu, FALSE);
		return;
	}

	/* set write mode and update possible settings */
	gtk_option_menu_set_history(GTK_OPTION_MENU (omenu),
        	writerreaderdevs[i]->writer_mode);
        menu_shell = GTK_MENU_SHELL(GTK_OPTION_MENU (omenu)->menu);

        /* loop through all given menu entries */
        j = 0;
       	loop = g_list_first(menu_shell->children);
       	while(loop) {
               	menuitem = loop->data;  
              	if (!writemode_supported(j, devnr)) {
                       	gtk_widget_set_sensitive(menuitem, FALSE);
               	} else {
                       	gtk_widget_set_sensitive(menuitem, TRUE);
               	}
               	j++;
               	loop = loop->next;
      	}               
}


/*
 * callbacks for devices_setup_write
 */
static void writedev_selected(GtkWidget *item, gpointer devnr) {
GdkCursor *cursor;
gint i;

	do_lock(1);
	/* change cursor to watch */
	cursor = gdk_cursor_new(GDK_WATCH);
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);

	while (gtk_events_pending())
		gtk_main_iteration();

        curset.writer_devnr = GPOINTER_TO_INT(devnr);
        i = get_writerreaderdevs_index(curset.writer_devnr);

        /* update speed display */
        if (cdr_spd_spin) {
                gtk_spin_button_set_value(GTK_SPIN_BUTTON(cdr_spd_spin),
                        (gfloat)writerreaderdevs[i]->writer_speed);
        }

	/* update any writer specific stuff for a given menu */

	/* write menu? */
	if (submenu == 1 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets[4])) == 1) {
		if (dupl_cd_mode_omenu) {
			preselect_write_mode_menu(dupl_cd_mode_omenu, 
				curset.writer_devnr);
		}
		if (dupl_cd_burnfree_check) {
			if (!does_support_burnproof(curset.writer_devnr)) {
                		gtk_widget_set_sensitive(dupl_cd_burnfree_check,FALSE);
			} else {
                		gtk_widget_set_sensitive(dupl_cd_burnfree_check,TRUE);
			}
		}  
	}

	/* write menu2? */
	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[5])) == 1) {
		if (crea_cd_mode_omenu) {
			preselect_write_mode_menu(crea_cd_mode_omenu, 
				curset.writer_devnr);
		}
		if (crea_cd_burnfree_check) {
			if (!does_support_burnproof(curset.writer_devnr)) {
                		gtk_widget_set_sensitive(crea_cd_burnfree_check,FALSE);
			} else {
                		gtk_widget_set_sensitive(crea_cd_burnfree_check,TRUE);
			}
		}
	}

	/* master menu */
	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[4])) == 1) {
		if (crea_cd_mode_omenu) {
			preselect_write_mode_menu(crea_cd_mode_omenu, 
				curset.writer_devnr);
		}
		if (crea_cd_burnfree_check) {
			if (!does_support_burnproof(curset.writer_devnr)) {
                		gtk_widget_set_sensitive(crea_cd_burnfree_check,FALSE);
			} else {
                		gtk_widget_set_sensitive(crea_cd_burnfree_check,TRUE);
			}
		}
	}

	/* reset cursor */
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
	gdk_cursor_destroy (cursor);
	do_unlock(1);
}


static void writedev_speed(GtkWidget *item, GtkSpinButton *spin) {
gint i;

	i = get_writerreaderdevs_index(curset.writer_devnr);
        writerreaderdevs[i]->writer_speed = gtk_spin_button_get_value_as_int(spin);
}


/*
 * draw the device-setup-write line
 */
void devices_setup_write(gint row, GtkWidget *tbl) {
GtkWidget *omenu;
GtkWidget *menu;
GtkWidget *menu_item;
GtkWidget *l1;
GtkWidget *speed1;
GtkObject *adj;
gint menuidx, menuhistory;
gchar tmp[MAXLINE];
gint i;

	cdr_spd_spin = NULL;

	/* select primary writer */
	if (curset.writer_devnr == -1) {
		curset.writer_devnr = setupdata.writer_devnr;
	}

	/* device still valid? */
	if (get_writerreaderdevs_index(curset.writer_devnr) == -1) {
		/* invalid device, pick the first available instead */
		i = 0;
		while(writerreaderdevs[i] != NULL) {
       	         	if (writerreaderdevs[i]->is_cdrwriter ||
                    	    writerreaderdevs[i]->is_dvdwriter) {
	
				curset.writer_devnr = writerreaderdevs[i]->devnr;
				break;
			}
			i++;
		}
	}
	
	/* write device */
	l1 = rightjust_gtk_label_new(_("Write Device:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4*4,row,row+1);
	gtk_widget_show(l1);

	omenu = gtk_option_menu_new ();
	menu = gtk_menu_new();
	menuidx = 0; menuhistory = -1;
	i = 0;

	while(writerreaderdevs[i] != NULL) {

                /* only show writers here */
                if (writerreaderdevs[i]->is_cdrwriter ||
                    writerreaderdevs[i]->is_dvdwriter) {

                        if (convert_devnr2devstring(writerreaderdevs[i]->devnr,tmp) == 0) {
                                menu_item = gtk_menu_item_new_with_label(tmp);
                                gtk_signal_connect(GTK_OBJECT(menu_item),
                                        "activate", GTK_SIGNAL_FUNC(writedev_selected),
                                        GINT_TO_POINTER(writerreaderdevs[i]->devnr));
                                gtk_menu_append (GTK_MENU (menu), menu_item);
                                if (curset.writer_devnr == writerreaderdevs[i]->devnr) { menuhistory = menuidx; }
                                menuidx++;
                                gtk_widget_show (menu_item);
                        }
                }
                i++;
        }

	gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
        if (menuhistory != -1) {
                gtk_option_menu_set_history(GTK_OPTION_MENU (omenu),menuhistory);
        } else {
                /* nothing valid preselected */
                curset.writer_devnr = setupdata.writer_devnr;
                gtk_option_menu_set_history(GTK_OPTION_MENU (omenu), 0);
        }
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,4*4,12*4,row,row+1);
	gtk_widget_show(omenu);
	define_tooltip(omenu, _("The Writer you want to use now to burn your Discs."));

	l1 = rightjust_gtk_label_new(_("Speed:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,12*4,15*4-1,row,row+1);
	gtk_widget_show(l1);

	adj = gtk_adjustment_new(0.0,0.0,64.0,1.0,1.0,0.0);
	speed1 = gtk_spin_button_new(GTK_ADJUSTMENT(adj),0,0);
	cdr_spd_spin = speed1;
	gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
		GTK_SIGNAL_FUNC (writedev_speed),speed1);
	gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(speed1),1);
	gtk_table_attach_defaults(GTK_TABLE(tbl),speed1,15*4-1,16*4,row,row+1);

	i = get_writerreaderdevs_index(curset.writer_devnr);
	if (i >= 0) {
		gtk_spin_button_set_value(GTK_SPIN_BUTTON(speed1),
			(gfloat)writerreaderdevs[i]->writer_speed);
	} else {
               	gtk_widget_set_sensitive(speed1,FALSE);
	}
	gtk_widget_show(speed1);
	define_tooltip(speed1, _("The speed you want to burn Discs with. (Depends on your current Disc.)"));

       	if (!isroot() && !setupdata.root_option_change_writeparam) {
               	gtk_widget_set_sensitive(speed1,FALSE);
	}
}


/*
 * function to remove all selections on a clist
 */
void undo_selections(GtkWidget *clist, gint row, gint column,
	GdkEventButton *event, gpointer data) {

	gtk_clist_unselect_all(GTK_CLIST(clist));
}


/*
 * draw the disc-info-menu
 */
void draw_info_menu() {
GtkWidget *hbox, *vbox;
GtkWidget *f1,*f2;
GtkWidget *b1, *b_update;
GtkWidget *e1;
GtkWidget *l1;
GtkWidget *tbl;
GtkWidget *cd_list, *img_list;
gchar *titles[2];
GtkWidget *scrolled_win;

	/* prepare draw area */
	clear_actionspace();

	f1 = gtk_frame_new(_("Devices-Setup"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(actionspace),f1,FALSE,FALSE,5);
	gtk_widget_show(f1);

	tbl = gtk_table_new(1,16*4,TRUE);	
	gtk_table_set_col_spacing(GTK_TABLE(tbl),4*4-1,5);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),15*4-1,5);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
	gtk_container_add(GTK_CONTAINER(f1),tbl);
	gtk_widget_show(tbl);

	devices_setup_read(0, tbl, 0);


	/* left and right info-frames */
	tbl = gtk_table_new(1,2,TRUE);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(actionspace),tbl,TRUE,TRUE,10);
	gtk_widget_show(tbl);
	if (!curset.isProDVD) {
		f1 = gtk_frame_new(_("Disc-Information"));
	} else {
		f1 = gtk_frame_new(_("CD/DVD-Information"));
	}
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,0,1,0,1);
	gtk_widget_show(f1);
	f2 = gtk_frame_new(_("Image-Information"));
	set_font_and_color_frame(f2,PANGO_BOLD,NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f2,1,2,0,1);
	gtk_widget_show(f2);

	/* button bar at the bottom */
	hbox = gtk_hbox_new(TRUE,10);
	gtk_box_pack_start(GTK_BOX(actionspace),hbox,FALSE,TRUE,10);
	gtk_widget_show(hbox);
	b1 = gtk_button_new_with_label(_("Query CDDB"));
	gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
	gtk_widget_show(b1);
	gtk_signal_connect(GTK_OBJECT(b1), "clicked",
		GTK_SIGNAL_FUNC(cddb_clicked), NULL);
	define_tooltip(b1,_("Download the track titles for current CD. Requires a connection to the Internet."));

	b1 = gtk_button_new_with_label(_("Edit titles for CD-Text"));
	gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
	gtk_widget_show(b1);
	gtk_signal_connect(GTK_OBJECT(b1), "clicked",
		GTK_SIGNAL_FUNC(edit_cdtext_clicked), GINT_TO_POINTER(0));
	define_tooltip(b1,_("Edits the title and performer information before any tracks are read from the inserted CD. Only required to author a CD with CD-Text."));

	b_update = gtk_button_new_with_label(_("Update"));
	gtk_box_pack_start(GTK_BOX(hbox),b_update,TRUE,TRUE,10);
	gtk_widget_show(b_update);
	gtk_signal_connect(GTK_OBJECT(b_update), "clicked",
		GTK_SIGNAL_FUNC(update_clicked), NULL);
	define_tooltip(b_update,_("Refreshes the content of the information windows (e.g. after a Disc change)."));


	/* left info frame */
	vbox = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(f1),vbox);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
	gtk_widget_show(vbox);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_box_pack_start(GTK_BOX(vbox),scrolled_win,TRUE,TRUE,0);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
		GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
	gtk_widget_show(scrolled_win);
	
	titles[0] = g_strdup("");
	titles[1] = _("Tracks");
	cd_list = gtk_clist_new_with_titles(2,titles);
	gtk_signal_connect(GTK_OBJECT(cd_list), "select_row",
		GTK_SIGNAL_FUNC(undo_selections), NULL);
	gtk_container_add (GTK_CONTAINER (scrolled_win), cd_list);
	cdlist = GTK_CLIST(cd_list);
	gtk_clist_set_column_width(cdlist, 0, 16);
	gtk_clist_set_column_auto_resize(cdlist, 1, TRUE);
	gtk_widget_show(cd_list);

	tbl = gtk_table_new(3,8,TRUE);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),10);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,10);
	gtk_widget_show(tbl);
	
	l1 = rightjust_gtk_label_new(_("Type:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,0,1);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l1 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,0,1);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Label:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,1,2);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l2 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,1,2);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Size:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,2,3);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l3 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,2,3);
	gtk_widget_show(e1);


	/* right info frame */
	vbox = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(f2),vbox);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
	gtk_widget_show(vbox);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_box_pack_start(GTK_BOX(vbox),scrolled_win,TRUE,TRUE,0);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
		GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
	gtk_widget_show(scrolled_win);
	
	titles[0] = g_strdup("");
	titles[1] = _("Images");
	img_list = gtk_clist_new_with_titles(2,titles);
	gtk_signal_connect(GTK_OBJECT(img_list), "select_row",
		GTK_SIGNAL_FUNC(undo_selections), NULL);
	gtk_container_add (GTK_CONTAINER (scrolled_win), img_list);
	imglist = GTK_CLIST(img_list);
	gtk_clist_set_column_width(imglist, 0, 16);
	gtk_clist_set_column_auto_resize(imglist, 1, TRUE);
	gtk_widget_show(img_list);

	tbl = gtk_table_new(1,8,TRUE);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),10);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,10);
	gtk_widget_show(tbl);
	
	l1 = rightjust_gtk_label_new(_("Total Size:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,0,1);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	imglist_l1 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,3,8,0,1);
	gtk_widget_show(e1);
	define_tooltip(e1,_("Data / Audio"));

	gtk_widget_show(actionspace);

	while (gtk_events_pending())
		gtk_main_iteration();

	/* now update screen */
	gtk_button_clicked(GTK_BUTTON(b_update));
}


/*
 * calculate the space that would be recycled on the hard disk
 * when reading tracks and overwriting the ones with same names.
 * This is used to show the user what space really is free 
 * dependant of the name he chooses for his files
 */
static gint get_free_space_by_overwriting_trackfiles(gint *biggest) {
track_read_param_t *trackparam;
gfloat per;
gint i;
gint overwrite;
gint overwritebiggest;

	/* disc loaded? */
	if (cdinfo.nr_tracks < 0) {
		/* no disc in drive - no files to read */
		*biggest = 0;
		return 0;
	}

	/* free structure first */
	clear_trackreadset();

	/* fill structure */
	trackreadset.nrtracks = cdinfo.nr_tracks;

	for(i=0; i<cdinfo.nr_tracks; i++) {

		/* allocate memory */
		trackparam = g_new0(track_read_param_t,1);

		trackparam->trackinfo_index = i;
		trackparam->starttrack = trackinfo[i]->track_nr;
		trackparam->endtrack = 0;
		trackparam->tracktype = trackinfo[i]->type;
		per = (gfloat)trackinfo[i]->size * 100.0  / cdinfo.total_size;
		trackparam->percent = per;
		
		if (trackparam->tracktype == 0) {
			/* data track */
			trackparam->kbyte = trackinfo[i]->size *
				(DATASECTORSIZE/1024);
			trackparam->frames = trackinfo[i]->size;
			trackparam->startoffset = trackinfo[i]->start_sec;
			if (i == cdinfo.nr_tracks-1) {
				/* last track - leadout is track-end */
				trackparam->endoffset = cdinfo.leadout - 2; 	
			} else {
				/* sub 150 (2 sec leadout),
				   sub 2 (2 run out sectors) */
				trackparam->endoffset = 
					trackinfo[i+1]->start_sec -150-2; 	
			}
		} else {
			/* audio */
			trackparam->kbyte = trackinfo[i]->size *
				CDDAFRAME/1024;
			trackparam->frames = trackinfo[i]->size;
		}

		trackreadset.trackparams = g_list_append(
			trackreadset.trackparams, trackparam);
	}

	/* assign disk space */
	allocate_track_filenames(&overwrite, &overwritebiggest); 

	*biggest = overwritebiggest;
	return overwrite;
}


/*
 * callbacks for button in read-screen
 */
static void readalltracks_clicked(GtkWidget *widget, gpointer data) {
gchar path[MAXLINE];
gchar tmp[MAXLINE];
track_read_param_t *trackparam;
gfloat per;
gint i, ret, sectorstoread;
gint overwrite, overwritebiggest, stat;
gint datacount, audiocount, sectsize;
GList *loop;

	/* no disc reader defined */
	if (curset.reader_devnr == -1) {
		show_dialog(ICO_ERROR,_("No disc reader defined in Setup."), T_OK, NULL, NULL, 0);
		return;
	}

        datacount = 0;
        audiocount = 0;
        sectsize = get_sectorsize(curset.reader_devnr);


	/* now check if our disc information is still valid */
	get_cd_toc_and_volid(curset.reader_devnr);

	/* disc loaded? */
	if (cdinfo.nr_tracks < 0) {
		/* update screen ... */
		fill_read_menu();
		show_dialog(ICO_WARN,_("No Disc loaded in read device."),T_OK,NULL,NULL,0);
		return;
	}

	/* now check for CD-Extra because
	   we don't handle this currently */
	if (determine_disc_type(tmp,0) == 3) {
		show_dialog(ICO_INFO,_("This test release does currently not\nsupport copying of CD-Extra."),T_OK,NULL,NULL,0);
		return;
	}
	
	/* ok, the user wants to read all tracks */
	/* lets check if the file-prefix-entry is up to date */
	set_image_prefix_callback(imglist_l1, NULL); 

	/* free structure first */
	clear_trackreadset();

	/* fill structure */
	trackreadset.nrtracks = cdinfo.nr_tracks;

	for(i=0; i<cdinfo.nr_tracks; i++) {

		/* allocate memory */
		trackparam = g_new0(track_read_param_t,1);

		trackparam->trackinfo_index = i;
		trackparam->starttrack = trackinfo[i]->track_nr;
		trackparam->endtrack = 0;
		trackparam->tracktype = trackinfo[i]->type;
		per = (gfloat)trackinfo[i]->size * 100.0  / cdinfo.total_size;
		trackparam->percent = per;
		
		if (trackparam->tracktype == 0) {
			/* data track */
			datacount++;
			trackparam->kbyte = trackinfo[i]->size *
				(DATASECTORSIZE/1024);
			trackparam->frames = trackinfo[i]->size;
			trackparam->startoffset = trackinfo[i]->start_sec;
			if (i == cdinfo.nr_tracks-1) {
				/* last track - leadout is track-end */
				trackparam->endoffset = cdinfo.leadout - 2; 	
			} else {
				/* sub 150 (2 sec leadout),
				   sub 2 (2 run out sectors) */
				trackparam->endoffset = 
					trackinfo[i+1]->start_sec -150-2; 	
			}
			/*
			 * now do a paranoia check
			 * in some cases we skip to much of a track
			 */
			sectorstoread = trackparam->endoffset - 
				trackparam->startoffset;
			if (sectorstoread < trackinfo[i]->isosize) {
				trackparam->endoffset =
					trackparam->startoffset + 
						trackinfo[i]->isosize;
				trackparam->kbyte = trackinfo[i]->isosize * 2;
				dodebug(1,"readalltracks_clicked: corrected data track size from %d to %d sectors.\n", sectorstoread, trackinfo[i]->isosize);
			}
		} else {
			/* audio */
			audiocount++;
			trackparam->kbyte = trackinfo[i]->size *
				CDDAFRAME/1024;
			trackparam->frames = trackinfo[i]->size;
		}

		trackreadset.trackparams = g_list_append(
			trackreadset.trackparams, trackparam);
	}

        /* sectorsize firmware bug detection */
        if (datacount > 0 && sectsize != 2048) {
                ret = show_dialog(ICO_WARN,_("Your drive seems to have a faulty firmware which will not allow to read\ndata tracks reliably. Try to install a firmwire update or read your\ndata Discs with another drive. It is not recommended to continue."), T_ANYWAY, T_CANCEL, NULL, 1);
                if (ret == 1) {
                        /* abort */
                        return;
                }
        }


	/* assign disk space */
	stat = allocate_track_filenames(&overwrite, &overwritebiggest);

	if (stat == 1) {
		/* not enough space */
		ret = show_dialog(ICO_WARN,_("Not enough disk space available!\nDo you want to continue anyway or to abort?"), T_ANYWAY, T_CANCEL, NULL, 1);
		if (ret == 1) {
			/* abort */
			return;
		}
	}

        /* no writeable dirs */
        if (stat == 2) {
		show_dialog(ICO_WARN,_("No image-directories with write permissions found.\nPlease check your settings in the Setup."), T_OK, NULL, NULL, 1);
                return;
        }

	/* overwriting a link? */
	if (stat == 3) {
		/* FIX HERE USING GETTEXT FOR NEXT RELEASE */
		show_dialog(ICO_WARN,"Not allowing to overwrite a symlink.\nChoose another \"File prefix\".", T_OK, NULL, NULL, 1);
		return;
	}

	/* warn we are going to overwrite some files */
	if (setupdata.option_overwritewarn == 1 && overwrite > 0) {
		ret = show_dialog(ICO_WARN,_("You are going to overwrite old track images on your\nhard disk. Cancel now, if you don't want to do that\nand choose another \"File prefix\"."), T_ANYWAY, T_CANCEL, NULL, 1);
		if (ret == 1) {
			/* abort */
			return;
		}
	}
	
	/* assign now a toc-file name */
	strcpy(path, "");
	if (curset.image_index == -1) {
		/* automatic setting */
		loop = g_list_first(setupdata.image_dirs);
		while(loop) {
			strncpy(path,(gchar *)loop->data, MAXLINE);

			/* dir writeable? */
                        if (is_dir_writeable(path) == 0) {
				/* yes? take this */
				break;
			}
			loop = loop->next;
		}
	} else {
		strncpy(path,(gchar *)g_list_nth_data(setupdata.image_dirs,
			curset.image_index), MAXLINE);
	}
	g_snprintf(tmp,MAXLINE,"%s/%s.toc",path,curset.file_prefix);
	g_free(trackreadset.tocfile);
	trackreadset.tocfile = g_strdup(tmp);

	/* now all parameters for reading are set - lets begin */
	show_and_do_read_tracks(curset.reader_devnr, 1);
}


/*
 * fill the entries in the read_disc_menu
 */
static void fill_read_menu() {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar tmp3[MAXLINE];
gint overwritefree, normalfree, biggestfree, overwritefreebiggest, disc_type;

	/* file prefix */
	if (strcmp(curset.file_prefix,"") == 0) {
		g_free(curset.file_prefix);
		curset.file_prefix = g_strdup(IMGFILEPREFIX);
	}
	gtk_entry_set_text(GTK_ENTRY(imglist_l1), curset.file_prefix);
	gtk_entry_set_position(GTK_ENTRY(imglist_l1), 0);

	/* now check if the current filename has any influence on
	   the available space */
	overwritefree = 
		get_free_space_by_overwriting_trackfiles(&overwritefreebiggest);

	/* free size */
	normalfree = determine_free_space(&biggestfree);
	convert_kbytes2mbminstring(normalfree,tmp3);

	/* additional free space when overwriting files? */
	if (cdinfo.nr_tracks > 0 && overwritefree > 0) {
		convert_kbytes2mbstring(normalfree+overwritefree, tmp2);
		g_snprintf(tmp,MAXLINE,"%s (%s)", tmp3, tmp2);
	} else {
		strcpy(tmp,tmp3);
	}
	gtk_entry_set_text(GTK_ENTRY(imglist_l2), tmp);
	gtk_entry_set_position(GTK_ENTRY(imglist_l2), 0);

	/* biggest free block */
	convert_kbytes2mbminstring(biggestfree,tmp3);

	if (cdinfo.nr_tracks > 0 && overwritefreebiggest > 0) {
		convert_kbytes2mbstring(biggestfree+overwritefreebiggest, tmp2);
		g_snprintf(tmp,MAXLINE,"%s (%s)", tmp3, tmp2);
	} else {
		strcpy(tmp,tmp3);
	}
	gtk_entry_set_text(GTK_ENTRY(imglist_l3), tmp);
	gtk_entry_set_position(GTK_ENTRY(imglist_l3), 0);


	/* disc loaded? */
	if (cdinfo.nr_tracks == -1) {
		gtk_entry_set_text(GTK_ENTRY(cdlist_l1), _("No Disc loaded"));    
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2),"");	
		gtk_entry_set_text(GTK_ENTRY(cdlist_l3),"");	
		gtk_entry_set_text(GTK_ENTRY(cdlist_l4),"");	
		return;
        }
	if (cdinfo.nr_tracks == -2) {
		gtk_entry_set_text(GTK_ENTRY(cdlist_l1),  return_media_type(curset.reader_devnr));    
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2),"");	
		gtk_entry_set_text(GTK_ENTRY(cdlist_l3),"");	
		gtk_entry_set_text(GTK_ENTRY(cdlist_l4),"");	
		return;
        }

	/* get and display disc type */
	disc_type = determine_disc_type(tmp,0);
	gtk_entry_set_text(GTK_ENTRY(cdlist_l1), tmp); 

	/* display CD label */
	if (cdinfo.title && cdinfo.artist && 
		cdinfo.title[0] != '\0' && setupdata.option_displaycdtext) {
		g_snprintf(tmp,MAXLINE,"%s / %s", cdinfo.title, cdinfo.artist);
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2), tmp);
		gtk_entry_set_position(GTK_ENTRY(cdlist_l2),0);
	} else 
	if (cdinfo.cddb_dtitle != NULL) {
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2), cdinfo.cddb_dtitle);   
		gtk_entry_set_position(GTK_ENTRY(cdlist_l2),0);
	} else {
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2),"");    
	}

	/* display disc size */
	if (disc_type == 1 || disc_type == 2) { /* Audio or Mixed Mode CD */
		convert_frames2mbminstring(cdinfo.total_size, tmp);
	} else {                        /* Data CD/DVD/BD and CD Extra */
		convert_sectors2mbminstring(cdinfo.total_size, tmp);
	}
	gtk_entry_set_text(GTK_ENTRY(cdlist_l3), tmp);

	/* nr tracks */	
	g_snprintf(tmp,MAXLINE,"%d",cdinfo.nr_tracks);
	gtk_entry_set_text(GTK_ENTRY(cdlist_l4), tmp);
}


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

	g_free(curset.file_prefix);
	strcpy(tmp,gtk_entry_get_text(GTK_ENTRY(widget)));
	/* now check for illegal chars */
	if (remove_illegal_chars(tmp) == 1) {
		gtk_entry_set_text(GTK_ENTRY(widget), tmp);
		show_dialog(ICO_WARN,_("Illegal chars found in entry field.\nSubstituted them by \"_\" chars"),T_OK,NULL,NULL, 0);
	}
	curset.file_prefix = g_strdup(tmp);

	/* empty-file? */
	if (strcmp(curset.file_prefix,"") == 0) {
		g_free(curset.file_prefix);
		curset.file_prefix = g_strdup(IMGFILEPREFIX);
		gtk_entry_set_text(GTK_ENTRY(widget), curset.file_prefix);
	}

	/* update free overwrite size */
	if (submenu == 1) {
		fill_read_menu();
	}

	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[1])) == 1) {
		fill_read_tracks(1);
	}
	if (submenu == 2 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(side_widgets2[4])) == 1) {
		fill_master_write_menu();
	}

}


void readoptions_selected(GtkWidget *item, gpointer nr) {
gint sel;

	sel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));

	switch(GPOINTER_TO_INT(nr)) {
		case 0:
			curset.indexscan = sel;
			break;
		case 1:
			curset.deemphasize = sel;
			break;

	}
}


/*
 * draw the read disc menu
 */
static void draw_read_menu() {
gchar tmp[MAXLINE];
GtkWidget *hbox, *vbox;
GtkWidget *f1,*f2, *f3;
GtkWidget *b1, *b_update;
GtkWidget *e1;
GtkWidget *l1;
GtkWidget *tbl, *check;

	/* prepare draw area */
	clear_actionspace();

	f1 = gtk_frame_new(_("Devices-Setup"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(actionspace),f1,FALSE,FALSE,5);
	gtk_widget_show(f1);

	tbl = gtk_table_new(2,16*4,TRUE);	
	gtk_table_set_col_spacing(GTK_TABLE(tbl),4*4-1,5);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),15*4-2 ,5);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
	gtk_container_add(GTK_CONTAINER(f1),tbl);
	gtk_widget_show(tbl);

	devices_setup_read(0, tbl, 1);
	devices_setup_image(1, tbl);
	/* devices_setup_write(2, tbl); */

	/* left and right info-frames */
	tbl = gtk_table_new(1,2,TRUE);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(actionspace),tbl,TRUE,TRUE,10);
	gtk_widget_show(tbl);
	vbox = gtk_vbox_new(FALSE,10);
	gtk_table_attach_defaults(GTK_TABLE(tbl),vbox,0,1,0,1);
	if (!curset.isProDVD) {
		f1 = gtk_frame_new(_("Disc-Information"));
	} else {
		f1 = gtk_frame_new(_("CD/DVD-Information"));
	}
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(vbox),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);
	f3 = gtk_frame_new(_("Read options"));
	set_font_and_color_frame(f3,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(vbox),f3,FALSE,FALSE,0);
	gtk_widget_show(f3);
	f2 = gtk_frame_new(_("Image-Information"));
	set_font_and_color_frame(f2,PANGO_BOLD,NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f2,1,2,0,1);
	gtk_widget_show(f2);
	gtk_widget_show(vbox);

	/* button bar at the bottom */
	hbox = gtk_hbox_new(TRUE,10);
	gtk_box_pack_start(GTK_BOX(actionspace),hbox,FALSE,TRUE,10);
	gtk_widget_show(hbox);
	b1 = gtk_button_new_with_label(_("Read all tracks"));
	gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
	gtk_widget_show(b1);
	gtk_signal_connect(GTK_OBJECT(b1), "clicked",
		GTK_SIGNAL_FUNC(readalltracks_clicked), NULL);
	define_tooltip(b1, _("Reads all tracks from the current Disc and saves them in the image directories on the hard disk."));

	b_update = gtk_button_new_with_label(_("Update"));
	gtk_box_pack_start(GTK_BOX(hbox),b_update,TRUE,TRUE,10);
	gtk_widget_show(b_update);
	gtk_signal_connect(GTK_OBJECT(b_update), "clicked",
		GTK_SIGNAL_FUNC(update_readvrfy_clicked), GINT_TO_POINTER(1));
	define_tooltip(b_update,_("Refreshes the content of the information windows (e.g. after a Disc change)."));


	/* left info frame */
	vbox = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(f1),vbox);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
	gtk_widget_show(vbox);

	tbl = gtk_table_new(4,8,TRUE);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),10);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,10);
	gtk_widget_show(tbl);
	
	l1 = rightjust_gtk_label_new(_("Type:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,0,1);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l1 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,0,1);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Label:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,1,2);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l2 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,1,2);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Size:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,2,3);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l3 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,2,3);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Tracks:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,3,4);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l4 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,3,4);
	gtk_widget_show(e1);

	/* options frame */
	vbox = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(f3),vbox);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
	gtk_widget_show(vbox);

	tbl = gtk_table_new(1,8,TRUE);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,10);
	gtk_widget_show(tbl);

	/* index scan? */
	check = gtk_check_button_new_with_label(_("Do index scan"));
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
		GTK_SIGNAL_FUNC(readoptions_selected),GINT_TO_POINTER(0));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,8,0,1);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.indexscan);
	define_tooltip(check, _("Long-lasting audio tracks may be subdivided with indices, some audio CDs are recorded with pre-emphasis. If this option is enabled, the copy will be exactly as the original. Please note that some drives may need a little time to scan."));
	gtk_widget_show(check);

	/* deemphasize? */
	check = gtk_check_button_new_with_label(_("Audio deemphasis"));
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
		GTK_SIGNAL_FUNC(readoptions_selected),GINT_TO_POINTER(1));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,8,1,2);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.deemphasize);
	define_tooltip(check, _("Some audio CDs are recorded with pre-emphasis. This option detects and deemphasizes such audio tracks. This is mandatory if you want to convert the files e.g. to flac, ogg or mp3. By contrast, all Audio CD players would perform the deemphasis automatically."));
	gtk_widget_show(check);


	/* right info frame */
	vbox = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(f2),vbox);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
	gtk_widget_show(vbox);

	tbl = gtk_table_new(4,8,TRUE);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),10);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,10);
	gtk_widget_show(tbl);
	
	l1 = rightjust_gtk_label_new(_("File prefix:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4,0,1);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
	imglist_l1 = e1;
	gtk_signal_connect(GTK_OBJECT(e1), "activate",
		GTK_SIGNAL_FUNC(set_image_prefix_callback),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,4,8,0,1);
	gtk_widget_show(e1);
	g_snprintf(tmp,MAXLINE,"%s %s", _("This is the prefix of the filenames of the tracks saved to the hard disk."), _("Change this name if you want to read another Disc or to create another Disc image."));
	define_tooltip(e1,tmp);         /* concatenated text */

	l1 = rightjust_gtk_label_new(_("Free space:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,4,1,2);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	imglist_l2 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,4,8,1,2);
	gtk_widget_show(e1);
	define_tooltip(e1, _("If the Image Directory is set to \"Automatic\" this is the free hard disk space of all the image directories: Data / Audio"));

	l1 = leftjust_gtk_label_new(_("biggest available block of that:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,1,8,2,3);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	imglist_l3 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,4,8,3,4);
	gtk_widget_show(e1);
	define_tooltip(e1, _("The largest free space currently straight available: Data / Audio"));

	gtk_widget_show(actionspace);

	/* fill entries */
	fill_read_menu();
}


/*
 * fill the entries in the verify_disc_menu
 */
static void fill_verify_menu() {
gchar tmp[MAXLINE];
GList *loop;
GtkWidget *menu;
GtkWidget *menu_item, *menuselitem;
gint menuidx, menuhistory;
gint i, len, disc_type;

	/* get list of toc-files (save in tocfiles var) */
	scan_for_toc_files();

	/* clear out the old menu first (if any) */
	gtk_option_menu_remove_menu(GTK_OPTION_MENU (write_toc_menu));

	menu = gtk_menu_new();
	menuselitem = NULL;
	menu_item = NULL;
	menuidx = 0; menuhistory = 0;
	i = 0;
	loop = g_list_first(tocfiles);	
	while (loop) {
		/*
		 * a bug in GTK won't allow overlong option menus...
		 * well, then strip off the strings (not nice,
		 * but so far the only way I can think of)
		 */
		len = strlen((gchar *)loop->data);
		if (len > 24) {
			strcpy(tmp, ".. ");
			strcat(tmp, (gchar *)loop->data + len - 24);
		} else {
			strcpy(tmp, (gchar *)loop->data);
		}
		menu_item = gtk_menu_item_new_with_label(tmp);
		if (menuselitem == NULL) {
			/* default first element */
			menuselitem = menu_item;
		} 
		gtk_signal_connect(GTK_OBJECT(menu_item),
			"activate", GTK_SIGNAL_FUNC(tocwrite_selected),
			GINT_TO_POINTER(i));
		if (strcmp(curset.tocfile, (gchar *)loop->data) == 0) {
			menuhistory = menuidx;
			menuselitem = menu_item;
		}
		gtk_menu_append (GTK_MENU (menu), menu_item);
		gtk_widget_show (menu_item);
		loop = loop->next;
		menuidx++;
		i++;
	}

	/* no toc file found? */
	if (i == 0) {
	
		menu_item = gtk_menu_item_new_with_label(_(" - "));
		gtk_signal_connect(GTK_OBJECT(menu_item),
			"activate", GTK_SIGNAL_FUNC(tocwrite_selected),
			GINT_TO_POINTER(-2));
		if (strcmp(curset.tocfile, "-") == 0) {
			menuhistory = menuidx;
			menuselitem = menu_item;
		}
		gtk_menu_append (GTK_MENU (menu), menu_item);
		gtk_widget_show (menu_item);
	}
	gtk_option_menu_set_menu (GTK_OPTION_MENU (write_toc_menu), menu);
	gtk_option_menu_set_history(GTK_OPTION_MENU (write_toc_menu),menuhistory);
	/* toggle currently active menu */ 
	if (menuselitem != NULL) {
		gtk_menu_item_activate(GTK_MENU_ITEM (menuselitem));
	} else {
		/* if no active menu, activate the last set
		   (on-the-fly in this case) */
		gtk_menu_item_activate(GTK_MENU_ITEM (menu_item));
	}	


	/* ---------------- */

	/* disc loaded? */
	if (cdinfo.nr_tracks == -1) {
		gtk_entry_set_text(GTK_ENTRY(vrylist_l1), _("No Disc loaded"));    
		gtk_entry_set_text(GTK_ENTRY(vrylist_l2),"");	
		gtk_entry_set_text(GTK_ENTRY(vrylist_l3),"");	
		gtk_entry_set_text(GTK_ENTRY(vrylist_l4),"");	
		return;
        }
	if (cdinfo.nr_tracks == -2) {
		gtk_entry_set_text(GTK_ENTRY(vrylist_l1),  return_media_type(curset.reader_devnr));    
		gtk_entry_set_text(GTK_ENTRY(vrylist_l2),"");	
		gtk_entry_set_text(GTK_ENTRY(vrylist_l3),"");	
		gtk_entry_set_text(GTK_ENTRY(vrylist_l4),"");	
		return;
        }

	/* get and display disc type */
	disc_type = determine_disc_type(tmp,0);
	gtk_entry_set_text(GTK_ENTRY(vrylist_l1), tmp); 

	/* display CD label */
	if (cdinfo.title && cdinfo.artist && 
		cdinfo.title[0] != '\0' && setupdata.option_displaycdtext) {
		g_snprintf(tmp,MAXLINE,"%s / %s", cdinfo.title, cdinfo.artist);
		gtk_entry_set_text(GTK_ENTRY(vrylist_l2), tmp);
		gtk_entry_set_position(GTK_ENTRY(vrylist_l2),0);
	} else 
	if (cdinfo.cddb_dtitle != NULL) {
		gtk_entry_set_text(GTK_ENTRY(vrylist_l2), cdinfo.cddb_dtitle);
		gtk_entry_set_position(GTK_ENTRY(vrylist_l2),0);
	} else {
		gtk_entry_set_text(GTK_ENTRY(vrylist_l2),"");    
	}

	/* display disc size */
	if (disc_type == 1 || disc_type == 2) { /* Audio or Mixed Mode CD */
		convert_frames2mbminstring(cdinfo.total_size, tmp);
	} else {                        /* Data CD/DVD/BD and CD Extra */
		convert_sectors2mbminstring(cdinfo.total_size, tmp);
	}
	gtk_entry_set_text(GTK_ENTRY(vrylist_l3), tmp);

	/* nr tracks */	
	g_snprintf(tmp,MAXLINE,"%d",cdinfo.nr_tracks);
	gtk_entry_set_text(GTK_ENTRY(vrylist_l4), tmp);

}


/*
 * callbacks for verify-screen
 */
static void verify_clicked(GtkWidget *widget, gpointer data) {
gint stat;
gint ret;
track_read_param_t *trackparam;
GList *loop;
gint i, sectorstoread;
gint datat,audio;
gint datasize;

	/* no disc reader defined */
	if (curset.reader_devnr == -1) {
		show_dialog(ICO_ERROR,_("No disc reader defined in Setup."), T_OK, NULL, NULL, 0);
		return;
	}

        /* now check if our disc information is still valid */
        get_cd_toc_and_volid(curset.reader_devnr);

	/* disc loaded? */
	if (cdinfo.nr_tracks < 0) {
		fill_verify_menu();
		show_dialog(ICO_WARN,_("No Disc loaded in read device."),T_OK,NULL,NULL,0);
		return;
	}

	/* no tocfile selected */
	if (strcmp(curset.tocfile,"-") == 0) {
		show_dialog(ICO_WARN,_("No TOC file selected which specifies\nwhich tracks are to verify."),T_OK,NULL,NULL,0);
		return;
	}
	
	/* first check if all tracks we need are available on hd */
	stat = check_write_files(0);
	switch(stat) {
	/* files with wrong size */
	case 1:
		ret = show_dialog(ICO_QUEST,_("Some tracks do have a different file-size as expected.\nPerhaps the tracks are outdated or belong to another Disc.\nDo you want to continue anyway or to abort?"),T_ANYWAY,T_CANCEL, 
			NULL, 1);
		if (ret == 1) {
			/* aborted */
			return;
		}	
		break;
	/* files missing */
	case 2:
		show_dialog(ICO_ERROR,_("Some tracks belonging to the Disc you want to write are missing.\nPerhaps the TOC file is outdated and the tracks\nwere already removed from the hard drive."),T_OK,NULL,NULL,0);
		return;

	/* no permission/invalid */
	case 3:
		show_dialog(ICO_ERROR,_("You don't have permission to read all the track-files or\nthe tracks are not regular files on the hard drive."),T_OK,NULL,NULL,0);
		return;

	default:
		break;
	}

	/*
	 * now check if we have the correct disc to verify in the drive
	 * allow an offset of 15 sectors (padding)
	 */
	if (trackreadset.nrtracks != cdinfo.nr_tracks ||
	    (cdinfo.total_size-trackreadset.cdsize) > 15) {

		show_dialog(ICO_WARN,_("TOC file does not match the Disc in the drive.\nVerifying is therefore impossible."),T_OK,NULL,NULL,0);
		return;
	}


	datat = 0;
	audio = 0;
	datasize = 0;

	/* fill some additional data in the trackreadset-structure */
	loop = g_list_first(trackreadset.trackparams);
	for(i=0; i<cdinfo.nr_tracks; i++) {

		if (loop == NULL) {
			/* should never happen */
			show_dialog(ICO_WARN,_("TOC file does not match the Disc in the drive.\nVerifying is therefore impossible."),T_OK,NULL,NULL,0);
			return;
		}
		trackparam = loop->data;
		
		trackparam->trackinfo_index = i;

		/* does the tracktypes match? */
		if (trackparam->tracktype != trackinfo[i]->type) {
			show_dialog(ICO_WARN,_("TOC file does not match the Disc in the drive.\nVerifying is therefore impossible."),T_OK,NULL,NULL,0);
			return;
		}

		if (trackparam->tracktype == 0) {
			/* data track */
			trackparam->kbyte = trackinfo[i]->size *
				(DATASECTORSIZE/1024);
			trackparam->startoffset = trackinfo[i]->start_sec;
			if (i == cdinfo.nr_tracks-1) {
				/* last track - leadout is track-end */
				trackparam->endoffset = cdinfo.leadout - 2;
			} else {
				/* sub 150 (2 sec leadout),
				   sub 2 (2 run out sectors) */
				trackparam->endoffset =
					trackinfo[i+1]->start_sec -150-2;
			}
			/*
			 * now do a paranoia check
			 * in some cases we skip to much of a track
			 */
			sectorstoread = trackparam->endoffset - 
				trackparam->startoffset;
			if (sectorstoread < trackinfo[i]->isosize) {
				trackparam->endoffset =
					trackparam->startoffset + 
						trackinfo[i]->isosize;
				trackparam->kbyte = trackinfo[i]->isosize * 2;
				dodebug(1,"verify_clicked: corrected data track size from %d to %d sectors.\n", sectorstoread, trackinfo[i]->isosize);
			}

			datat++;
			datasize += trackparam->frames;
		} else {
			/* audio */
			trackparam->kbyte = trackinfo[i]->size *
				CDDAFRAME/1024;
			audio++;
		}	
		loop = loop->next;
	}


	/*
	 * OK...now we know we have the correct disc in the drive and a fully 
	 * functional set of image-files on the HD. All set for verifying.
	 */

	/* check if are allowed to verify audio */
	if (curset.noaudioverify == 1 && datat == 0 && audio > 0) {
		show_dialog(ICO_WARN,_("The Disc contains only audio tracks and you set that\naudio tracks should not be verified. Verifying is therefore impossible."), T_OK, NULL, NULL, 0);
		return;
	}

	/* do we have to recalc the percentages because we don't want
	   to verify audio? */
	if (curset.noaudioverify == 1 && audio > 0 && datat > 0) {
		loop = g_list_first(trackreadset.trackparams);
		while(loop) {
			trackparam = loop->data;
			/* only take data-tracks in account */
			trackparam->percent = 
				(gfloat)trackparam->frames / datasize;
			loop = loop->next; 
		}
	}

	show_and_do_verify_tracks(curset.reader_devnr);
}


void verifyoptions_selected(GtkWidget *item, gpointer nr) {
gint sel;

	sel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));

	switch(GPOINTER_TO_INT(nr)) {
		case 0:
			curset.noaudioverify = sel;
			break;
		case 1:
			curset.verifyfailabort = sel;
			break;
	}
}


/*
 * draw the verify-info-menu
 */
static void draw_verify_menu() {
GtkWidget *hbox, *vbox;
GtkWidget *f1, *f2, *f3;
GtkWidget *b1, *b_update;
GtkWidget *e1;
GtkWidget *l1;
GtkWidget *tbl, *omenu, *check;

	/* prepare draw area */
	clear_actionspace();

	edit_cdtext_btn = NULL;

	f1 = gtk_frame_new(_("Devices-Setup"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(actionspace),f1,FALSE,FALSE,5);
	gtk_widget_show(f1);

	tbl = gtk_table_new(2,16*4,TRUE);	
	gtk_table_set_col_spacing(GTK_TABLE(tbl),4*4-1,5);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),15*4-2,5);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
	gtk_container_add(GTK_CONTAINER(f1),tbl);
	gtk_widget_show(tbl);

	devices_setup_read(0, tbl, 1);
	devices_setup_image(1, tbl);

	/* left and right info-frames */
	tbl = gtk_table_new(1,2,TRUE);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(actionspace),tbl,TRUE,TRUE,10);
	gtk_widget_show(tbl);
	vbox = gtk_vbox_new(FALSE,10);
	gtk_table_attach_defaults(GTK_TABLE(tbl),vbox,0,1,0,1);
	if (!curset.isProDVD) {
		f1 = gtk_frame_new(_("Disc-Information"));
	} else {
		f1 = gtk_frame_new(_("CD/DVD-Information"));
	}
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(vbox),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);
	f3 = gtk_frame_new(_("Verify options"));
	set_font_and_color_frame(f3,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(vbox),f3,FALSE,FALSE,0);
	gtk_widget_show(f3);
	f2 = gtk_frame_new(_("Tracks to verify"));
	set_font_and_color_frame(f2,PANGO_BOLD,NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f2,1,2,0,1);
	gtk_widget_show(f2);
	gtk_widget_show(vbox);

	/* button bar at the bottom */
	hbox = gtk_hbox_new(TRUE,10);
	gtk_box_pack_start(GTK_BOX(actionspace),hbox,FALSE,TRUE,10);
	gtk_widget_show(hbox);
	b1 = gtk_button_new_with_label(_("Verify tracks"));
	gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
	gtk_widget_show(b1);
	gtk_signal_connect(GTK_OBJECT(b1), "clicked",
		GTK_SIGNAL_FUNC(verify_clicked), NULL);
	define_tooltip(b1, _("Reads all tracks from the current Disc again and does compare them with the tracks on the hard disk as specified in the selected TOC file."));

	b_update = gtk_button_new_with_label(_("Update"));
	gtk_box_pack_start(GTK_BOX(hbox),b_update,TRUE,TRUE,10);
	gtk_widget_show(b_update);
	gtk_signal_connect(GTK_OBJECT(b_update), "clicked",
		GTK_SIGNAL_FUNC(update_readvrfy_clicked), GINT_TO_POINTER(0));
	define_tooltip(b_update,_("Refreshes the content of the information windows (e.g. after a Disc change)."));


	/* left info frame */
	vbox = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(f1),vbox);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
	gtk_widget_show(vbox);

	tbl = gtk_table_new(4,8,TRUE);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),10);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,10);
	gtk_widget_show(tbl);
	
	l1 = rightjust_gtk_label_new(_("Type:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,0,1);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	vrylist_l1 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,0,1);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Label:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,1,2);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	vrylist_l2 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,1,2);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Size:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,2,3);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	vrylist_l3 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,2,3);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Tracks:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,3,4);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	vrylist_l4 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,8,3,4);
	gtk_widget_show(e1);

	/* options frame */
	vbox = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(f3),vbox);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
	gtk_widget_show(vbox);

	tbl = gtk_table_new(2,8,TRUE);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,10);
	gtk_widget_show(tbl);

	check = gtk_check_button_new_with_label(_("Don't verify audio tracks"));
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
		GTK_SIGNAL_FUNC(verifyoptions_selected),GINT_TO_POINTER(0));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,8,0,1);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		curset.noaudioverify);
	gtk_widget_show(check);
	define_tooltip(check, _("Skips verification of audio tracks, because a lot of optical disc drives are not able to read audio data reliably."));
	
	check = gtk_check_button_new_with_label(_("Abort after verify fail"));
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
		GTK_SIGNAL_FUNC(verifyoptions_selected),GINT_TO_POINTER(1));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,8,1,2);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		curset.verifyfailabort);
	gtk_widget_show(check);
	define_tooltip(check, _("Abort Verifying when one mismatch was found. Otherwise X-CD-Roast does continue to verify the other tracks anyway."));
	

	/* right info frame */
	vbox = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(f2),vbox);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
	gtk_widget_show(vbox);

	tbl = gtk_table_new(5,8,FALSE);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),10);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,0);
	gtk_widget_show(tbl);
	
	l1 = rightjust_gtk_label_new(_("TOC-File:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,0,1);
	gtk_widget_show(l1);

	omenu = gtk_option_menu_new();
	write_toc_menu = omenu;
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,3,8,0,1);
	gtk_widget_show(omenu);
	define_tooltip(omenu, _("Select which tracks should be verified against the current Disc. The TOC file must match the Disc, of course."));

	l1 = rightjust_gtk_label_new(_("Type:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,1,2);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l1 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,3,8,1,2);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Label:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,2,3);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l2 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,3,8,2,3);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Size:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,3,4);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l3 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,3,8,3,4);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Tracks:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,4,5);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l4 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,3,8,4,5);
	gtk_widget_show(e1);


	gtk_widget_show(actionspace);

	/* fill entries */
	fill_verify_menu();
}


/*
 * what do to when user selects a track from the list
 */
static void playlist_select_row(GtkWidget *clist, gint row, gint col,
	GdkEventButton *event, gpointer data) {

	/* double click? */
	if (event && event->type == GDK_2BUTTON_PRESS) {
		/* stop current song and play selected */
		wavplay_dodouble();
	}
}


/*
 * draw the play-tracks-menu
 */
void draw_play_tracks_menu() {
GtkWidget *scrolled_win;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar tmp3[MAXLINE];
gchar tmp4[MAXLINE];
gchar *titles[5];
gchar *data[5];
GtkWidget *list;
GtkCList *clist;
GdkPixmap *pixmap1;
GdkBitmap *mask1;
GtkStyle *style;
GList *loop;
image_files_t *entry;
gint count;

	/* prepare draw area */
	clear_actionspace();

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
	gtk_box_pack_start(GTK_BOX(actionspace),scrolled_win,TRUE,TRUE,5);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
		GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
	gtk_widget_show(scrolled_win);
	
	titles[0] = "";
	titles[1] = _("Nr.");
	titles[2] = _("Track title");
	titles[3] = _("Length");
	titles[4] = _("Filename");

	list = gtk_clist_new_with_titles(5,titles);
	gtk_container_add (GTK_CONTAINER (scrolled_win), list);
	gtk_widget_realize(list);
	clist = GTK_CLIST(list);
	gtk_clist_set_column_auto_resize(clist, 4, TRUE);
	play_clist = clist;
	gtk_signal_connect(GTK_OBJECT(list), "select_row",
		GTK_SIGNAL_FUNC(playlist_select_row), NULL);

	style = gtk_style_copy(gtk_widget_get_style(list));
	pixmap1 = gdk_pixmap_create_from_xpm_d(clist->clist_window,
		&mask1, &style->bg[GTK_STATE_NORMAL],(gchar **)miniaudio_xpm);
	data[0] = NULL;

	gtk_clist_set_row_height(clist, tbf(20));
	gtk_clist_set_column_width(clist, 0, tbf(20));
	gtk_clist_set_column_width(clist, 1, tbf(30));
	gtk_clist_set_column_justification(clist, 1, GTK_JUSTIFY_CENTER);
	gtk_clist_set_column_width(clist, 2, tbf(250));
	gtk_clist_set_column_width(clist, 3, tbf(80));
	gtk_widget_show(list);

	/* fill clist with valid audio-tracks */
	count = 1;
	loop = g_list_first(imagelist);
	while (loop) {
		entry = loop->data;
		if (entry->type == 1) {
			g_snprintf(tmp,MAXLINE,"%d.",count);
			data[1] = convert_for_gtk2(tmp);
			if (entry->title && entry->artist &&
			    strcmp(entry->title,"") && strcmp(entry->artist,"")) {
				g_snprintf(tmp3,MAXLINE,"%s / %s",
					entry->title, entry->artist);
				data[2] = convert_for_gtk2(tmp3);
			} else 
			if (entry->title && strcmp(entry->title,"")) {
				strncpy(tmp3, entry->title, MAXLINE);
				data[2] = convert_for_gtk2(tmp3);
			} else 
			if (entry->cddb_ttitle && strcmp(entry->cddb_ttitle,"")) {
				strncpy(tmp3, entry->cddb_ttitle, MAXLINE);
				data[2] = convert_for_gtk2(tmp3);
			} else {
				data[2] = NULL;
			} 
			convert_frames2minstring((gint)((off_t)entry->size/CDDAFRAME), tmp2);
			data[3] = convert_for_gtk2(tmp2);
			strncpy(tmp4, entry->path, MAXLINE);
			data[4] = convert_for_gtk2(tmp4);
			gtk_clist_append(clist,data);
			gtk_clist_set_pixmap(clist,count-1,0,pixmap1,mask1);

			count++;
		}
		loop = loop->next;
	}

	/* add wavplayer */
	wavplay_frontend(actionspace);

	gtk_widget_show(actionspace);
}


/*
 * callbacks for buttons in write-screen
 */
void blankcd_clicked(GtkWidget *widget, gpointer data) {
	
	/* no disc writer defined */
	if (curset.writer_devnr == -1) {
		show_dialog(ICO_ERROR,_("No disc writer defined in Setup."), T_OK, NULL, NULL, 0);
		return;
	}

	display_blank_cdrw(curset.writer_devnr);
}

void adv_write_options_clicked(GtkWidget *widget, gpointer data) {

	/* no disc writer defined */
	if (curset.writer_devnr == -1) {
		show_dialog(ICO_ERROR,_("No disc writer defined in Setup."), T_OK, NULL, NULL, 0);
		return;
	}

	display_advwriteoptions(curset.writer_devnr);
}

void show_atip_info(GtkWidget *widget, gpointer data) {

	/* no disc writer defined */
	if (curset.writer_devnr == -1) {
		show_dialog(ICO_ERROR,_("No disc writer defined in Setup."), T_OK, NULL, NULL, 0);
		return;
	}

	display_atip_info(curset.writer_devnr);
}

void cdrtype_selected(GtkWidget *item, gpointer mode) {

	curset.cdrtype = GPOINTER_TO_INT(mode);
	/*
	 * enable selection of write modes for CD and no multisession
	 * if the user has got the permission;
	 * disable it for DVD and BD in menus "Write Disc" and "Write Tracks"
	 */
	if ((isroot() || setupdata.root_option_change_writeparam)
	  && (curset.cdrtype < 1000 && !curset.multisession)) {
		if (dupl_cd_mode_omenu) {
			gtk_widget_set_sensitive(dupl_cd_mode_omenu, TRUE);
		}
		if (crea_cd_mode_omenu) {
			gtk_widget_set_sensitive(crea_cd_mode_omenu, TRUE);
		}
	} else if (curset.cdrtype > 1000) {
		if (dupl_cd_mode_omenu) {
			gtk_widget_set_sensitive(dupl_cd_mode_omenu, FALSE);
		}
		if (crea_cd_mode_omenu) {
			gtk_widget_set_sensitive(crea_cd_mode_omenu, FALSE);
		}
	}
}

void writemode_selected(GtkWidget *item, gpointer data) {
gint i;
	i = get_writerreaderdevs_index(curset.writer_devnr);
	writerreaderdevs[i]->writer_mode = GPOINTER_TO_INT(data);
}

void writeoptions_selected(GtkWidget *item, gpointer nr) {
gint sel;

	sel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));

	switch(GPOINTER_TO_INT(nr)) {
		case 0:
			curset.writesimul = sel;
			break;
		case 1:
			curset.writeeject = sel;
			break;
		case 2:
			curset.writepad = sel;
			break;
		case 3:
			curset.writeswap = sel;
			break;
		case 4:
			curset.nofixate = sel;
			break;
		case 5:
			curset.multisession = sel;
			/*
			 * disable/enable write mode selector in "Create Disc" menu
			 * also depends on the rights the user has got and on cdrtype;
			 * disable/enable the nofixate checkbox as well
			 */
			if (sel) {
				if (crea_cd_mode_omenu && curset.writer_devnr != -1) {
					gtk_widget_set_sensitive(crea_cd_mode_omenu, FALSE);
				}
				if (crea_cd_nofixate_check && curset.writer_devnr != -1) {
					gtk_widget_set_sensitive(crea_cd_nofixate_check,FALSE);
				}
			} else {
				if ((isroot() || setupdata.root_option_change_writeparam)
				  && curset.cdrtype < 1000
				  && crea_cd_mode_omenu && curset.writer_devnr != -1) {
					gtk_widget_set_sensitive(crea_cd_mode_omenu, TRUE);
				}
				if (crea_cd_nofixate_check && curset.writer_devnr != -1) {
					gtk_widget_set_sensitive(crea_cd_nofixate_check,TRUE);
				}
			}
			break;
		case 6: 
			curset.writecdtext = sel;
			break;
		case 7:
			curset.writeoverburn = sel;
			break;
		case 8:
			curset.writeburnfree = sel;
			break;	
		case 9: 
			curset.writeaudiomaster = sel;
			break;
		case 10:
			curset.writeforcespeed = sel;
			break;
		case 11:
			curset.writeignsize = sel;
			break;
		case 12:
			curset.writeimmed = sel;
			break;
	}
}


/*
 * callback for toc-selector in write menu
 */
static void tocwrite_selected(GtkWidget *item, gpointer val) {
GList *lelement;
gchar tmp[MAXLINE];
GdkCursor *cursor;
gint disc_type;

	strcpy(tmp,"");
	if (GPOINTER_TO_INT(val) >= 0) {
		lelement = g_list_nth(tocfiles, GPOINTER_TO_INT(val));
		if (lelement != NULL) {
			strcpy(tmp,(gchar *)lelement->data);
		}
	} else
	if (GPOINTER_TO_INT(val) == -1)  {
		/* on the fly setting */
		strcpy(tmp,"-");
	} else {
	 	/* empty setting (verify menu) */
		g_free(curset.tocfile);
		curset.tocfile = g_strdup("-");
		gtk_entry_set_text(GTK_ENTRY(cdlist_l1),"");
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2),"");
		gtk_entry_set_text(GTK_ENTRY(cdlist_l3),"");
		gtk_entry_set_text(GTK_ENTRY(cdlist_l4),"");
		return;
	}

	/*
	 * save current setting
	 * use full path string here because
	 * the index-number can get lost too easily
	 */
	g_free(curset.tocfile);
	curset.tocfile = g_strdup(tmp);

	do_lock(1);
	/* ok, now do some work - change cursor to watch */
	cursor = gdk_cursor_new(GDK_WATCH);
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);

	while (gtk_events_pending())
		gtk_main_iteration();

	if (strcmp(curset.tocfile,"-") != 0) {
		read_copy_cd_toc_file(curset.tocfile);
	
		/* get and display disc type */
		disc_type = determine_disc_type(tmp,1);
		gtk_entry_set_text(GTK_ENTRY(cdlist_l1), tmp);	

		/* disc title */
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2), 
			trackreadset.cdtitle);
		
		/* display track size */
		if (disc_type == 1 || disc_type == 2) { /* Audio or Mixed Mode CD */
			convert_frames2mbminstring(trackreadset.cdsize, tmp);
		} else {                        /* Data CD/DVD/BD and CD Extra */
			convert_sectors2mbminstring(trackreadset.cdsize, tmp);
		}
		gtk_entry_set_text(GTK_ENTRY(cdlist_l3), tmp);
	
		/* nr tracks */
		g_snprintf(tmp,MAXLINE,"%d",trackreadset.nrtracks);	
		gtk_entry_set_text(GTK_ENTRY(cdlist_l4), tmp);

	} else {
		/* we copy on the fly... */
		gtk_entry_set_text(GTK_ENTRY(cdlist_l2),"");
		gtk_entry_set_text(GTK_ENTRY(cdlist_l3),"");
		gtk_entry_set_text(GTK_ENTRY(cdlist_l4),"");
		if (cdinfo.nr_tracks == -1) {
			gtk_entry_set_text(GTK_ENTRY(cdlist_l1), _("No Disc loaded"));
		} else 
		if (cdinfo.nr_tracks == -2) {
			gtk_entry_set_text(GTK_ENTRY(cdlist_l1),  return_media_type(curset.reader_devnr));
		} else {
			/* disc is inserted - get and display type */
			disc_type = determine_disc_type(tmp,0);
			gtk_entry_set_text(GTK_ENTRY(cdlist_l1), tmp);

			/* display CD label */
			if (cdinfo.title && cdinfo.artist && 
				cdinfo.title[0] != '\0' && 
				setupdata.option_displaycdtext) {
				g_snprintf(tmp,MAXLINE,"%s / %s", 
					cdinfo.title, cdinfo.artist);
				gtk_entry_set_text(GTK_ENTRY(cdlist_l2), tmp);
				gtk_entry_set_position(GTK_ENTRY(cdlist_l2),0);
			} else 
				if (cdinfo.cddb_dtitle != NULL) {
				gtk_entry_set_text(GTK_ENTRY(cdlist_l2), 
					cdinfo.cddb_dtitle);   
				gtk_entry_set_position(GTK_ENTRY(cdlist_l2),0);
			}

			/* display disc size */
			if (disc_type == 1 || disc_type == 2) { /* Audio or Mixed Mode CD */
				convert_frames2mbminstring(cdinfo.total_size, tmp);
			} else {                        /* Data CD/DVD/BD and CD Extra */
				convert_sectors2mbminstring(cdinfo.total_size, tmp);
			}
			gtk_entry_set_text(GTK_ENTRY(cdlist_l3), tmp);

			/* nr tracks */	
			g_snprintf(tmp,MAXLINE,"%d",cdinfo.nr_tracks);
			gtk_entry_set_text(GTK_ENTRY(cdlist_l4), tmp);
		}
	}

	/* reset cursor */
	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
	gdk_cursor_destroy (cursor);
	do_unlock(1);
}


/*
 * callback for write button in write menu
 */
static void writetracks_clicked(GtkWidget *widget, gpointer data) {
gint stat;
gint ret,i;
gint onthefly;
gint spaceneededoncd;
gint outofspace;
gint64 tmpsize;
GList *loop;
track_read_param_t *trackparam;
gint datacount, audiocount;
gint readspeed, writespeed;

	/* no disc writer defined */
	if (curset.writer_devnr == -1) {
		show_dialog(ICO_ERROR,_("No disc writer defined in Setup."), T_OK, NULL, NULL, 0);
		return;
	}

	/* on the fly setting? */
	if (strcmp(curset.tocfile,"-") == 0) {
		onthefly = 1;

		spaceneededoncd = cdinfo.total_size;

		if (cdinfo.nr_tracks < 0) {
			show_dialog(ICO_WARN,_("No Disc loaded in read device."),T_OK,NULL,NULL,0);
			return;
		}

		/* now check if read device is different from write device */
		if (curset.reader_devnr == curset.writer_devnr) {
			show_dialog(ICO_WARN,_("Read device is the same as the write device!\nOn the fly copy is only possible with different devices\n"),T_OK,NULL,NULL,0);
			return;
		}

		/* check write speeds */
		i = get_writerreaderdevs_index(curset.reader_devnr);
		readspeed = writerreaderdevs[i]->audioread_speed;
		i = get_writerreaderdevs_index(curset.writer_devnr);
		writespeed = writerreaderdevs[i]->writer_speed;

		if (writespeed > readspeed && readspeed != 0) {
			ret = show_dialog(ICO_WARN,_("When copy on the fly it is not advised to use a\nhigher speed to write then to read."),T_ANYWAY,T_CANCEL, 
				NULL, 1);
			if (ret == 1) {
				/* aborted */
				return;
			}
		}

		audiocount = 0;
		datacount = 0;
                /* check cdinfo-structure */
                for (i = 0; i < cdinfo.nr_tracks; i++) {
                        if (trackinfo[i]->type == 0) {
                                datacount++;
                        } else {
                                audiocount++;
                        }
		}

			/*
			 * alpha version of the cdrtools installed, allow
			 * copy of audio (and simple data and cd-extra)
			 */
			if ((datacount > 0 && audiocount > 0 && trackinfo[0]->type != 1) ||
			    datacount > 1) {
				show_dialog(ICO_WARN,_("Currently on-the-fly copy is only supported\nfor simple data CDs, audio CDs or CDs with a data track\nafter several audio tracks (CD-Extra)."),T_OK,NULL,NULL,0);
				return;
			}	

			/* warn when cd-extra */
			if (datacount > 0 && audiocount > 0 && trackinfo[0]->type == 1) {
				ret = show_dialog(ICO_WARN,_("That CD contains both audio and data tracks. X-CD-Roast\nwill only copy the audio tracks in on-the-fly mode."),T_OK,T_CANCEL,NULL,0);
				if (ret == 1) {
					return;
				}
			}
		/* ok...everything seems to be fine */

	} else {
		onthefly = 0;
		spaceneededoncd = trackreadset.cdsize;

		/* first check if all tracks we need are available on hd */
		stat = check_write_files(0);
		switch(stat) {
		/* files with wrong size */
		case 1:
			ret = show_dialog(ICO_QUEST,_("Some tracks do have a different file-size as expected.\nPerhaps the tracks are outdated or belong to another Disc.\nDo you want to continue anyway or to abort?"),T_ANYWAY,T_CANCEL, 
				NULL, 1);
			if (ret == 1) {
				/* aborted */
				return;
			}	
			break;
		/* files missing */
		case 2:
			show_dialog(ICO_ERROR,_("Some tracks belonging to the Disc you want to write are missing.\nPerhaps the TOC file is outdated and the tracks\nwere already removed from the hard drive."),T_OK,NULL,NULL,0);
			return;

		/* no permission/invalid */
		case 3:
			show_dialog(ICO_ERROR,_("You don't have permission to read all the track-files or\nthe tracks are not regular files on the hard drive."),T_OK,NULL,NULL,0);
			return;

                /* invalid isrc or mcn */
                case 4:
                        ret = show_dialog(ICO_WARN,_("Some of the audio files you want to write have been recorded\nwith an invalid ISRC or MCN id. X-CD-Roast can clear these\ninvalid ids for you and continue or you have to abort now."),"Clear and continue",T_CANCEL,NULL,1);
                        if (ret == 1) {
                                /* abort */
                                return;
                        } else {
                                /* clear ids */
                                stat = clear_isrc_mcn_from_tracks();
                                if (stat == 1) {
                                        /* error resetting ids */
                                        show_dialog(ICO_ERROR,_("Failed to clear the ISRC or MCN id in all tracks.\nPerhaps you have no write permission on the .inf files?\nPlease correct the problem and try again."),T_OK,NULL,NULL,0);
                                        return;
                                }
                        }
                        break;
		}
	}

	/* check if enough space on disc? */
	dodebug(2,"Sectors required: %d, Mediatype = %d\n", spaceneededoncd,
		curset.cdrtype);
	outofspace = 0;
	if (curset.cdrtype < 1000) {
		/* minutes to check */
		if (spaceneededoncd > (curset.cdrtype*60*75)) {
			outofspace = 1;
		}
	} else {
		/*
		 * DVD sizes are declared with decimal prefix
		 *  - we use MB.
		 * We have to add 1 MB to avoid
		 * the 'out of space' warning.
		 * first the capacity of a DVD in Bytes
		 */
		tmpsize = (gint64)(curset.cdrtype +1) * 1000 * 1000;
		/* and now in sectors */
		tmpsize = tmpsize / 2048;

		if (spaceneededoncd > (gint)tmpsize) {
			outofspace = 1;
		}
	}
	if (outofspace) {
		if (!is_dvdwriter(curset.writer_devnr)) {
			ret = show_dialog(ICO_WARN,_("There may be not enough space on the CD-R available.\nYou can continue at own risk, but the resulting CD\nmight not be readable."),T_ANYWAY,T_CANCEL,NULL,1);
		} else {
			/* perhaps we want to write a dvd? */
			ret = show_dialog(ICO_WARN,_("There may be not enough space on the CD-R available.\nPerhaps you want to write a DVD, but you have not selected\nthe correct media size? You can continue at own\nrisk, but the resulting CD might not be readable."),T_ANYWAY,T_CANCEL,NULL,1);
		}
		if (ret == 1) {
			/* aborted */
			return;
		}	
	}

	/*
	 * check if wrong write mode
	 * for CD-Text is selected
	 */
	if (curset.writecdtext) {
		gshort i, wrmode;
		i = get_writerreaderdevs_index(curset.writer_devnr);
		wrmode = (writerreaderdevs[i]->writer_mode);
		if (wrmode != 0 && wrmode != 3 && wrmode != 4) {
			ret = show_dialog(ICO_WARN,_("Hint: The CD-Text will not be written.\nFor this, you need the Write Mode:\n \"DAO\" or \"raw96r\" or \"raw96p\"."),T_ANYWAY,T_CANCEL,NULL,1);
			if (ret) {
				return;
			}
		}
	}

	/*
	 * ok, now we are sure that all tracks are fine
	 * ...prompt for disc
	 */
	ret = show_dialog(ICO_INFO,pleaseinsertmedia(),T_OK,T_CANCEL,NULL,0);
	if (ret != 0) {
		return;
	}

	/*
	 * if we have to write CD-Text then
	 * edit the .inf files from cdda2wav
	 */
	if (curset.writecdtext && !onthefly) {
		loop = g_list_first(trackreadset.trackparams);
		while(loop) {
			trackparam = loop->data;
			if (trackparam->trackfile != NULL) {
				edit_xinf_for_cd_text(trackparam->trackfile,
					curset.tocfile);
			}
			loop = loop->next;
		}	

	}

	/* start writing */
	show_and_do_write_tracks(curset.writer_devnr, curset.reader_devnr, onthefly);
}


/*
 * fill the entries in the write disc menu
 */
static void fill_write_menu() {
GList *loop;
GtkWidget *menu;
GtkWidget *menu_item, *menuselitem;
gchar tmp[MAXLINE];
gint menuidx, menuhistory;
gint i, len;

	/* get list of toc-files (save in tocfiles var) */
	scan_for_toc_files();

	/* clear out the old menu first (if any) */
	gtk_option_menu_remove_menu(GTK_OPTION_MENU (write_toc_menu));

	menu = gtk_menu_new();
	menuselitem = NULL;
	menuidx = 0; menuhistory = 0;
	i = 0;
	loop = g_list_first(tocfiles);	
	while (loop) {
		/*
		 * a bug in GTK won't allow overlong option menus...
		 * well, then strip off the strings (not nice,
		 * but so far the only way I can think of)
		 */
		len = strlen((gchar *)loop->data);
		if (len > 24) {
			strcpy(tmp, ".. ");
			strcat(tmp, (gchar *)loop->data + len - 24);
		} else {
			strcpy(tmp, (gchar *)loop->data);
		}
		menu_item = gtk_menu_item_new_with_label(tmp);
		if (menuselitem == NULL) {
			/* default first element */
			menuselitem = menu_item;
		} 
		gtk_signal_connect(GTK_OBJECT(menu_item),
			"activate", GTK_SIGNAL_FUNC(tocwrite_selected),
			GINT_TO_POINTER(i));
		if (strcmp(curset.tocfile, (gchar *)loop->data) == 0) {
			menuhistory = menuidx;
			menuselitem = menu_item;
		}
		gtk_menu_append (GTK_MENU (menu), menu_item);
		gtk_widget_show (menu_item);
		loop = loop->next;
		menuidx++;
		i++;
	}
	/* on the fly setting */
	menu_item = gtk_menu_item_new_with_label(_("Copy on the fly"));
	gtk_signal_connect(GTK_OBJECT(menu_item),
		"activate", GTK_SIGNAL_FUNC(tocwrite_selected),
		GINT_TO_POINTER(-1));
	if (strcmp(curset.tocfile, "-") == 0) {
		menuhistory = menuidx;
		menuselitem = menu_item;
	}
	gtk_menu_append (GTK_MENU (menu), menu_item);
	gtk_widget_show (menu_item);

	gtk_option_menu_set_menu (GTK_OPTION_MENU (write_toc_menu), menu);
	gtk_option_menu_set_history(GTK_OPTION_MENU (write_toc_menu),menuhistory);
	/* toggle currently active menu */ 
	if (menuselitem != NULL) {
		gtk_menu_item_activate(GTK_MENU_ITEM (menuselitem));
	} else {
		/* if no active menu, activate the last set
		   (one the fly in this case) */
		gtk_menu_item_activate(GTK_MENU_ITEM (menu_item));
	}	

}


/*
 * draw the write disc menu
 */
static void draw_write_menu() {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
GtkWidget *hbox, *vbox;
GtkWidget *f1,*f2;
GtkWidget *b1;
GtkWidget *e1, *check;
GtkWidget *l1;
GtkWidget *tbl;
GtkWidget *sep;
GtkWidget *omenu;
GtkWidget *menu;
GtkWidget *menu_item;
gint cdrtypes[] = CDR_TYPES_MIN;
gint dvdtypes[] = DVD_TYPES_MB;
static const gchar *writemodes[] = WRITE_MODES;
static const gchar *helpwritemodes[] = HELP_WRITE_MODES;
gint i, tmpval;
gint menuidx, menuhistory;

	/*
	 * fixed settings for nofixate and multisession
 	 * since there is no checkbox for them
 	 * in "Duplicate Disc" menu
	 */
	curset.nofixate = FALSE;
	curset.multisession = FALSE;

	/* prepare draw area */
	clear_actionspace();

	/* initializion of global pointers */
	crea_cd_mode_omenu = NULL;
	dupl_cd_mode_omenu = NULL;
	dupl_cd_burnfree_check = NULL;

	f1 = gtk_frame_new(_("Devices-Setup"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(actionspace),f1,FALSE,FALSE,5);
	gtk_widget_show(f1);

	tbl = gtk_table_new(3,16*4,TRUE);	
	gtk_table_set_col_spacing(GTK_TABLE(tbl),4*4-1,5);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),15*4-2,5);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
	gtk_container_add(GTK_CONTAINER(f1),tbl);
	gtk_widget_show(tbl);

	devices_setup_read(0, tbl, 1);
	devices_setup_image(1, tbl);
	devices_setup_write(2, tbl);

	/* left and right info-frames */
	tbl = gtk_table_new(1,2,TRUE);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(actionspace),tbl,TRUE,TRUE,10);
	gtk_widget_show(tbl);
	if (!curset.isProDVD) {
		f1 = gtk_frame_new(_("Disc to write"));
	} else {
		f1 = gtk_frame_new(_("CD/DVD to write"));
	}
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,0,1,0,1);
	gtk_widget_show(f1);
	f2 = gtk_frame_new(_("Write parameters"));
	set_font_and_color_frame(f2,PANGO_BOLD,NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f2,1,2,0,1);
	gtk_widget_show(f2);

	/* button bar at the bottom */
	hbox = gtk_hbox_new(TRUE,10);
	gtk_box_pack_start(GTK_BOX(actionspace),hbox,FALSE,TRUE,5);
	gtk_widget_show(hbox);
	if (!curset.isProDVD) {
		b1 = gtk_button_new_with_label(_("Write Disc"));
	} else {
		b1 = gtk_button_new_with_label(_("Write CD/DVD"));
	}
	gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
	gtk_widget_show(b1);
	gtk_signal_connect(GTK_OBJECT(b1), "clicked",
		GTK_SIGNAL_FUNC(writetracks_clicked), NULL);
	define_tooltip(b1,_("Writes all tracks specified by the TOC file to a Disc."));

	if (!curset.isProDVD) {
		b1 = gtk_button_new_with_label(_("Blank Disc"));
	} else {
		b1 = gtk_button_new_with_label(_("Blank CD/DVD+-RW"));
	}
	gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
	gtk_widget_show(b1);
	gtk_signal_connect(GTK_OBJECT(b1), "clicked",
		GTK_SIGNAL_FUNC(blankcd_clicked), NULL);
	define_tooltip(b1,_("Blanks a rewritable Disc inserted in the Writer."));


	/* left info frame */
	vbox = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(f1),vbox);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
	gtk_widget_show(vbox);

	tbl = gtk_table_new(5,8,FALSE);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),10);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,0);
	gtk_widget_show(tbl);
	
	l1 = rightjust_gtk_label_new(_("TOC-File:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,0,1);
	gtk_widget_show(l1);

	omenu = gtk_option_menu_new();
	write_toc_menu = omenu;
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,3,8,0,1);
	gtk_widget_show(omenu);
	define_tooltip(omenu,_("Select the TOC file that specifies which tracks should be written to Disc. The setting \"Copy on the fly\" will read the tracks directly from the Disc reader instead from the harddisk."));

	l1 = rightjust_gtk_label_new(_("Type:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,1,2);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l1 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,3,8,1,2);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Label:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,2,3);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l2 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,3,8,2,3);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Size:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,3,4);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l3 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,3,8,3,4);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Tracks:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,4,5);
	gtk_widget_show(l1);

	e1 = gtk_entry_new();
	cdlist_l4 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,3,8,4,5);
	gtk_widget_show(e1);


	/* right info frame */
	vbox = gtk_vbox_new(FALSE,0);
	gtk_container_add(GTK_CONTAINER(f2),vbox);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 7);
	gtk_widget_show(vbox);

	tbl = gtk_table_new(8,16,FALSE);
	gtk_table_set_row_spacing(GTK_TABLE(tbl),0,2);
	gtk_table_set_row_spacing(GTK_TABLE(tbl),1,5);
	gtk_table_set_row_spacing(GTK_TABLE(tbl),2,5);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),2);
	gtk_box_pack_start(GTK_BOX(vbox),tbl,FALSE,FALSE,0);
	gtk_widget_show(tbl);
	
	/* disc type */

	l1 = rightjust_gtk_label_new(_("Disc Type:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,6,0,1);
	gtk_widget_show(l1);

	omenu = gtk_option_menu_new();
	menu = gtk_menu_new();
	menuidx = 0; menuhistory = 0;

	i = 0;
	tmpval = curset.cdrtype;
	while (cdrtypes[i] != 0) {
		/* construct minute-list */
		g_snprintf(tmp,MAXLINE,"%d min",abs(cdrtypes[i]));

		menu_item = gtk_menu_item_new_with_label(tmp);
		gtk_signal_connect(GTK_OBJECT(menu_item),
			"activate", GTK_SIGNAL_FUNC(cdrtype_selected),
			GINT_TO_POINTER(abs(cdrtypes[i])));
		gtk_menu_append (GTK_MENU (menu), menu_item);
		if (tmpval == abs(cdrtypes[i])) { 
			menuhistory = menuidx;
		}
		/* default set defined by negativ value */
		if (tmpval == 0 && cdrtypes[i] < 0) {
			menuhistory = menuidx;
			curset.cdrtype = abs(cdrtypes[i]);
		}
		menuidx++;
		gtk_widget_show (menu_item);
		i++;
	}

	i = 0;
	tmpval = curset.cdrtype;
	while (dvdtypes[i] != 0) {
		/* construct GB-list */
		g_snprintf(tmp2,MAXLINE,"%.2f", (gfloat)dvdtypes[i]/1000);
		if (tmp2[strlen(tmp2)-1] == '0') {
			tmp2[strlen(tmp2)-1] = '\0'; /* strip off last 0 */
		}
		g_snprintf(tmp,MAXLINE,"%s GB",tmp2); /*decimal prefix*/

		menu_item = gtk_menu_item_new_with_label(tmp);
		gtk_signal_connect(GTK_OBJECT(menu_item),
		"activate", GTK_SIGNAL_FUNC(cdrtype_selected),
		GINT_TO_POINTER(dvdtypes[i]));
		gtk_menu_append (GTK_MENU (menu), menu_item);
		if (tmpval == abs(dvdtypes[i])) { 
			menuhistory = menuidx;
		}
		menuidx++;
		gtk_widget_show (menu_item);
		i++;
	}

	gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
	gtk_option_menu_set_history(GTK_OPTION_MENU (omenu),menuhistory);
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,6,10,0,1);
	gtk_widget_show(omenu);
	define_tooltip(omenu,_("The capacity of the currently used Disc."));

	b1 = gtk_button_new_with_label(_("ATIP-Info"));
	gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(show_atip_info),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),b1,10,16,0,1);
	gtk_widget_show(b1);
	define_tooltip(b1,_("Read detailed information from a (empty) Disc."));


	/* write mode */
	l1 = rightjust_gtk_label_new(_("Write Mode:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,6,1,2);
	gtk_widget_show(l1);

        omenu = gtk_option_menu_new ();
        menu = gtk_menu_new();
	dupl_cd_mode_omenu = omenu;

        i = 0;
        while (writemodes[i]) {
                menu_item = gtk_menu_item_new_with_label(_(writemodes[i]));
                gtk_signal_connect(GTK_OBJECT(menu_item), "activate",
                        GTK_SIGNAL_FUNC(writemode_selected),
                        GINT_TO_POINTER(i));
                gtk_menu_append (GTK_MENU (menu), menu_item);
                gtk_widget_show (menu_item);
                if (helpwritemodes[i])
                        define_tooltip(menu_item,(gchar *)_(helpwritemodes[i]));
                i++;
        }

        gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
	preselect_write_mode_menu(omenu, curset.writer_devnr);
        gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,6,16,1,2);
        gtk_widget_show(omenu);
        g_snprintf(tmp,MAXLINE,"%s %s",_("Choose which mode you want to use for writing CDs. Try \"DAO\" first, because this is the best one for all modern disc writers."), _("Click an option and hold the button to get additional help for each mode."));
        define_tooltip(omenu,tmp);	/* concatenated text */

	/*
	 * disable selection of write modes
	 * if the user hasn't got the permission
	 * or if DVD or BD or if multisession
	 */
	if ((!isroot() && !setupdata.root_option_change_writeparam)
	  || curset.cdrtype > 1000 || curset.multisession) {
		gtk_widget_set_sensitive(omenu,FALSE);
	}

	sep = gtk_hseparator_new();
	gtk_table_attach_defaults(GTK_TABLE(tbl),sep,0,16,2,3);
	gtk_widget_show(sep);

	check = gtk_check_button_new_with_label(_("Simulation write"));
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
		GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(0));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,3,4);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		curset.writesimul);
	gtk_widget_show(check);
	define_tooltip(check,_("Just simulate the burning process. Please note that DVD+ media and Blu-ray media do not support simulation writes."));

	check = gtk_check_button_new_with_label(_("Eject after write"));
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
		GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(1));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,4,5);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		curset.writeeject);
	gtk_widget_show(check);
	define_tooltip(check,_("Eject the Disc after the burning was completed."));
	
	check = gtk_check_button_new_with_label(_("Pad Tracks"));
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
		GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(2));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,5,6);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		curset.writepad);
	gtk_widget_show(check);
	define_tooltip(check,_("Pads data-tracks with zeros to eliminate reading problems on some systems and adapts the length of audio-tracks for CD writing. This must be enabled when you want to burn wav-files not created with X-CD-Roast."));
	
	check = gtk_check_button_new_with_label(_("Enable protection from Buffer Underruns"));
	dupl_cd_burnfree_check = check;
 
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
		GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(8));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,16,6,7);
	if (does_support_burnproof(curset.writer_devnr)) {
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
			curset.writeburnfree);
	}
	gtk_widget_show(check);
	define_tooltip(check,_("When available it does enable protection from Buffer Underrun errors. Supported are Sanyo BURN-Proof, Ricoh Just-Link and similar."));

	if (!does_support_burnproof(curset.writer_devnr))
                gtk_widget_set_sensitive(check,FALSE);

	check = gtk_check_button_new_with_label(_("Write CD-Text"));
	gtk_signal_connect(GTK_OBJECT(check),"clicked",
		GTK_SIGNAL_FUNC(writeoptions_selected),GINT_TO_POINTER(6));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,2,8,7,8);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		curset.writecdtext);
	gtk_widget_show(check);
	define_tooltip(check,_("Writes CD-Text information to the CD-R/RW when your CD Writer is supporting it. This usually works only when writing in DAO or raw96 mode."));

        b1 = gtk_button_new_with_label(_("Edit titles"));
	edit_cdtext_btn = b1;
        gtk_signal_connect (GTK_OBJECT (b1), "clicked",
                GTK_SIGNAL_FUNC(edit_cdtext_clicked), GINT_TO_POINTER(1));
        gtk_table_attach_defaults(GTK_TABLE(tbl),b1,8,16,7,8);
        gtk_widget_show(b1);
        define_tooltip(b1,_("Edits the title and performer information of your tracks before they are written to a CD-R/RW with CD-Text."));


        b1 = gtk_button_new_with_label(_("Advanced options"));
        gtk_signal_connect (GTK_OBJECT (b1), "clicked",
                GTK_SIGNAL_FUNC(adv_write_options_clicked), NULL);
	gtk_box_pack_end(GTK_BOX(vbox),b1,FALSE,FALSE,0);
        gtk_widget_show(b1);
        define_tooltip(b1,_("Set additional write options for advanced users."));

	
	gtk_widget_show(actionspace);


	/* fill entries */
	fill_write_menu();

}


/*
 * fill the list with the tracks to delete
 */
static void fill_delete_menu() {
GtkStyle *style;
gchar *data[5];
GdkPixmap *pixmap1, *pixmap2, *pixmap3, *pixmap4, *pixmap5;
GdkBitmap *mask1, *mask2, *mask3, *mask4, *mask5;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar tmp3[MAXLINE];
gchar tmp4[MAXLINE];
gchar basename[MAXLINE], imgdir[MAXLINE], *p;
GList *loop;
image_files_t *entry;
gint lcount, count;
gint sizecount;
gint dummy;

	/* clean up first */
	gtk_clist_clear(imglist);

	style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(imglist)));
	pixmap1 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
		&mask1, &style->bg[GTK_STATE_NORMAL],(gchar **)minidata_xpm);
	pixmap2 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
		&mask2, &style->bg[GTK_STATE_NORMAL],(gchar **)miniaudio_xpm);
	pixmap3 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
		&mask3, &style->bg[GTK_STATE_NORMAL],(gchar **)mininodata_xpm);
	pixmap4 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
		&mask4, &style->bg[GTK_STATE_NORMAL],(gchar **)mininoaudio_xpm);
	pixmap5 = gdk_pixmap_create_from_xpm_d(imglist->clist_window,
		&mask5, &style->bg[GTK_STATE_NORMAL],(gchar **)minitoc_xpm);

	data[0] = NULL;
	strcpy(imgdir,"");
	lcount = 0;
	count = 1;
	sizecount = 0;

	/* check image-selector */
	if (curset.image_index != -1) {
		/* no automatic setting? */
		strncpy(imgdir,(gchar *)g_list_nth_data(setupdata.image_dirs,
			curset.image_index), MAXLINE);
	}

	loop = g_list_first(imagelist);
	while (loop) {
		entry = loop->data;

		/* get the base-dirname */
		strncpy(basename,entry->path,MAXLINE);	
		p = rindex(basename,'/');
		*p = '\0';
		if (strcmp(basename,"") == 0) {
			strcpy(basename,"/");
		}
		if (strcmp(basename,imgdir) != 0 && imgdir[0] != '\0') {
			/* skip not selected dirs */
			loop = loop->next;
			continue;
		}

		/* count */
		g_snprintf(tmp,MAXLINE,"%d.",count);
		data[1] = convert_for_gtk2(tmp); 

		/* title */
		if (entry->title && entry->artist &&
			strcmp(entry->title,"") && strcmp(entry->artist,"")) {
			g_snprintf(tmp3,MAXLINE,"%s / %s",
				entry->title, entry->artist);
				data[2] = convert_for_gtk2(tmp3); 
		} else 
		if (entry->title && strcmp(entry->title,"")) {
			strncpy(tmp3, entry->title, MAXLINE);
			data[2] = convert_for_gtk2(tmp3); 
		} else 
		 if (entry->cddb_ttitle && strcmp(entry->cddb_ttitle,"")) {
			strncpy(tmp3, entry->cddb_ttitle, MAXLINE);
			data[2] = convert_for_gtk2(tmp3); 
		} else 
		if (entry->volname && strcmp(entry->volname,"")) {
			g_snprintf(tmp3,MAXLINE,"%s / ISO9660",
				entry->volname);
			data[2] = convert_for_gtk2(tmp3); 
		} else {
			data[2] = NULL;
		}

		/* path */
		strncpy(tmp4, entry->path, MAXLINE);
		data[4] = convert_for_gtk2(tmp4); 

		/* iso9600-track/ unknown  */
		if (entry->type == 0 || entry->type == 3) {
			convert_frames2mbstring((gint)((off_t)entry->size/DATASECTORSIZE),
				tmp2);
			data[3] = convert_for_gtk2(tmp2); 
			gtk_clist_append(imglist,data);
			if (entry->readable == 1 && entry->type == 0) {
				gtk_clist_set_pixmap(imglist,lcount,0,pixmap1,mask1);	
			} else {
				gtk_clist_set_pixmap(imglist,lcount,0,pixmap3,mask3);	
			}
			lcount++;
			sizecount+=(gint)((off_t)entry->size >> 10);
			count++;
		}

		/* valid/invalid wav-file */
		if (entry->type == 1 || entry->type == 2) {
			convert_frames2minstring((gint)((off_t)entry->size/CDDAFRAME), tmp2);
			data[3] = convert_for_gtk2(tmp2); 
			gtk_clist_append(imglist,data);
			if (entry->readable == 1 && entry->type == 1) {
				gtk_clist_set_pixmap(imglist,lcount,0,pixmap2,mask2);	
			} else {
				gtk_clist_set_pixmap(imglist,lcount,0,pixmap4,mask4);	
			}
			lcount++;
			sizecount+=(gint)((off_t)entry->size >> 10);
			count++;
		}	

		/* toc-file */
		if (entry->type == 4) {
			data[3] = NULL; 
			gtk_clist_append(imglist,data);
			gtk_clist_set_pixmap(imglist,lcount,0,pixmap5, mask5);
			count++;
			lcount++;
		}

		loop = loop->next;
	}

	/* nothing selected - no size of files */
	convert_kbytes2mbminstring(0, tmp);
	gtk_entry_set_text(GTK_ENTRY(imglist_l1), tmp);	 

	/* free size */
	convert_kbytes2mbminstring(determine_free_space(&dummy),tmp);
	gtk_entry_set_text(GTK_ENTRY(imglist_l2), tmp);
}


/*
 * select a row with a given filename
 */
static void select_delete_row_by_filename(gchar *fname) {
gint i;
gchar *cell;

	/* loop through all rows */
	for (i = 0; i < imglist->rows; i++) {
		gtk_clist_get_text(imglist,i,4,&cell);
		if (strcmp(cell, fname) == 0) {
			/* match found - select row */
			gtk_clist_select_row(imglist, i, 0);
		}
	}
}


/*
 * update currently selected track-size
 */
static void update_delete_size(gint doubleclick, gint clickrow) {
GList *sel;
gint row,type;
gchar *cell;
off_t size;
gint sizecount;
gchar tmp[MAXLINE];
GList *loop;
track_read_param_t *trackparam;

	sizecount = 0;

	/* check for doubleclick on list */
	if (doubleclick) {
		gtk_clist_get_text(imglist,clickrow,4,&cell);
		type = get_type_from_imagelist(cell);
		/* is it a toc-file? (type 4) */
		if (type == 4) {
			/* now scan toc file */
			read_copy_cd_toc_file(cell);
			/*
			 * select all files to delete
			 * which are in the toc-file
			 */
			loop = g_list_first(trackreadset.trackparams);
			while(loop) {
				trackparam = loop->data;
				select_delete_row_by_filename(
					trackparam->trackfile);

				loop = loop->next;
			}
		}
	}

	/* loop through all selected tracks */
	sel = imglist->selection;
	while (sel) {
		row = GPOINTER_TO_INT(sel->data);		
		gtk_clist_get_text(imglist,row,4,&cell);
		size = get_size_from_imagelist(cell);
		sizecount += (gint)((off_t)size >> 10);
		sel = sel->next;
	}

	convert_kbytes2mbminstring(sizecount, tmp);
	gtk_entry_set_text(GTK_ENTRY(imglist_l1), tmp);
}


/*
 * start the delete job
 */
static void do_delete_press(GtkWidget *widget, gpointer data) {
GList *sel;
gint row;
gchar *cell;
gint count,ret;
gchar tmp[MAXLINE];
GList *delfiles;

	delfiles = NULL;
	count = 0;
	/*
	 * loop through all selected tracks
	 * create a glist containing all files names to delete
	 */
	sel = imglist->selection;
	while (sel) {
		row = GPOINTER_TO_INT(sel->data);		
		gtk_clist_get_text(imglist,row,4,&cell);
		delfiles = g_list_append(delfiles,g_strdup(cell));
		count++;
		sel = sel->next;
	}

	if (count == 0) {
		show_dialog(ICO_WARN,_("No tracks selected to delete"), T_OK, NULL, NULL, 0);
		return;
	} else 
	if (count == 1) {
		ret = show_dialog(ICO_QUEST,_("Are you sure you want to delete one track?"),T_YES,T_NO,NULL,0);
	} else {
		g_snprintf(tmp,MAXLINE,_("Are you sure you want to delete %d tracks?"),count);
		ret = show_dialog(ICO_QUEST,tmp,T_YES,T_NO,NULL,0);
	}

	if (ret == 1) {
		/* not sure - abort */
		return;
	}

	/* create menu showing deletion */
	show_and_do_delete(delfiles);

	free_glist(&delfiles);

	/* now update image-list */
	scan_imagedirs();
	fill_delete_menu();
}

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

	gtk_clist_select_all(imglist);
}

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

	gtk_clist_unselect_all(imglist);
}

static void delete_select_row(GtkWidget *clist, gint row, gint col,
	GdkEventButton *event, gpointer data) {

	/* double click? */
	if (event && event->type == GDK_2BUTTON_PRESS) {
		update_delete_size(1, row);
	} else {
		update_delete_size(0, row);
	}
}


/*
 * draw the delete-tracks menu
 */
void draw_delete_menu() {
GtkWidget *hbox;
GtkWidget *f1;
GtkWidget *b1;
GtkWidget *list;
gchar *titles[5];
GtkCList *clist;
GtkWidget *e1;
GtkWidget *l1;
GtkWidget *tbl;
GtkWidget *sep, *dummy;
GtkWidget *scrolled_win;

	/* prepare draw area */
	clear_actionspace();

	f1 = gtk_frame_new(_("Devices-Setup"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(actionspace),f1,FALSE,FALSE,5);
	gtk_widget_show(f1);

	tbl = gtk_table_new(1,16*4,TRUE);	
	gtk_table_set_col_spacing(GTK_TABLE(tbl),4*4-1,5);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),15*4-2,5);
	gtk_container_set_border_width(GTK_CONTAINER (tbl),5);
	gtk_container_add(GTK_CONTAINER(f1),tbl);
	gtk_widget_show(tbl);

	devices_setup_image(0, tbl);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 10);
	gtk_box_pack_start(GTK_BOX(actionspace),scrolled_win,TRUE,TRUE,0);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
		GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
	gtk_widget_show(scrolled_win);
	
	titles[0] = "";
	titles[1] = _("Nr.");
	titles[2] = _("Track title");
	titles[3] = _("Length");
	titles[4] = _("Filename");

	list = gtk_clist_new_with_titles(5,titles);
	gtk_container_add (GTK_CONTAINER (scrolled_win), list);
	gtk_widget_realize(list);
	clist = GTK_CLIST(list);
	imglist = clist;
	gtk_clist_set_column_auto_resize(clist, 4, TRUE);
	gtk_signal_connect(GTK_OBJECT(clist), "select_row",
		GTK_SIGNAL_FUNC(delete_select_row),NULL);
	gtk_signal_connect(GTK_OBJECT(clist), "unselect_row",
		GTK_SIGNAL_FUNC(delete_select_row),NULL);

	gtk_clist_set_row_height(clist, tbf(20));
	gtk_clist_set_column_width(clist, 0, tbf(20));
	gtk_clist_set_column_width(clist, 1, tbf(30));
	gtk_clist_set_column_justification(clist, 1, GTK_JUSTIFY_CENTER);
	gtk_clist_set_column_width(clist, 2, tbf(250));
	gtk_clist_set_column_width(clist, 3, tbf(80));
	gtk_clist_set_selection_mode (clist, GTK_SELECTION_MULTIPLE);
	gtk_widget_show(list);

	tbl = gtk_table_new(2,16,TRUE);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),10);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(actionspace),tbl,FALSE,FALSE,10);
	gtk_widget_show(tbl);
	
	l1 = rightjust_gtk_label_new(_("Size of selected tracks:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,6,0,1);
	gtk_widget_show(l1);
	e1 = gtk_entry_new();
	imglist_l1 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,6,10,0,1);
	gtk_widget_show(e1);

	l1 = rightjust_gtk_label_new(_("Free space:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,6,1,2);
	gtk_widget_show(l1);
	e1 = gtk_entry_new();
	imglist_l2 = e1;
	gtk_entry_set_editable(GTK_ENTRY(e1),FALSE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,6,10,1,2);
	gtk_widget_show(e1);
	define_tooltip(e1, _("If the Image Directory is set to \"Automatic\" this is the free hard disk space of all the image directories: Data / Audio"));

	sep = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(actionspace),sep,FALSE,FALSE,10);
	gtk_widget_show(sep);

	/* button bar at the bottom */
	hbox = gtk_hbox_new(FALSE,5);
	gtk_box_pack_start(GTK_BOX(actionspace),hbox,FALSE,TRUE,0);
	gtk_widget_show(hbox);

	b1 = gtk_button_new_with_label(_("Select all"));
	gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
	gtk_widget_show(b1);
	gtk_signal_connect(GTK_OBJECT(b1),"clicked",
		GTK_SIGNAL_FUNC(delete_select_all), NULL);
	define_tooltip(b1,_("Selects all displayed tracks."));

	b1 = gtk_button_new_with_label(_("Select none"));
	gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
	gtk_widget_show(b1);
	gtk_signal_connect(GTK_OBJECT(b1),"clicked",
		GTK_SIGNAL_FUNC(delete_select_none), NULL);
	define_tooltip(b1,_("Deselects all tracks."));

	dummy = gtk_label_new("");
	gtk_box_pack_start(GTK_BOX(hbox),dummy,FALSE,FALSE,10);
	gtk_widget_show(dummy);

	b1 = gtk_button_new_with_label(_("Delete selected tracks"));
	gtk_box_pack_start(GTK_BOX(hbox),b1,TRUE,TRUE,10);
	gtk_widget_show(b1);
	gtk_signal_connect(GTK_OBJECT(b1),"clicked",
		GTK_SIGNAL_FUNC(do_delete_press), NULL);
	define_tooltip(b1,_("Deletes all selected Tracks. Hint: A doubleclick on a TOC-file in the list will select all tracks specified in it."));

	gtk_widget_show(actionspace);

	/* fill entries */
	fill_delete_menu();
}


/*
 * unselects all buttons on the sidebar (except the one given)
 * So there is always only one selected
 */
static void reset_duplicate_buttons(GtkWidget *exclude) {
int i;

	for (i = 0; i < 7; i++) {
		if (side_widgets[i] != exclude) {
			gtk_signal_handler_block(GTK_OBJECT(side_widgets[i]),side_handlers[i]);
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(side_widgets[i]),0);
			gtk_signal_handler_unblock(GTK_OBJECT(side_widgets[i]),side_handlers[i]);
		}
	}

	/*
	 * since this is called whenever somebody clicks on a
	 * sidebar button, we can here check if the wav-player
	 * process from "play track" is still running, when the
	 * user quits this menu. So lets care here that it is
	 * terminated in a nice way
	 */
	if (wav_in != -1) {
		do_lock(0);

		/* we want to quit the wavplayer.. */
		wavplay_quit = 1;

		/* simulate quit-button-press */
		gtk_button_clicked(GTK_BUTTON(wav_quit_button));

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

		/* now give gtk some extra time to initialize */
		for (i = 0; i < 3; i++) {
			wait_and_process_events();
		}

		do_unlock(0);
	}
} 

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

	/* if button already pressed ignore and undo click */
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == 0) {
		gtk_signal_handler_block(GTK_OBJECT(widget),side_handlers[0]);
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),1);
		gtk_signal_handler_unblock(GTK_OBJECT(widget),side_handlers[0]);
		return;
	}
	reset_duplicate_buttons(widget);

	dolog(2, "Entering duplicate: info menu\n");
	draw_info_menu();
}

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

	/* if button already pressed ignore and undo click */
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == 0) {
		gtk_signal_handler_block(GTK_OBJECT(widget),side_handlers[1]);
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),1);
		gtk_signal_handler_unblock(GTK_OBJECT(widget),side_handlers[1]);
		return;
	}
	reset_duplicate_buttons(widget);

	dolog(2, "Entering duplicate: read menu\n");
	draw_read_menu();
}

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

	/* if button already pressed ignore and undo click */
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == 0) {
		gtk_signal_handler_block(GTK_OBJECT(widget),side_handlers[2]);
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),1);
		gtk_signal_handler_unblock(GTK_OBJECT(widget),side_handlers[2]);
		return;
	}
	reset_duplicate_buttons(widget);

	dolog(2, "Entering duplicate: verify menu\n");
	draw_verify_menu();
}

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

	/* if button already pressed ignore and undo click */
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == 0) {
		gtk_signal_handler_block(GTK_OBJECT(widget),side_handlers[3]);
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),1);
		gtk_signal_handler_unblock(GTK_OBJECT(widget),side_handlers[3]);
		return;
	}
	reset_duplicate_buttons(widget);

	dolog(2, "Entering duplicate: play menu\n");
	draw_play_tracks_menu();
}

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

	/* if button already pressed ignore and undo click */
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == 0) {
		gtk_signal_handler_block(GTK_OBJECT(widget),side_handlers[4]);
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),1);
		gtk_signal_handler_unblock(GTK_OBJECT(widget),side_handlers[4]);
		return;
	}
	reset_duplicate_buttons(widget);

	dolog(2, "Entering duplicate: write menu\n");
	draw_write_menu();
}

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

	/* if button already pressed ignore and undo click */
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == 0) {
		gtk_signal_handler_block(GTK_OBJECT(widget),side_handlers[5]);
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),1);
		gtk_signal_handler_unblock(GTK_OBJECT(widget),side_handlers[5]);
		return;
	}

	reset_duplicate_buttons(widget);

	dolog(2, "Entering duplicate: delete menu\n");
	draw_delete_menu();
}

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

	reset_duplicate_buttons(widget);
	create_main(0);
}


/*
 * called by the duplicate-button
 */
void create_duplicate() {
GtkWidget *side_t;
GtkWidget *head,*head_l;
GtkWidget *b1;
GtkWidget *xcdroast_logo;

	submenu = 1;
	clear_sidespace();
	clear_workspace();

        /* load the small xcdrlogo logo */
 	xcdroast_logo = display_logo(img.xcdrlogo_small, "[LOGO]");

	/* sidespace */
	side_t = gtk_table_new(10,1, TRUE);
	gtk_table_set_row_spacings(GTK_TABLE(side_t),10);
	gtk_box_pack_start(GTK_BOX(sidespace), side_t,TRUE,TRUE,0);

	head = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(head),GTK_SHADOW_NONE);
	gtk_widget_set_size_request(head, -1, 45);
	gtk_table_attach_defaults(GTK_TABLE(side_t), head, 0,1,0,1);
	gtk_widget_show(head);
	gtk_container_add(GTK_CONTAINER(head), xcdroast_logo);
#if DISPLAY_SIDEBAR_LOGO
        gtk_widget_show(xcdroast_logo);
#endif

	b1 = gtk_toggle_button_new_with_label(_("Disc/Image Info"));
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,1,2);
	/* preselect the first button */
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b1),1);
	gtk_widget_show(b1);
	side_handlers[0] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_duplicate_info),NULL);	
	side_widgets[0] = b1;
	define_tooltip(b1,_("Displays information about the currently inserted Disc and tracks stored on the hard disk."));

	if (!curset.isProDVD) {
		b1 = gtk_toggle_button_new_with_label(_("Read Disc"));
	} else {
		b1 = gtk_toggle_button_new_with_label(_("Read CD/DVD"));
	}
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,2,3);
	gtk_widget_show(b1);
	side_handlers[1] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_duplicate_read),NULL);	
	side_widgets[1] = b1;
	define_tooltip(b1,_("Reads all tracks of a Disc and copy them to the hard disk."));

	if (!curset.isProDVD) {
		b1 = gtk_toggle_button_new_with_label(_("Verify Disc"));
	} else {
		b1 = gtk_toggle_button_new_with_label(_("Verify CD/DVD"));
	}
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,3,4);
	gtk_widget_show(b1);
	side_handlers[2] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_duplicate_verify),NULL);	
	side_widgets[2] = b1;
	define_tooltip(b1,_("Reads all tracks of a Disc again and compares them with the tracks saved on the hard disk."));

	b1 = gtk_toggle_button_new_with_label(_("Play Audio-Tracks"));
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,4,5);
	gtk_widget_show(b1);
	side_handlers[3] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_duplicate_play),NULL);	
	side_widgets[3] = b1;
	define_tooltip(b1,_("Plays audio tracks (.wav files) from the hard disk via soundcard."));

	if (!curset.isProDVD) {
		b1 = gtk_toggle_button_new_with_label(_("Write Disc"));
	} else {
		b1 = gtk_toggle_button_new_with_label(_("Write CD/DVD"));
	}
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,5,6);
	gtk_widget_show(b1);
	side_handlers[4] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_duplicate_write),NULL);	
	side_widgets[4] = b1;
	define_tooltip(b1,_("Writes tracks to a Disc: Will read the tracks from the hard disk or copies them on-the-fly from from another Disc."));

	b1 = gtk_toggle_button_new_with_label(_("Delete Tracks"));
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,6,7);
	gtk_widget_show(b1);
	side_handlers[5] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_duplicate_delete),NULL);	
	side_widgets[5] = b1;
	define_tooltip(b1,_("Deletes saved Tracks from the hard disk to free up space."));

	b1 = gtk_toggle_button_new_with_label(_("Back to main menu"));
	gtk_table_attach_defaults(GTK_TABLE(side_t), b1, 0,1,8,9);
	gtk_widget_show(b1);
	side_handlers[6] = gtk_signal_connect (GTK_OBJECT (b1), "clicked",
		GTK_SIGNAL_FUNC(menu_duplicate_back),NULL);	
	side_widgets[6] = b1;
	define_tooltip(b1,_("Quits the duplicate menu and returns to the main menu."));

	gtk_widget_show(side_t);
	gtk_widget_show(sidespace);

	/* draw workspace */

	head = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(head),GTK_SHADOW_IN);
	gtk_widget_set_size_request(head, -1, 45);
	gtk_box_pack_start(GTK_BOX(workspace), head,FALSE,FALSE,0);
	gtk_widget_show(head);
	head_l = gtk_label_new(_("Duplicate Disc"));
	set_font_and_color(head_l,PANGO_BIG,NULL);
	gtk_container_add(GTK_CONTAINER(head),head_l);
	gtk_widget_show(head_l);

	/* space where sub-windows are placed */
	actionspace = gtk_vbox_new(FALSE,0);
	gtk_box_pack_start(GTK_BOX(workspace), actionspace,TRUE,FALSE,0);

	gtk_widget_show(workspace);

	/* the default submenu for a start */
 	draw_info_menu();	
}

