/*
 * Copyright (C) 1999 Dave Camp <dave@davec.dhs.org>
 *  
 * 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.
 *  
 */

#include <config.h>
#include <string.h>
#include <dirent.h>
#include <limits.h>
#include <ctype.h>
#include <gtk/gtk.h>
#include <mateconf/mateconf-client.h>
#include <mate-panel-applet-mateconf.h>
#include "geyes.h"

#define NUM_THEME_DIRECTORIES 2
#define HIG_IDENTATION  "    "

static char *theme_directories[NUM_THEME_DIRECTORIES];

enum {
	COL_THEME_DIR = 0,
	COL_THEME_NAME,
	TOTAL_COLS
};

void
theme_dirs_create (void)
{
	static gboolean themes_created = FALSE;
	
	if (themes_created == TRUE)
		return;

	theme_directories[0] = g_strdup (GEYES_THEMES_DIR);
	theme_directories[1] = g_strdup_printf ("%s/.mate2/geyes-themes/", g_get_home_dir());

	themes_created = TRUE;
}

static void
parse_theme_file (EyesApplet *eyes_applet, FILE *theme_file)
{
        gchar line_buf [512]; /* prolly overkill */
        gchar *token;
        fgets (line_buf, 512, theme_file);
        while (!feof (theme_file)) {
                token = strtok (line_buf, "=");
                if (strncmp (token, "wall-thickness", 
                             strlen ("wall-thickness")) == 0) {
                        token += strlen ("wall-thickness");
                        while (!isdigit (*token)) {
                                token++;
                        }
                        sscanf (token, "%d", &eyes_applet->wall_thickness); 
                } else if (strncmp (token, "num-eyes", strlen ("num-eyes")) == 0) {
                        token += strlen ("num-eyes");
                        while (!isdigit (*token)) {
                                token++;
                        }
                        sscanf (token, "%d", &eyes_applet->num_eyes);
			if (eyes_applet->num_eyes > MAX_EYES)
				eyes_applet->num_eyes = MAX_EYES;
                } else if (strncmp (token, "eye-pixmap", strlen ("eye-pixmap")) == 0) {
                        token = strtok (NULL, "\"");
                        token = strtok (NULL, "\"");          
                        if (eyes_applet->eye_filename != NULL) 
                                g_free (eyes_applet->eye_filename);
                        eyes_applet->eye_filename = g_strdup_printf ("%s%s",
                                                                    eyes_applet->theme_dir,
                                                                    token);
                } else if (strncmp (token, "pupil-pixmap", strlen ("pupil-pixmap")) == 0) {
                        token = strtok (NULL, "\"");
                        token = strtok (NULL, "\"");      
            if (eyes_applet->pupil_filename != NULL) 
                    g_free (eyes_applet->pupil_filename);
            eyes_applet->pupil_filename 
                    = g_strdup_printf ("%s%s",
                                       eyes_applet->theme_dir,
                                       token);   
                }
                fgets (line_buf, 512, theme_file);
        }       
}

int
load_theme (EyesApplet *eyes_applet, const gchar *theme_dir)
{
	GtkWidget *dialog;

	FILE* theme_file;
        gchar *file_name;

        eyes_applet->theme_dir = g_strdup_printf ("%s/", theme_dir);

        file_name = g_strdup_printf("%s%s",theme_dir,"/config");
        theme_file = fopen (file_name, "r");
        if (theme_file == NULL) {
        	g_free (eyes_applet->theme_dir);
        	eyes_applet->theme_dir = g_strdup_printf (GEYES_THEMES_DIR "Default-tiny/");
        	g_free (file_name);
                file_name = g_strdup (GEYES_THEMES_DIR "Default-tiny/config");
                theme_file = fopen (file_name, "r");
        }

	/* if it's still NULL we've got a major problem */
	if (theme_file == NULL) {
		dialog = gtk_message_dialog_new_with_markup (NULL,
				GTK_DIALOG_DESTROY_WITH_PARENT,
				GTK_MESSAGE_ERROR,
				GTK_BUTTONS_OK,
				"<b>%s</b>\n\n%s",
				_("Can not launch the eyes applet."),
				_("There was a fatal error while trying to load the theme."));

		gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);

		gtk_dialog_run (GTK_DIALOG (dialog));
		gtk_widget_destroy (dialog);

		gtk_widget_destroy (GTK_WIDGET (eyes_applet->applet));

		return FALSE;
	}

        parse_theme_file (eyes_applet, theme_file);
        fclose (theme_file);

        eyes_applet->theme_name = g_strdup (theme_dir);
       
        if (eyes_applet->eye_image)
        	g_object_unref (eyes_applet->eye_image);
        eyes_applet->eye_image = gdk_pixbuf_new_from_file (eyes_applet->eye_filename, NULL);
        if (eyes_applet->pupil_image)
        	g_object_unref (eyes_applet->pupil_image);
        eyes_applet->pupil_image = gdk_pixbuf_new_from_file (eyes_applet->pupil_filename, NULL);

	eyes_applet->eye_height = gdk_pixbuf_get_height (eyes_applet->eye_image);
        eyes_applet->eye_width = gdk_pixbuf_get_width (eyes_applet->eye_image);
        eyes_applet->pupil_height = gdk_pixbuf_get_height (eyes_applet->pupil_image);
        eyes_applet->pupil_width = gdk_pixbuf_get_width (eyes_applet->pupil_image);
        
        g_free (file_name);
   
	return TRUE;
}

static void
destroy_theme (EyesApplet *eyes_applet)
{
	/* Dunno about this - to unref or not to unref? */
	if (eyes_applet->eye_image != NULL) {
        	g_object_unref (eyes_applet->eye_image); 
        	eyes_applet->eye_image = NULL;
        }
        if (eyes_applet->pupil_image != NULL) {
        	g_object_unref (eyes_applet->pupil_image); 
        	eyes_applet->pupil_image = NULL;
	}
	
        g_free (eyes_applet->theme_dir);
        g_free (eyes_applet->theme_name);
}

static gboolean
key_writable (MatePanelApplet *applet, const char *key)
{
	gboolean writable;
	char *fullkey;
	static MateConfClient *client = NULL;

	if (client == NULL)
		client = mateconf_client_get_default ();

	fullkey = mate_panel_applet_mateconf_get_full_key (applet, key);

	writable = mateconf_client_key_is_writable (client, fullkey, NULL);

	g_free (fullkey);

	return writable;
}

static void
theme_selected_cb (GtkTreeSelection *selection, gpointer data)
{
	EyesApplet *eyes_applet = data;
	GtkTreeModel *model;
	GtkTreeIter iter;
	gchar *theme;
	gchar *theme_dir;
	
	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
		return;
	
	gtk_tree_model_get (model, &iter, COL_THEME_DIR, &theme, -1);
	
	g_return_if_fail (theme);
	
	theme_dir = g_strdup_printf ("%s/", theme);
	if (!g_ascii_strncasecmp (theme_dir, eyes_applet->theme_dir, strlen (theme_dir))) {
		g_free (theme_dir);
		return;
	}
	g_free (theme_dir);
		
	destroy_eyes (eyes_applet);
        destroy_theme (eyes_applet);
        load_theme (eyes_applet, theme);
        setup_eyes (eyes_applet);
	
	mate_panel_applet_mateconf_set_string (
		eyes_applet->applet, "theme_path", theme, NULL);
	
	g_free (theme);
}

static void
phelp_cb (GtkDialog *dialog)
{
	GError *error = NULL;

	gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (dialog)),
		"ghelp:geyes?geyes-settings",
		gtk_get_current_event_time (),
		&error);

	if (error) {
		GtkWidget *error_dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
								  _("There was an error displaying help: %s"), error->message);
		g_signal_connect (G_OBJECT (error_dialog), "response", G_CALLBACK (gtk_widget_destroy) , NULL);
		gtk_window_set_resizable (GTK_WINDOW (error_dialog), FALSE);
		gtk_window_set_screen (GTK_WINDOW (error_dialog), gtk_widget_get_screen (GTK_WIDGET (dialog)));
		gtk_widget_show (error_dialog);
		g_error_free (error);
		error = NULL;
	}
}

static void
presponse_cb (GtkDialog *dialog, gint id, gpointer data)
{
	EyesApplet *eyes_applet = data;
	if(id == GTK_RESPONSE_HELP){
		phelp_cb (dialog);
		return;
	}


	gtk_widget_destroy (GTK_WIDGET (dialog));

	eyes_applet->prop_box.pbox = NULL;
}

void
properties_cb (GtkAction  *action,
	       EyesApplet *eyes_applet)
{
	GtkWidget *pbox, *hbox;
	GtkWidget *vbox, *indent;
	GtkWidget *categories_vbox;
	GtkWidget *category_vbox, *control_vbox;
        GtkWidget *tree;
	GtkWidget *scrolled;
        GtkWidget *label;
        GtkListStore *model;
        GtkTreeViewColumn *column;
        GtkCellRenderer *cell;
        GtkTreeSelection *selection;
        GtkTreeIter iter;
        DIR *dfd;
        struct dirent *dp;
        int i;
#ifdef PATH_MAX
        gchar filename [PATH_MAX];
#else
	gchar *filename;
#endif
        gchar *title;
     
	if (eyes_applet->prop_box.pbox) {
		gtk_window_set_screen (
			GTK_WINDOW (eyes_applet->prop_box.pbox),
			gtk_widget_get_screen (GTK_WIDGET (eyes_applet->applet)));
		gtk_window_present (GTK_WINDOW (eyes_applet->prop_box.pbox));
		return;
	}

        pbox = gtk_dialog_new_with_buttons (_("Geyes Preferences"), NULL,
        				     GTK_DIALOG_DESTROY_WITH_PARENT,
					     GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
					     GTK_STOCK_HELP, GTK_RESPONSE_HELP,
					     NULL);

	gtk_window_set_screen (GTK_WINDOW (pbox),
			       gtk_widget_get_screen (GTK_WIDGET (eyes_applet->applet)));
        
	gtk_widget_set_size_request (GTK_WIDGET (pbox), 300, 200);
        gtk_dialog_set_default_response(GTK_DIALOG (pbox), GTK_RESPONSE_CLOSE);
        gtk_dialog_set_has_separator (GTK_DIALOG (pbox), FALSE);
        gtk_container_set_border_width (GTK_CONTAINER (pbox), 5);
	gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (pbox))), 2);

        g_signal_connect (pbox, "response",
			  G_CALLBACK (presponse_cb),
			  eyes_applet);
	
	vbox = gtk_vbox_new (FALSE, 0);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
	gtk_widget_show (vbox);
	
	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (pbox))), vbox,
			    TRUE, TRUE, 0);

	categories_vbox = gtk_vbox_new (FALSE, 18);
	gtk_box_pack_start (GTK_BOX (vbox), categories_vbox, TRUE, TRUE, 0);
	gtk_widget_show (categories_vbox);

	category_vbox = gtk_vbox_new (FALSE, 6);
	gtk_box_pack_start (GTK_BOX (categories_vbox), category_vbox, TRUE, TRUE, 0);
	gtk_widget_show (category_vbox);
	
	title = g_strconcat ("<span weight=\"bold\">", _("Themes"), "</span>", NULL);
	label = gtk_label_new (_(title));
	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
	gtk_box_pack_start (GTK_BOX (category_vbox), label, FALSE, FALSE, 0);
	g_free (title);
	
	hbox = gtk_hbox_new (FALSE, 0);
	gtk_box_pack_start (GTK_BOX (category_vbox), hbox, TRUE, TRUE, 0);
	gtk_widget_show (hbox);
	
	indent = gtk_label_new (HIG_IDENTATION);
	gtk_label_set_justify (GTK_LABEL (indent), GTK_JUSTIFY_LEFT);
	gtk_box_pack_start (GTK_BOX (hbox), indent, FALSE, FALSE, 0);
	gtk_widget_show (indent);
	
	control_vbox = gtk_vbox_new (FALSE, 6);
	gtk_box_pack_start (GTK_BOX (hbox), control_vbox, TRUE, TRUE, 0);
	gtk_widget_show (control_vbox);
	
	label = gtk_label_new_with_mnemonic (_("_Select a theme:"));
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
	gtk_box_pack_start (GTK_BOX (control_vbox), label, FALSE, FALSE, 0);

	scrolled = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
					GTK_POLICY_AUTOMATIC,
					GTK_POLICY_AUTOMATIC);

	model = gtk_list_store_new (TOTAL_COLS, G_TYPE_STRING, G_TYPE_STRING);
	tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree), FALSE);
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), tree);
	g_object_unref (model);

	gtk_container_add (GTK_CONTAINER (scrolled), tree);
	
	cell = gtk_cell_renderer_text_new ();
	column = gtk_tree_view_column_new_with_attributes ("not used", cell,
                                                           "text", COL_THEME_NAME, NULL);
        gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
                                                           
        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
	g_signal_connect (selection, "changed",
			  G_CALLBACK (theme_selected_cb),
			  eyes_applet);

	if ( ! key_writable (eyes_applet->applet, "theme_path")) {
		gtk_widget_set_sensitive (tree, FALSE);
		gtk_widget_set_sensitive (label, FALSE);
	}

        for (i = 0; i < NUM_THEME_DIRECTORIES; i++) {
                if ((dfd = opendir (theme_directories[i])) != NULL) {
                        while ((dp = readdir (dfd)) != NULL) {
                                if (dp->d_name[0] != '.') {
                                        gchar *theme_dir;
					gchar *theme_name;
#ifdef PATH_MAX
                                        strcpy (filename, 
                                                theme_directories[i]);
                                        strcat (filename, dp->d_name);
#else
					asprintf (&filename, theme_directories[i], dp->d_name);
#endif
					theme_dir = g_strdup_printf ("%s/", filename);
					theme_name = g_path_get_basename (filename);
					
                                        gtk_list_store_append (model, &iter);
                                        gtk_list_store_set (model, &iter,
							    COL_THEME_DIR, &filename,
							    COL_THEME_NAME, theme_name,
							    -1);
                                        
					if (!g_ascii_strncasecmp (eyes_applet->theme_dir, theme_dir, strlen (theme_dir))) {
                                        	GtkTreePath *path;
                                        	path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), 
                                                        			&iter);
                                                gtk_tree_view_set_cursor (GTK_TREE_VIEW (tree), 
                                                			  path, 
                                                			  NULL, 
                                                			  FALSE);
                                                gtk_tree_path_free (path);
                                        }
					g_free (theme_name);
                                        g_free (theme_dir);
                                }
                        }
                        closedir (dfd);
                }
        }
#ifndef PATH_MAX
	g_free (filename);
#endif
        
        gtk_box_pack_start (GTK_BOX (control_vbox), scrolled, TRUE, TRUE, 0);
        
        gtk_widget_show_all (pbox);
        
        eyes_applet->prop_box.pbox = pbox;
	
	return;
}