/*  efx.c - EFX main
 *  Copyright (C) 1999  Charles <int@linuxcore.com>
 *
 *  EFXmms code (c) mld <mld@users.sourceforge.net>
 *
 *  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 *
 * $Id: efx.c,v 1.3 1999/12/27 13:08:25 int Exp $
 */



#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */

#include <unistd.h>
#include <errno.h>

#include <glib.h>
#include <gmodule.h>
#include <gtk/gtk.h>

#include <xmms/plugin.h>
#include <xmms/configfile.h>
#include <xmms/util.h>

#include "efx.h"

static void make_gui ();
static void init ();
static void cleanup ();

static int mod_samples (gpointer * d, gint length, AFormat afmt, gint srate,
			gint nch);
static char *strip_path (gchar * path);

static void efx_configwrite_end ();
static void efx_configwrite ();
static void efx_configread ();

GList *installed_efx_list = 0;
GList *active_efx_list = 0;

GtkWidget *efxwindow = NULL;

EffectPlugin efx_ep = {
	NULL,
	NULL,
	NULL,				/* Description */
	init,
	cleanup,
	show_about_dialog,		/* about */
	make_gui,			/* GUI */
	mod_samples,			/* Effect */
	NULL
};

EffectPlugin *get_eplugin_info (void)
{
        efx_ep.description = g_strdup_printf(_("EFXmms Plugin %s"), VERSION);
	return &efx_ep;
}

void show_about_plugin (EffectPlugin * efx)
{
	if (!efx || !efx->about)
	{
		show_about_dialog ();
	}
	else
	{
		efx->about ();
	}
}


static void init ()
{
	GList *entry, *e;
	EffectPlugin *effect;

	entry = get_effect_list ();

	for (e = entry; e != NULL; e = e->next)
	{
		effect = e->data;
		if (effect && effect->filename)
		{

			/* "Censor us out */
			if (strcasecmp
			    (strip_path (effect->filename), "libefx.so"))
			{
				if (effect && effect->mod_samples)
					//g_print ("\t%s", effect->description);
					//g_print ("\t%s", effect->filename);

					installed_efx_list =
						g_list_append
						(installed_efx_list, effect);

			}
		}
	}

	efx_configread ();
	g_list_free (e);
	return;
}

static void cleanup ()
{
	g_list_free (installed_efx_list);
	g_list_free (active_efx_list);
	return;
}


static int mod_samples (gpointer * d, gint length, AFormat afmt, gint srate,
			gint nch)
{
	int sz;
	GList *e;
	EffectPlugin *effect;


	sz = length;
	if (sz < 0)
		return 0;

	for (e = g_list_copy (active_efx_list); e != NULL; e = e->next)
	{
		effect = e->data;
		sz = effect->mod_samples (d, sz, afmt, srate, nch);
	}
	g_list_free (e);
	return sz;
}

static void make_gui ()
{
	GtkWidget *vbox, *w;
	GtkWidget *button_box;
	GtkWidget *ok_button, *cancel_button, *apply_button;

	if (!efxwindow)
	{
		efxwindow = gtk_window_new (GTK_WINDOW_DIALOG);

		gtk_window_set_title (GTK_WINDOW (efxwindow),
				      _("EFXmms - Configuration"));
		gtk_container_set_border_width (GTK_CONTAINER (efxwindow), 5);
		gtk_window_set_policy (GTK_WINDOW (efxwindow), FALSE, TRUE,
				       FALSE);
		gtk_window_set_position (GTK_WINDOW (efxwindow),
					 GTK_WIN_POS_MOUSE);
		gtk_window_set_default_size (GTK_WINDOW (efxwindow), 240 * 2,
					     128 * 2);
		gtk_signal_connect (GTK_OBJECT (efxwindow), "destroy",
				    GTK_SIGNAL_FUNC (gtk_widget_destroyed),
				    &efxwindow);

		vbox = gtk_vbox_new (FALSE, 8);

		w = create_plugins_page ();
		gtk_box_pack_start (GTK_BOX (vbox), w, TRUE, TRUE, 0);

/*ok, close, apply buttons */
		button_box = gtk_hbutton_box_new ();
		gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box),
					   GTK_BUTTONBOX_END);
		gtk_button_box_set_spacing (GTK_BUTTON_BOX (button_box), 5);
		gtk_box_pack_start (GTK_BOX (vbox), button_box, FALSE, FALSE,
				    0);

		apply_button = gtk_button_new_with_label (_("Apply"));
		GTK_WIDGET_SET_FLAGS (apply_button, GTK_CAN_DEFAULT);
		gtk_signal_connect_object (GTK_OBJECT (apply_button),
					   "clicked",
					   GTK_SIGNAL_FUNC (efx_configwrite),
					   NULL);

		cancel_button = gtk_button_new_with_label (_("Cancel"));
		GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT);
		gtk_signal_connect_object (GTK_OBJECT (cancel_button),
					   "clicked",
					   GTK_SIGNAL_FUNC
					   (gtk_widget_destroy),
					   GTK_OBJECT (efxwindow));

		ok_button = gtk_button_new_with_label (_("Ok"));
		GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
		gtk_widget_grab_default (ok_button);
		gtk_signal_connect_object (GTK_OBJECT (ok_button), "clicked",
					   GTK_SIGNAL_FUNC
					   (efx_configwrite_end), NULL);

		gtk_box_pack_start_defaults (GTK_BOX (button_box), ok_button);
		gtk_box_pack_start_defaults (GTK_BOX (button_box),
					     cancel_button);
		gtk_box_pack_start_defaults (GTK_BOX (button_box),
					     apply_button);

/* Finished*/
		gtk_container_add (GTK_CONTAINER (efxwindow), vbox);
		gtk_widget_show_all (efxwindow);

	}
	else
	{
		gdk_window_raise (efxwindow->window);
	}
}

static char *strip_path (gchar * path)
{
	gchar *effectname;

	effectname = (g_strdup_printf ("%s", strrchr (path, '/')));
	effectname++;		/* Skip slash */
	return effectname;
}


static void efx_configwrite_end ()
{
	gtk_widget_destroy (efxwindow);
	efx_configwrite ();
	return;
}


static void efx_configwrite ()
{
	GList *e;
	ConfigFile *cfg;
	EffectPlugin *effect;
	gchar *effectname = NULL;
	gchar *list;

	effectname = "";
	list = "";

	for (e = active_efx_list; e != NULL; e = e->next)
	{
		effect = e->data;
		if (effect && effect->filename)
		{
			effectname = strip_path (effect->filename);
			list = (g_strdup_printf ("%s%s;", list, effectname));
		}
	}

	/* write Configfile */
	cfg = xmms_cfg_open_default_file ();
	xmms_cfg_write_string (cfg, "efx", "effect_plugins", list);
	xmms_cfg_write_default_file (cfg);
	xmms_cfg_free (cfg);

	return;
}

static void efx_configread ()
{
	ConfigFile *cfg;
	EffectPlugin *effect;
	GList *e;
	gchar *list = "";
	gchar *c;
	gchar *cfg_effect;
	int len;

	cfg = xmms_cfg_open_default_file ();
	xmms_cfg_read_string (cfg, "efx", "effect_plugins", &list);

	xmms_cfg_free (cfg);

	while (strlen (list) != 0)
	{
		len =
			strlen (list) -
			strlen (g_strdup_printf ("%s", strchr (list, ';')));
		if (len != 0)
		{
			cfg_effect = g_strndup (list, len);
			for (e = installed_efx_list; e != NULL; e = e->next)
			{
				effect = e->data;
				if (effect && effect->filename)
				{
					if (!strcasecmp
					    (cfg_effect,
					     strip_path (effect->filename)))
					{
						active_efx_list =
							g_list_append
							(active_efx_list,
							 effect);
					}
				}
			}
		}
		list = g_strdup_printf ("%s", strchr (list, ';'));
		list++;
	}
	return;
}

