/*
 * XMP plugin for XMMS
 * Written by Claudio Matsuoka <claudio@helllabs.org>, 2000-04-30
 * Based on J. Nick Koston's MikMod plugin
 */

#include "xmp-plugin.h"
#include "xmms/configfile.h"
#include "xmms/util.h"
#include <gtk/gtk.h>

#include "xmp.h"
#include "xmpi.h"
#include "driver.h"
#include "formats.h"

static void	init		(void);
static int	is_our_file	(char *);
static void	play_file	(char *);
static int	get_time	(void);
static void	stop(void);
static void	*play_loop	(void *);
static void	mod_pause	(short);
static void	seek		(int time);
static void	aboutbox	(void);
static void	get_song_info	(char *, char **, int *);
static void	configure	(void);
static void	config_ok	(GtkWidget *, gpointer);
static void	file_info_box	(char *);

static struct xmp_control ctl;

static pthread_t decode_thread;
static pthread_mutex_t load_mutex = PTHREAD_MUTEX_INITIALIZER;

XMPConfig xmp_cfg;
extern gboolean xmp_xmms_audio_error;
extern InputPlugin xmp_ip;

/* module parameters */
gboolean xmp_going = 0;

static GtkWidget *Res_16;
static GtkWidget *Res_8;
static GtkWidget *Chan_ST;
static GtkWidget *Chan_MO;
static GtkWidget *Sample_44;
static GtkWidget *Sample_22;
static GtkWidget *Sample_11;
static GtkWidget *Convert_Check;
static GtkWidget *Fixloops_Check;
static GtkWidget *Modrange_Check;
static GtkWidget *Interp_Check;
static GtkObject *pansep_adj;

static GtkWidget *xmp_conf_window = NULL;
static GtkWidget *about_window = NULL;


InputPlugin xmp_ip = {
	NULL,			/* handle */
	NULL,			/* filename */
	"XMP Player " VERSION,	/* description */
	init,			/* init */
	aboutbox,		/* about */
	configure,		/* configure */
	is_our_file,		/* is_our_file */
	NULL,			/* scan_dir */
	play_file,		/* play_file */
	stop,			/* stop */
	mod_pause,		/* pause */
	seek,			/* seek */
	NULL,			/* set_eq */
	get_time,		/* get_time */
	NULL,			/* get_volume */
	NULL,			/* set_volume */
	NULL,			/* add_vis -- obsolete */
	NULL,			/* get_vis_type -- obsolete */
	NULL,			/* add_vis_pcm */
	NULL,			/* set_info */
	NULL,			/* set_info_text */
	get_song_info,		/* get_song_info */
	file_info_box,		/* file_info_box */
	NULL			/* output */
};


static void aboutbox ()
{
	GtkWidget *dialog_vbox1;
	GtkWidget *hbox1;
	GtkWidget *label1;
	GtkWidget *dialog_action_area1;
	GtkWidget *about_exit;

	if (about_window) {
		gdk_window_raise(about_window->window);
		return;
	}

	about_window = gtk_dialog_new();
	gtk_object_set_data(GTK_OBJECT(about_window),
		"about_window", about_window);
	gtk_window_set_title(GTK_WINDOW(about_window), "About xmp plugin");
	gtk_window_set_policy(GTK_WINDOW(about_window), FALSE, FALSE, FALSE);
	gtk_window_set_position(GTK_WINDOW(about_window), GTK_WIN_POS_MOUSE);
	gtk_signal_connect(GTK_OBJECT(about_window), "destroy",
		GTK_SIGNAL_FUNC(gtk_widget_destroyed), &about_window);
	gtk_container_border_width(GTK_CONTAINER(about_window), 10);

	dialog_vbox1 = GTK_DIALOG(about_window)->vbox;
	gtk_object_set_data(GTK_OBJECT(about_window),
			"dialog_vbox1", dialog_vbox1);
	gtk_widget_show(dialog_vbox1);
	gtk_container_border_width(GTK_CONTAINER(dialog_vbox1), 5);

	hbox1 = gtk_hbox_new(FALSE, 0);
	gtk_object_set_data(GTK_OBJECT(about_window), "hbox1", hbox1);
	gtk_widget_show(hbox1);
	gtk_box_pack_start(GTK_BOX(dialog_vbox1), hbox1, TRUE, TRUE, 0);
	gtk_container_border_width(GTK_CONTAINER(hbox1), 5);
	gtk_widget_realize(about_window);

	label1 = gtk_label_new(
		"Extended Module Player " VERSION "\n"
		"http://xmp.helllabs.org\n"
		"Written by Claudio Matsuoka <claudio@helllabs.org>\n"
		"and Hipolito Carraro Jr. <hipolito@onda.com.br>"
		"\n\nWARNING: This plugin is experimental. Please\n"
		"report bugs to xmp-bugs@helllabs.org"
	);
	gtk_object_set_data(GTK_OBJECT(about_window), "label1", label1);
	gtk_widget_show(label1);
	gtk_box_pack_start(GTK_BOX(hbox1), label1, TRUE, TRUE, 0);

	dialog_action_area1 = GTK_DIALOG(about_window)->action_area;
	gtk_object_set_data(GTK_OBJECT(about_window),
		"dialog_action_area1", dialog_action_area1);
	gtk_widget_show(dialog_action_area1);
	gtk_container_border_width(GTK_CONTAINER(dialog_action_area1), 10);

	about_exit = gtk_button_new_with_label("Ok");
	gtk_signal_connect_object(GTK_OBJECT(about_exit), "clicked",
		GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(about_window));

	gtk_object_set_data(GTK_OBJECT(about_window), "about_exit", about_exit);
	gtk_widget_show(about_exit);
	gtk_box_pack_start(GTK_BOX(dialog_action_area1),
		about_exit, TRUE, TRUE, 0);

	gtk_widget_show(about_window);
}


static void stop (void)
{
	if (!xmp_going)
		return;

	_D("*** stop!");
	xmp_stop_module (); 
	pthread_join (decode_thread, NULL);
}


static void seek (int time)
{
	/*
	   We need to seek in pattrens somehow
	   can't seek by time only by X patterns on way or the other

	   Player_NextPosition ();
	   Player_PrevPosition ();

	 */
	return;
}


static void mod_pause (short p)
{
	xmp_ip.output->pause(p);
}


static int get_time (void)
{
	if (xmp_xmms_audio_error)
		return -2;
	if (!xmp_going)
		return -1;
#if 0
	if(!Player_Active() && !xmp_ip.output->buffer_playing())
		return -1;
#endif
	return xmp_ip.output->output_time();
}


InputPlugin *get_iplugin_info (void)
{
	return &xmp_ip;
}


static void init(void)
{
	ConfigFile *cfg;
	gchar *filename;

	xmp_cfg.mixing_freq = 0;
	xmp_cfg.convert8bit = 0;
	xmp_cfg.fixloops = 0;
	xmp_cfg.modrange = 0;
	xmp_cfg.force8bit = 0;
	xmp_cfg.force_mono = 0;
	xmp_cfg.interpolation = TRUE;
	xmp_cfg.pan_amplitude = 80;

#define CFGREADINT(x) xmms_cfg_read_int (cfg, "XMP", #x, &xmp_cfg.##x)

	filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL);
	if ((cfg = xmms_cfg_open_file(filename))) {
		CFGREADINT (mixing_freq);
		CFGREADINT (force8bit);
		CFGREADINT (convert8bit);
		CFGREADINT (modrange);
		CFGREADINT (fixloops);
		CFGREADINT (force_mono);
		CFGREADINT (interpolation);
		CFGREADINT (pan_amplitude);

		xmms_cfg_free(cfg);
	}

	xmp_drv_register (&drv_xmms);
	xmp_init_formats ();

	memset (&ctl, 0, sizeof (struct xmp_control));
	xmp_event_callback = NULL;

	xmp_drv_mutelloc (64);
}


static int is_our_file (char *filename)
{
	int i;

	/* Checking files by extension is braindead, we should check
	 * by file magic instead. But the xmp interface is also braindead
	 * in the point that it doesn't allow us to load a module while
	 * the audio device isn't selected. Yuck.
	 *
	 * Additionally, xmp 2.0 can't load a module while another module
	 * is playing, so it can't check if the module is valid or not.
	 * In this case, we'll blindly accept the file.
	 */

	if (xmp_going)
		return 1;

	pthread_mutex_lock (&load_mutex);

	ctl.maxvoc = 16;
	ctl.drv_id = "xmms_mix";
	ctl.verbose = 0;
	ctl.memavl = 0;
	xmp_drv_set (&ctl);

	_D("checking: %s", filename);
	i = xmp_load_module (filename) >= 0;
	_D("  returned %d", i);

	pthread_mutex_unlock (&load_mutex);

	return i;
}


static void get_song_info(char *filename, char **title, int *length)
{
	char *x;

	/* Ugh. xmp doesn't allow me to load and scan a module while
	 * playing. Must fix this.
	 */
	_D("song_info: %s", filename);
	if ((x = strrchr (filename, '/')))
		filename = ++x;
	*title = g_strdup (filename);
}


static void play_file(char *filename)
{
	struct xmp_module_info mi;
	int channelcnt = 1;
	int format = FMT_U8;
	FILE *f;
	char *info;
	
	_D("play_file: %s", filename);

	stop ();	/* sanity check */

	if(!(f = fopen(filename,"rb"))) {
		xmp_going = 0;
		return;
	}
	fclose(f);

	xmp_xmms_audio_error = FALSE;
	xmp_going = 1;
	ctl.resol = 8;
	ctl.verbose = 0;
	ctl.drv_id = "xmms_mix";

	switch (xmp_cfg.mixing_freq) {
	case 1:
		ctl.freq = 22050;	/* 1:2 mixing freq */
		break;
	case 2:
		ctl.freq = 11025;	/* 1:4 mixing freq */
		break;
	default:
		ctl.freq = 44100;	/* standard mixing freq */
		break;
	}

	if ((xmp_cfg.force8bit == 0)) {
		format = FMT_S16_NE;
		ctl.resol = 16;
	}

	if ((xmp_cfg.force_mono == 0)) {
		channelcnt = 2;
	} else {
		ctl.outfmt |= XMP_FMT_MONO;
	}

	if ((xmp_cfg.interpolation == 1))
		ctl.flags |= XMP_CTL_ITPT;

	ctl.mix = xmp_cfg.pan_amplitude;

	pthread_mutex_lock (&load_mutex);

	xmp_open_audio (&ctl);
	if (xmp_load_module (filename) < 0) {
		xmp_ip.set_info_text("Error loading mod");
		xmp_going = 0;
		return;
	}

	xmp_get_module_info (&mi);

	pthread_mutex_unlock (&load_mutex);

	info = malloc (strlen (mi.name) + strlen (mi.type) + 20);
	sprintf (info, "%s [%s, %d ch]", mi.name, mi.type, mi.chn);

	xmp_ip.set_info(info, -1, 128 * 1000, ctl.freq, channelcnt);
	free (info);

	_D("--- pthread_create");
	pthread_create(&decode_thread, NULL, play_loop, NULL);

	return;
}


static void *play_loop (void *arg)
{
	xmp_play_module ();
	xmp_close_audio ();
	xmp_going = 0;
	_D("--- pthread_exit");
	pthread_exit(NULL);
}


static void configure()
{
	GtkWidget *notebook1;
	GtkWidget *vbox;
	GtkWidget *vbox1;
	GtkWidget *hbox1;
	GtkWidget *Resolution_Frame;
	GtkWidget *vbox4;
	GSList *resolution_group = NULL;
	GtkWidget *Channels_Frame;
	GtkWidget *vbox5;
	GSList *vbox5_group = NULL;
	GtkWidget *Downsample_Frame;
	GtkWidget *vbox3;
	GSList *sample_group = NULL;
	GtkWidget *vbox6;
	GtkWidget *Quality_Label;
	GtkWidget *Options_Label;
	GtkWidget *pansep_label, *pansep_hscale;
	GtkWidget *bbox;
	GtkWidget *ok;
	GtkWidget *cancel;

	if (xmp_conf_window) {
		gdk_window_raise(xmp_conf_window->window);
		return;
	}
	xmp_conf_window = gtk_window_new(GTK_WINDOW_DIALOG);
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window),
		"xmp_conf_window", xmp_conf_window);
	gtk_window_set_title(GTK_WINDOW(xmp_conf_window), "XMP Configuration");
	gtk_window_set_policy(GTK_WINDOW(xmp_conf_window), FALSE, FALSE, FALSE);
	gtk_window_set_position(GTK_WINDOW(xmp_conf_window), GTK_WIN_POS_MOUSE);
	gtk_signal_connect(GTK_OBJECT(xmp_conf_window), "destroy",
		GTK_SIGNAL_FUNC(gtk_widget_destroyed),&xmp_conf_window);
	gtk_container_border_width(GTK_CONTAINER(xmp_conf_window), 10);

	vbox = gtk_vbox_new(FALSE, 10);
	gtk_container_add(GTK_CONTAINER(xmp_conf_window), vbox);

	notebook1 = gtk_notebook_new();
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window),"notebook1", notebook1);
	gtk_widget_show(notebook1);
	gtk_box_pack_start(GTK_BOX(vbox), notebook1, TRUE, TRUE, 0);
	gtk_container_border_width(GTK_CONTAINER(notebook1), 3);

	vbox1 = gtk_vbox_new(FALSE, 0);
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window),"vbox1", vbox1);
	gtk_widget_show(vbox1);

	hbox1 = gtk_hbox_new(FALSE, 0);
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window),"hbox1", hbox1);
	gtk_widget_show(hbox1);
	gtk_box_pack_start(GTK_BOX(vbox1), hbox1, TRUE, TRUE, 0);

	Resolution_Frame = gtk_frame_new("Resolution");
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window),
		"Resolution_Frame", Resolution_Frame);
	gtk_widget_show(Resolution_Frame);
	gtk_box_pack_start(GTK_BOX(hbox1), Resolution_Frame, TRUE, TRUE, 0);
	gtk_container_set_border_width(GTK_CONTAINER (Resolution_Frame), 5);

	vbox4 = gtk_vbox_new(FALSE, 0);
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window),"vbox4", vbox4);
	gtk_widget_show(vbox4);
	gtk_container_add(GTK_CONTAINER(Resolution_Frame), vbox4);

	Res_16 = gtk_radio_button_new_with_label(resolution_group, "16 bit");
	resolution_group = gtk_radio_button_group(GTK_RADIO_BUTTON(Res_16));
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window), "Res_16", Res_16);
	gtk_widget_show(Res_16);
	gtk_box_pack_start(GTK_BOX(vbox4), Res_16, TRUE, TRUE, 0);
	if (xmp_cfg.force8bit == 0)
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Res_16), TRUE);

	Res_8 = gtk_radio_button_new_with_label(resolution_group, "8 bit");
	resolution_group = gtk_radio_button_group(GTK_RADIO_BUTTON(Res_8));
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window), "Res_8", Res_8);
	gtk_widget_show(Res_8);
	gtk_box_pack_start(GTK_BOX(vbox4), Res_8, TRUE, TRUE, 0);
	if (xmp_cfg.force8bit == 1)
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Res_8), TRUE);

	Channels_Frame = gtk_frame_new("Channels");
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window),
		"Channels_Frame", Channels_Frame);
	gtk_widget_show(Channels_Frame);
	gtk_box_pack_start(GTK_BOX(hbox1), Channels_Frame, TRUE, TRUE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(Channels_Frame), 5);

	vbox5 = gtk_vbox_new(FALSE, 0);
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window), "vbox5", vbox5);
	gtk_widget_show(vbox5);
	gtk_container_add(GTK_CONTAINER(Channels_Frame), vbox5);

	Chan_ST = gtk_radio_button_new_with_label(vbox5_group, "Stereo");
	vbox5_group = gtk_radio_button_group(GTK_RADIO_BUTTON(Chan_ST));
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window), "Chan_ST", Chan_ST);
	gtk_widget_show(Chan_ST);
	gtk_box_pack_start(GTK_BOX(vbox5), Chan_ST, TRUE, TRUE, 0);
	if (xmp_cfg.force_mono == 0)
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Chan_ST), TRUE);

	Chan_MO = gtk_radio_button_new_with_label(vbox5_group, "Mono");
	vbox5_group = gtk_radio_button_group(GTK_RADIO_BUTTON(Chan_MO));
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window), "Chan_MO", Chan_MO);
	gtk_widget_show(Chan_MO);
	gtk_box_pack_start(GTK_BOX(vbox5), Chan_MO, TRUE, TRUE, 0);
	if (xmp_cfg.force_mono == 1)
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Chan_MO), TRUE);

	Downsample_Frame = gtk_frame_new("Sampling rate");
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window),
		"Downsample_Frame", Downsample_Frame);
	gtk_widget_show(Downsample_Frame);
	gtk_box_pack_start(GTK_BOX(vbox1), Downsample_Frame, TRUE, TRUE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(Downsample_Frame), 5);

	vbox3 = gtk_vbox_new(FALSE, 0);
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window), "vbox3", vbox3);
	gtk_widget_show(vbox3);
	gtk_container_add(GTK_CONTAINER(Downsample_Frame), vbox3);

	Sample_44 = gtk_radio_button_new_with_label(sample_group, "44 kHz");
	sample_group = gtk_radio_button_group(GTK_RADIO_BUTTON(Sample_44));
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window),"Sample_44", Sample_44);
	gtk_widget_show(Sample_44);
	gtk_box_pack_start(GTK_BOX(vbox3), Sample_44, TRUE, TRUE, 0);
	if (xmp_cfg.mixing_freq == FREQ_SAMPLE_44)
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Sample_44),TRUE);

	Sample_22 = gtk_radio_button_new_with_label(sample_group, "22 kHz)");
	sample_group = gtk_radio_button_group(GTK_RADIO_BUTTON(Sample_22));
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window), "Sample_22",Sample_22);
	gtk_widget_show(Sample_22);
	gtk_box_pack_start(GTK_BOX(vbox3), Sample_22, TRUE, TRUE, 0);
	if (xmp_cfg.mixing_freq == FREQ_SAMPLE_22)
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Sample_22),TRUE);

	Sample_11 = gtk_radio_button_new_with_label(sample_group, "11 kHz");
	sample_group = gtk_radio_button_group(GTK_RADIO_BUTTON(Sample_11));
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window), "Sample_11",Sample_11);
	gtk_widget_show(Sample_11);
	gtk_box_pack_start(GTK_BOX(vbox3), Sample_11, TRUE, TRUE, 0);
	if (xmp_cfg.mixing_freq == FREQ_SAMPLE_11)
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Sample_11),TRUE);

	vbox6 = gtk_vbox_new(FALSE, 0);
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window), "vbox6", vbox6);
	gtk_widget_show(vbox6);

	/* Options */

#define OPTCHECK(w,l,o) {						\
	w = gtk_check_button_new_with_label(l);				\
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window), #w, w);	\
	gtk_widget_show(w);						\
	gtk_box_pack_start(GTK_BOX(vbox6), w, TRUE, TRUE, 0);		\
	if (xmp_cfg.##o == 1)						\
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), TRUE); \
}

	OPTCHECK(Convert_Check, "Convert 16 bit samples to 8 bit", convert8bit);
	OPTCHECK(Fixloops_Check, "Fix sample loops", fixloops);
	OPTCHECK(Modrange_Check, "Force 3 octave range in standard MOD files",
		modrange);
	OPTCHECK(Interp_Check, "Enable 32-bit linear interpolation",
		interpolation);

	pansep_label = gtk_label_new("Pan amplitude (%)");
	gtk_widget_show(pansep_label);
	gtk_box_pack_start(GTK_BOX(vbox6), pansep_label, TRUE, TRUE, 0);
	pansep_adj = gtk_adjustment_new(xmp_cfg.pan_amplitude,
		0.0, 100.0, 1.0, 10.0, 1.0);
	pansep_hscale = gtk_hscale_new(GTK_ADJUSTMENT(pansep_adj));
	gtk_scale_set_digits(GTK_SCALE(pansep_hscale), 0);
	gtk_scale_set_draw_value(GTK_SCALE(pansep_hscale), TRUE);
	gtk_scale_set_value_pos(GTK_SCALE(pansep_hscale), GTK_POS_BOTTOM);
	gtk_widget_show(pansep_hscale);
	gtk_box_pack_start(GTK_BOX(vbox6), pansep_hscale, TRUE, TRUE, 0);

	Quality_Label = gtk_label_new("Quality");
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window),
		"Quality_Label", Quality_Label);
	gtk_widget_show(Quality_Label);
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), vbox1, Quality_Label);

	Options_Label = gtk_label_new("Options");
	gtk_object_set_data(GTK_OBJECT(xmp_conf_window),
		"Options_Label", Options_Label);
	gtk_widget_show(Options_Label);
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), vbox6, Options_Label);

	bbox = gtk_hbutton_box_new();
	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
	gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
	gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);

	ok = gtk_button_new_with_label("Ok");
	gtk_signal_connect(GTK_OBJECT(ok), "clicked",
		GTK_SIGNAL_FUNC(config_ok), NULL);
	GTK_WIDGET_SET_FLAGS(ok, GTK_CAN_DEFAULT);
	gtk_box_pack_start(GTK_BOX(bbox), ok, TRUE, TRUE, 0);
	gtk_widget_show(ok);
	gtk_widget_grab_default(ok);

	cancel = gtk_button_new_with_label("Cancel");
	gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked",
		GTK_SIGNAL_FUNC(gtk_widget_destroy),
		GTK_OBJECT(xmp_conf_window));
	GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT);
	gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0);
	gtk_widget_show(cancel);

	gtk_widget_show(bbox);

	gtk_widget_show(vbox);
	gtk_widget_show(xmp_conf_window);
}


static void config_ok (GtkWidget *widget, gpointer data)
{
	ConfigFile *cfg;
	gchar *filename;

	if (GTK_TOGGLE_BUTTON(Res_16)->active)
		xmp_cfg.force8bit = 0;
	if (GTK_TOGGLE_BUTTON(Res_8)->active)
		xmp_cfg.force8bit = 1;

	if (GTK_TOGGLE_BUTTON(Chan_ST)->active)
		xmp_cfg.force_mono = 0;
	if (GTK_TOGGLE_BUTTON(Chan_MO)->active)
		xmp_cfg.force_mono = 1;

	if (GTK_TOGGLE_BUTTON(Sample_44)->active)
		xmp_cfg.mixing_freq = 0;
	if (GTK_TOGGLE_BUTTON(Sample_22)->active)
		xmp_cfg.mixing_freq = 1;
	if (GTK_TOGGLE_BUTTON(Sample_11)->active)
		xmp_cfg.mixing_freq = 2;

	xmp_cfg.interpolation = !!GTK_TOGGLE_BUTTON(Interp_Check)->active;
	xmp_cfg.convert8bit = !!GTK_TOGGLE_BUTTON(Convert_Check)->active;
	xmp_cfg.modrange = !!GTK_TOGGLE_BUTTON(Modrange_Check)->active;
	xmp_cfg.fixloops = !!GTK_TOGGLE_BUTTON(Fixloops_Check)->active;

	xmp_cfg.pan_amplitude = (guchar)GTK_ADJUSTMENT(pansep_adj)->value;
        ctl.mix = xmp_cfg.pan_amplitude;

	filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL);
	cfg = xmms_cfg_open_file(filename);
	if (!cfg)
		cfg = xmms_cfg_new();

#define CFGWRITEINT(x) xmms_cfg_write_int (cfg, "XMP", #x, xmp_cfg.##x)

	CFGWRITEINT (mixing_freq);
	CFGWRITEINT (force8bit);
	CFGWRITEINT (convert8bit);
	CFGWRITEINT (modrange);
	CFGWRITEINT (fixloops);
	CFGWRITEINT (force_mono);
	CFGWRITEINT (interpolation);
	CFGWRITEINT (pan_amplitude);

	xmms_cfg_write_file(cfg, filename);
	xmms_cfg_free(cfg);
	g_free(filename);
	gtk_widget_destroy(xmp_conf_window);
}


static void file_info_box (char *filename)
{
}

