/*
 * Written 1997,2003 Jens Ch. Restemeier <jrestemeier@currantbun.com>
 * 
 * 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.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#ifdef WIN32

#else
#include <dirent.h>
#endif
#include <sys/stat.h>

#define GDK_DISABLE_DEPRECATED
//#define GTK_DISABLE_DEPRECATED

#include "gtk/gtk.h"
#include "libgimp/gimp.h"
#include "libgimp/gimpui.h"

#ifndef GIMP_VERSION
#include "../../lib/ui.h"
#include "../../lib/dialog.h"
/*#include "../../app/rc.c"*/
/*#define gimp_gimprc_set gimp_gimprc_set_token
#define gimp_gimprc_query gimprc_query*/

/* from app/rc.c */

typedef struct UnknownToken UnknownToken;

struct UnknownToken
{
  char *token;
  char *value;
};

static GList *unknown_tokens = NULL;

void
gimp_gimprc_set(char *token,
		  char *value)
{
  GList *list;
  UnknownToken *ut;

  list = unknown_tokens;
  while (list)
    {
      ut = (UnknownToken *) list->data;
      if (strcmp (ut->token, token) == 0)
	{
	  if (ut->value != value)
	    {
	      if (ut->value)
		g_free (ut->value);
	      ut->value = value;
	    }
	  break;
	}
      list = list->next;
    }
}

#endif

#include "uf_interface.h"
#include "uf_eval.h"
#include "uf_file.h"
#include "uf_main.h"
#include "uf_gui.h"

GtkWidget *dialog, *clist;
GtkObject *adjustment[8];

GtkWidget *preview;
GtkObject *prev_adj_x, *prev_adj_y;

GtkWidget *slider_value[8];
GtkWidget *source_text[4];

int result, preview_enable, gui_enable;

s_filter_data data;
char *scan_path;

void clear_filter_dir(GtkWidget *clist) 
{
	gint i;
	for (i = 0;i<GTK_CLIST(clist)->rows;i++) {
		gpointer p;
		p = gtk_clist_get_row_data(GTK_CLIST(clist), i);
		if (p != NULL) {
			free(p);
		}
	}
	gtk_clist_clear(GTK_CLIST(clist));
}

typedef struct FILEINFO {
	char *filename;
	long index;
} FILEINFO;

void readstring(char *s, int l, FILE *f)
{
	int t;
	if (l==0) return;
	if (s==NULL) return;
	t = 0;
	do {
		int c = fgetc( f );
		if (c == EOF) {
			s[t] = 0;
			return;
		} else if ( c == 0x0D ) {
			c = fgetc( f );
			if ( c != 0x0A ) {
				ungetc( c, f );
			}
			s[t] = 0;
			return;
		} else {
			s[t] = c;
		}
		t++;
	} while ((t+1)<l);
	s[t]=0;
}

int get_filter_from_library(FILE *f, long index, s_filter_data *filter)
{
	int i;
	fseek(f, index, SEEK_SET);
	if (feof(f)) return 0;
	readstring(filter->category, 256, f); /* filename, ignored */
	readstring(filter->category, 256, f);
	readstring(filter->title, 256, f);
	readstring(filter->author, 256, f);
	readstring(filter->copyright, 256, f);
	for(i=0; i<4; i++) {
		readstring(filter->map_label[i], 256, f);
	}
	for(i=0; i<8; i++) {
		readstring(filter->control_label[i], 256, f);
	}
	for(i=0; i<8; i++) {
		char val[10];
		readstring(val, 10, f);
		filter->control_value[i]=atoi(val);
	}
	for(i=0; i<4; i++) {
		readstring(filter->source[i], 8192, f);
	}
	return 1;
}

int scan_filter_library(char *s, GtkWidget *clist)
{
	FILE *f;
	char id[10], len[10];
	int num_filters, cnt;
	s_filter_data filter;
	f=fopen(s, "rb");
	if (f==NULL) return 0;
	readstring(id, sizeof(id), f);
	if (strcmp(id, "FFL1.0")!=0) return 0;
	readstring(len, sizeof(len), f);
	num_filters=atoi(len);
	for (cnt=0; cnt<num_filters; cnt++) {
		FILEINFO *fileinfo;
		fileinfo=(FILEINFO *)malloc(sizeof(FILEINFO));
		fileinfo->filename=strdup(s);
		fileinfo->index=ftell(f);
		if (get_filter_from_library(f, fileinfo->index, &filter)) {
			int row_num;
			char *text[5];
			text[0] = filter.category;
			text[1] = filter.title;
			text[2] = filter.author;
			text[3] = filter.copyright;
			text[4] = NULL;
			row_num = gtk_clist_append(GTK_CLIST(clist), text);
			gtk_clist_set_row_data(GTK_CLIST(clist), row_num, (gpointer)fileinfo);
		} else {
			free(fileinfo);
			cnt=num_filters;
		}
	}
	fclose(f);
	return 1;
}

void scan_filter_dir(char *path, GtkWidget *clist)
{
	DIR *dir;
	struct dirent *ent;
	struct stat filestat;
	s_filter_data filter;
	if (path == NULL) return;
	if (path[0] == 0) return;
	/*
	 * fix path
	 */
	if (path[0] == '~') {
		char *home, *tmp;
		home = getenv("HOME"); 
		tmp = malloc(strlen(home)+strlen(path)+1);
		sprintf(tmp, "%s%s", home, path+1);
		free(path);
		path = tmp;
	}
	if (path[strlen(path)] == '/') {
		path[strlen(path)]=0;
	}
	dir = opendir(path);
	if (dir==NULL) return;
	while ((ent = readdir(dir))) {
		if (ent->d_name[0] != '.') {
			int err;
			char *filename;
			filename = malloc(strlen(ent->d_name)+strlen(path)+2);
			sprintf(filename, "%s/%s", path, ent->d_name);
			
			err = stat(filename, &filestat);
			if (!err) {
				if (S_ISDIR(filestat.st_mode)) {
					scan_filter_dir(filename, clist);
				} else {
					if (load_filter(filename, &filter)) {
						int row_num;
						FILEINFO *fileinfo;
						char *text[5];
						text[0] = filter.category;
						text[1] = filter.title;
						text[2] = filter.author;
						text[3] = filter.copyright;
						text[4] = NULL;
						fileinfo=(FILEINFO*)malloc(sizeof(fileinfo));
						fileinfo->filename=strdup(filename);
						fileinfo->index=0;
						row_num = gtk_clist_append(GTK_CLIST(clist), text);
						gtk_clist_set_row_data(GTK_CLIST(clist), row_num, (gpointer)fileinfo);
					} else {
						if (!scan_filter_library(filename, clist)) {
							fprintf(stderr, "error loading %s !\n", filename); 
						}
					}
				}
			}
			free(filename);
		}
	}
	closedir(dir);
}

void uf_scan_filters(char *path, GtkWidget *clist, int freeze)
{
	char *tok, *p;
	if (freeze) gtk_clist_freeze(GTK_CLIST(clist));
	p = malloc(strlen(path)+1);
	strcpy(p, path);
	for (tok = strtok(p, ":"); tok; tok = strtok(NULL, ":")) {
		scan_filter_dir(tok, clist);
	} 
	free(p);
	if (freeze) gtk_clist_thaw(GTK_CLIST(clist));
}

void cb_update_preview(GtkWidget *widget, gpointer data)
{
	apply_to_preview(preview);
}

void file_selection_load(GtkWidget *widget, gpointer data)
{
	int tmp_preview_enable;
	gtk_widget_set_sensitive (dialog, TRUE);
	tmp_preview_enable = preview_enable; preview_enable = 0;
	strcpy(plug_in_data.last_filename, gtk_file_selection_get_filename (GTK_FILE_SELECTION (data)));
	load_file(plug_in_data.last_filename);
	preview_enable = tmp_preview_enable;
	gtk_widget_destroy(data);
	cb_update_preview(preview, NULL);
}

void file_selection_save(GtkWidget *widget, gpointer data)
{
	gtk_widget_set_sensitive (dialog, TRUE);
	strcpy(plug_in_data.last_filename, gtk_file_selection_get_filename (GTK_FILE_SELECTION (data)));
	save_file(plug_in_data.last_filename);
	gtk_widget_destroy(data);
}

void file_selection_cancel(GtkWidget *widget, gpointer data)
{
	gtk_widget_destroy(data);
	gtk_widget_set_sensitive (dialog, TRUE);
}

void cb_reset(GtkWidget *widget, gpointer data)
{
	int n, tmp_preview_enable;
	tmp_preview_enable = preview_enable;
	preview_enable = 0;
	for (n = 0; n<8; n++) {
		GTK_ADJUSTMENT(adjustment[n])->value = 0;
		gtk_signal_emit_by_name(GTK_OBJECT(adjustment[n]), "value_changed");
	}

	gtk_entry_set_text (GTK_ENTRY(source_text[0]), "r");
	gtk_entry_set_text (GTK_ENTRY(source_text[1]), "g");
	gtk_entry_set_text (GTK_ENTRY(source_text[2]), "b");
	gtk_entry_set_text (GTK_ENTRY(source_text[3]), "a");
                              
	preview_enable = tmp_preview_enable;
	cb_update_preview(preview, NULL);
}

void uf_fileselect_load(GtkWidget *widget, gpointer data)
{
	GtkWidget *file_select;
	file_select = gtk_file_selection_new ("Load filter...");
	gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_select)->ok_button), 
		"clicked", (GtkSignalFunc) file_selection_load, 
		(gpointer)file_select);
	gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_select)->cancel_button), 
		"clicked", (GtkSignalFunc) file_selection_cancel, 
		(gpointer)file_select);
	gtk_file_selection_set_filename (GTK_FILE_SELECTION (file_select), plug_in_data.last_filename);
	gtk_widget_show(file_select);
	gtk_widget_set_sensitive (dialog, FALSE);
}

void uf_clist_load(GtkWidget *widget, GtkWidget *clist)
{
	int tmp_preview_enable;
	FILEINFO *fileinfo;

	if (clist == NULL) {
		return;
	}
	if (GTK_CLIST(clist)->selection == NULL) {
		return;
	}

	fileinfo = (FILEINFO *)gtk_clist_get_row_data(GTK_CLIST(clist), (gint)GTK_CLIST(clist)->selection->data);
	if (fileinfo == NULL) {
		return;
	}
	if (fileinfo->filename == NULL) {
		return;
	}
	if (fileinfo->index == 0) {
		strcpy(plug_in_data.last_filename, fileinfo->filename);

		tmp_preview_enable = preview_enable; 
		preview_enable = 0;
		load_file(plug_in_data.last_filename);
		preview_enable = tmp_preview_enable;
	} else {
		FILE *f;
		int n;
		f=fopen(fileinfo->filename, "rb");
		get_filter_from_library(f, fileinfo->index, &data);
		fclose(f);
		tmp_preview_enable = preview_enable; 
		preview_enable = 0;
		gtk_window_set_title (GTK_WINDOW(dialog), data.title);
		for (n = 0; n<8; n++) {
			GTK_ADJUSTMENT(adjustment[n])->value = data.control_value[n];
			gtk_signal_emit_by_name(GTK_OBJECT(adjustment[n]), "value_changed");
		}
		gui_enable = 0;
		for (n = 0; n<4; n++) {
			gtk_entry_set_text(GTK_ENTRY(source_text[n]), data.source[n]);
		}
		gui_enable = 1;
		for (n = 0; n<8; n++) {
			gtk_entry_set_text(GTK_ENTRY(slider_value[n]), data.control_label[n]);
		}
		preview_enable = tmp_preview_enable;
	}
	cb_update_preview(preview, NULL);
}

void uf_fileselect_save_as(GtkWidget *widget, gpointer data)
{
	GtkWidget *file_select;
	file_select = gtk_file_selection_new ("Save filter...");
	gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_select)->ok_button), 
		"clicked", (GtkSignalFunc) file_selection_save, 
		(gpointer)file_select);
	gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_select)->cancel_button), 
		"clicked", (GtkSignalFunc) file_selection_cancel, 
		(gpointer)file_select);
	gtk_file_selection_set_filename (GTK_FILE_SELECTION (file_select), plug_in_data.last_filename);
	gtk_widget_show(file_select);
	gtk_widget_set_sensitive (dialog, FALSE);
}

void uf_fileselect_save(GtkWidget *widget, gpointer d)
{
	if (strcmp(plug_in_data.last_filename, "") == 0) {
		uf_fileselect_save_as(widget, d);
	} else {
		save_file(plug_in_data.last_filename);
	}
}

void load_file(char *s)
{
	int n;
	load_filter(s, &data);
	gtk_window_set_title (GTK_WINDOW(dialog), data.title);
	for (n = 0; n<8; n++) {
		GTK_ADJUSTMENT(adjustment[n])->value = data.control_value[n];
		gtk_signal_emit_by_name(GTK_OBJECT(adjustment[n]), "value_changed");
	}
	/* read channels */
	for (n = 0; n<4; n++) {
		gtk_entry_set_text(GTK_ENTRY(source_text[n]), data.source[n]);
	}
	for (n = 0; n<8; n++) {
		gtk_entry_set_text(GTK_ENTRY(slider_value[n]), data.control_label[n]);
	}
}

void save_file(char *s)
{
	int n;
	for (n = 0; n<8; n++) {
		data.control_value[n] = GTK_ADJUSTMENT(adjustment[n])->value;
	}
	/* read channels */
	for (n = 0; n<4; n++) {
		strcpy(data.source[n], gtk_entry_get_text(GTK_ENTRY(source_text[n])));
	}
	for (n = 0; n<8; n++) {
		strcpy(data.control_label[n], gtk_entry_get_text(GTK_ENTRY(slider_value[n])));
	}
	save_filter(s, &data);
}

void cb_close(GtkWidget *widget, gpointer data)
{
	gtk_main_quit();
}

void cb_cancel(GtkWidget *widget, gpointer data)
{
	result = FALSE;
	gtk_widget_destroy(GTK_WIDGET(data));
}

void cb_ok(GtkWidget *widget, gpointer data)
{
	result = TRUE;
	gtk_widget_destroy(GTK_WIDGET(data));
}

void cb_button_preview_update (GtkWidget *widget, gpointer data)
{
	preview_enable = GTK_TOGGLE_BUTTON(widget)->active;
}

void cb_preview_slider (GtkWidget *widget, gpointer data)
{
	prev_x1 = GTK_ADJUSTMENT(prev_adj_x)->value;
	prev_y1 = GTK_ADJUSTMENT(prev_adj_y)->value;
	build_preview();
	if (preview_enable) {
		apply_to_preview(preview);
	}
}

void cb_slider_update (GtkWidget *widget, gpointer data)
{
	GtkWidget *entry;
	char buf[256];
	int new_value;

	new_value = GTK_ADJUSTMENT(widget)->value;
	entry = gtk_object_get_user_data(GTK_OBJECT(widget));

	*((int *)data) = new_value;

	sprintf(buf, "%i", new_value);
	gtk_signal_handler_block_by_data(GTK_OBJECT(entry), data);
	gtk_entry_set_text(GTK_ENTRY(entry), buf);
	gtk_signal_handler_unblock_by_data(GTK_OBJECT(entry), data);

	if (preview_enable) { 
		cb_update_preview(preview, NULL);
	}
}

void cb_entry_update (GtkWidget *widget, gpointer data)
{
	if (gui_enable) {
		strcpy(data, gtk_entry_get_text(GTK_ENTRY(widget)));
	}
}

void cb_value_entry_update (GtkWidget *widget, gpointer data)
{
        GtkAdjustment *adjustment;
        int	new_value;

        new_value = atoi(gtk_entry_get_text(GTK_ENTRY(widget)));
	*((int *)data) = new_value;
	adjustment = gtk_object_get_user_data(GTK_OBJECT(widget));

	if (new_value  != adjustment->value) {
		if ((new_value >= adjustment->lower) &&
		    (new_value <= adjustment->upper)) {
			adjustment->value = new_value;
			gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
		}
	}
}

void manager_rescan_button (GtkWidget *widget, gpointer data)
{
	clear_filter_dir(GTK_WIDGET(data));
	uf_scan_filters(scan_path, GTK_WIDGET(data), 1);
}

void uf_build_preview(GtkWidget *box)
{
	GtkWidget *frame, *vbox, *button, *table, *scrollbar;
	frame = gtk_frame_new("Preview");
	gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 0);
	gtk_widget_show(frame);

	vbox = gtk_vbox_new(FALSE, 5);
	gtk_container_border_width (GTK_CONTAINER (vbox), 5);
	gtk_container_add(GTK_CONTAINER(frame), vbox);
	gtk_widget_show(vbox);

	/* preview-button and sliders */
        table = gtk_table_new (2, 2, FALSE);
        gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
	gtk_widget_show(table);

	button = gtk_button_new();
	gtk_signal_connect (GTK_OBJECT (button), "clicked", 
		(GtkSignalFunc) cb_update_preview, NULL);
	gtk_table_attach(GTK_TABLE(table), button, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
	gtk_widget_show(button);	

	preview = gtk_preview_new(GTK_PREVIEW_COLOR);
	gtk_preview_size(GTK_PREVIEW(preview), prev_size, prev_size);
	gtk_container_add(GTK_CONTAINER(button), preview);
	gtk_widget_show (preview);

	prev_adj_x = gtk_adjustment_new (prev_x1, 0.0, img_width, 1.0, prev_size*prev_scale, prev_size*prev_scale);
	gtk_signal_connect(GTK_OBJECT(prev_adj_x), 
		"value_changed", 
		(GtkSignalFunc) cb_preview_slider, 
		NULL);

	scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (prev_adj_x));
	gtk_range_set_update_policy (GTK_RANGE (scrollbar), GTK_UPDATE_DELAYED);
	gtk_table_attach(GTK_TABLE(table), scrollbar, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);    
	gtk_widget_show(scrollbar);

	prev_adj_y = gtk_adjustment_new (prev_y1, 0.0, img_height, 1.0, prev_size*prev_scale, prev_size*prev_scale);
	gtk_signal_connect(GTK_OBJECT(prev_adj_y), 
		"value_changed", 
		(GtkSignalFunc) cb_preview_slider, 
		NULL);

	scrollbar = gtk_vscrollbar_new (GTK_ADJUSTMENT (prev_adj_y));
	gtk_range_set_update_policy (GTK_RANGE (scrollbar), GTK_UPDATE_DELAYED);
	gtk_table_attach(GTK_TABLE(table), scrollbar, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);    
	gtk_widget_show(scrollbar);

	button = gtk_check_button_new_with_label("enable update");
	gtk_signal_connect (GTK_OBJECT (button), 
		"toggled", 
		(GtkSignalFunc) cb_button_preview_update, 
		0);
	gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
	gtk_widget_show (button);
	preview_enable = 1;
	gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), preview_enable);
}

void uf_build_page_sliders(GtkWidget *notebook)
{
	GtkWidget *table, *label, *scale;
	int i;

        table = gtk_table_new (8, 3, FALSE);
	label = gtk_label_new ("Values");
	gtk_notebook_append_page (GTK_NOTEBOOK (notebook), table, label);
	gtk_widget_show(table);

	for (i = 0; i<8; i++) {
		GtkWidget *v_entry;
		char buf[256];
		slider_value[i] = gtk_entry_new();
		gtk_entry_set_text(GTK_ENTRY(slider_value[i]), data.control_label[i]);
		gtk_widget_set_usize(slider_value[i], 100, 0);
                gtk_table_attach(GTK_TABLE(table), slider_value[i], 0, 1, i, i+1, GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
		gtk_widget_show(slider_value[i]);
		
		adjustment[i] = gtk_adjustment_new (data.control_value[i], 0.0, 255.0, 1.0, 1.0, 0.0);
		gtk_signal_connect(GTK_OBJECT(adjustment[i]), 
			"value_changed", 
			(GtkSignalFunc) cb_slider_update , 
			(gpointer)&(data.control_value[i]));
 		        
		scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment[i]));
		gtk_widget_set_usize(scale, 300, 0);
		gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
		gtk_scale_set_draw_value(GTK_SCALE(scale), FALSE);
                gtk_table_attach(GTK_TABLE(table), scale, 1, 2, i, i+1, GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);    
		gtk_widget_show(scale);
		
		v_entry = gtk_entry_new();
		sprintf(buf, "%i", (int)GTK_ADJUSTMENT(adjustment[i])->value);
		gtk_entry_set_text(GTK_ENTRY(v_entry), buf);
		gtk_widget_set_usize(v_entry, 60, 0);
                gtk_table_attach(GTK_TABLE(table), v_entry, 2, 3, i, i+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
		gtk_signal_connect(GTK_OBJECT(v_entry), "changed", 
			(GtkSignalFunc) cb_value_entry_update, 
			(gpointer)&(data.control_value[i]));
		gtk_widget_show(v_entry);
		
		/* connect entry and adjustment */
		gtk_object_set_user_data(GTK_OBJECT(v_entry), adjustment[i]);
		gtk_object_set_user_data(GTK_OBJECT(adjustment[i]), v_entry);
	}
	
}

void uf_build_page_edit(GtkWidget *notebook)
{
	static char *ch_name[4] = {"Red:", "Green:", "Blue:", "Alpha:"};
	GtkWidget *table, *label, *button;
	int i;

        table = gtk_table_new (4, 3, FALSE);
	label = gtk_label_new ("Edit");
	gtk_notebook_append_page (GTK_NOTEBOOK(notebook), table, label);
	gtk_widget_show(table);

	for (i = 0; i<4; i++) {
		label = gtk_label_new(ch_name[i]);
                gtk_table_attach(GTK_TABLE(table), label, 0, 1, i, i+1, GTK_SHRINK, GTK_SHRINK, 0, 0);    
		gtk_widget_show(label);
		
		source_text[i] = gtk_entry_new();
		gtk_signal_connect(GTK_OBJECT(source_text[i]), 
			"changed", 
			(GtkSignalFunc)cb_entry_update , 
			(gpointer)(data.source[i]));
                gtk_table_attach(GTK_TABLE(table), source_text[i], 1, 2, i, i+1, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);    
   		gtk_widget_show(source_text[i]);
		gtk_entry_set_text(GTK_ENTRY(source_text[i]), data.source[i]);

		button = gtk_button_new_with_label ("!");
                gtk_table_attach(GTK_TABLE(table), button, 2, 3, i, i+1, GTK_SHRINK, GTK_SHRINK, 0, 0);
		gtk_widget_show (button);
	}
}

void uf_build_page_about(GtkWidget *notebook)
{
	/* as soon as I add imlib support */
}

static void uf_clist_click_column (GtkCList *clist, gint column, gpointer data)
{
  if (column == clist->sort_column) {
	  clist->sort_type = (clist->sort_type == GTK_SORT_ASCENDING) ? GTK_SORT_DESCENDING : GTK_SORT_ASCENDING;
  }  else {
    	gtk_clist_set_sort_column (clist, column);
 }
 gtk_clist_sort (clist);
}

void uf_build_page_manager(GtkWidget *notebook)
{
	GtkWidget *vbox, *box, *label, *button, *scrolled_win;
	static char *titles[] = {"Category", "Title", "Author", "Copyright"};
	
        vbox = gtk_vbox_new (FALSE, 5);
	label = gtk_label_new ("Filter Manager");
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
	gtk_widget_show(vbox);
	box = gtk_vbox_new(FALSE, 5);
	gtk_container_border_width (GTK_CONTAINER (box), 0);
	gtk_box_pack_start(GTK_BOX(vbox), box, TRUE, TRUE, 0);
	gtk_widget_show(box);

/*Angepasst an gtk-1.2 am 24.3.99 */

/* Sorry, I don't have the time to upgrade the clist into a GtkTreeView -- JCR */
	scrolled_win = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_container_add(GTK_CONTAINER (box),scrolled_win);
	gtk_widget_show(scrolled_win);
	
	clist = gtk_clist_new_with_titles(4, titles);
	gtk_clist_set_row_height (GTK_CLIST (clist), 40);
	gtk_clist_set_column_width (GTK_CLIST (clist), 0, 100);
	gtk_clist_set_column_justification (GTK_CLIST (clist), 0, GTK_JUSTIFY_LEFT);
	gtk_clist_set_column_width (GTK_CLIST (clist), 1, 100);
	gtk_clist_set_column_justification (GTK_CLIST (clist), 1, GTK_JUSTIFY_LEFT);
	gtk_clist_set_column_width (GTK_CLIST (clist), 2, 100);
	gtk_clist_set_column_justification (GTK_CLIST (clist), 2, GTK_JUSTIFY_LEFT);
	gtk_clist_set_column_width (GTK_CLIST (clist), 3, 100);
	gtk_clist_set_column_justification (GTK_CLIST (clist), 3, GTK_JUSTIFY_LEFT);

	gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_BROWSE);
       gtk_signal_connect (GTK_OBJECT (clist), "click_column",
                            (GtkSignalFunc) uf_clist_click_column, NULL);

/* 	gtk_clist_set_policy (GTK_CLIST (clist), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); */

	gtk_container_border_width (GTK_CONTAINER (clist), 5);
	gtk_container_add (GTK_CONTAINER (scrolled_win), clist);
	gtk_widget_show (clist);

	box = gtk_hbox_new(FALSE, 5);
	gtk_container_border_width (GTK_CONTAINER (box), 5);
	gtk_box_pack_start(GTK_BOX (vbox), box, FALSE, FALSE, 0);
	gtk_widget_show(box);

	button = gtk_button_new_with_label ("Rescan");
	gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
	gtk_signal_connect (GTK_OBJECT (button), "clicked", 
		(GtkSignalFunc) manager_rescan_button, (gpointer)clist);
	gtk_widget_show (button);
#if 0
	button = gtk_button_new_with_label ("Rebuild previews");
	gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
	gtk_widget_show (button);
#endif
	button = gtk_button_new_with_label ("Load");
	gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
	gtk_signal_connect (GTK_OBJECT (button), "clicked", 
		(GtkSignalFunc) uf_clist_load, (gpointer)clist);
	gtk_widget_show (button);

	button = gtk_button_new_with_label ("Save");
	gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
	gtk_widget_set_sensitive (button, FALSE);
	gtk_widget_show (button);

	button = gtk_button_new_with_label ("Delete");
	gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
	gtk_widget_set_sensitive (button, FALSE);
	gtk_widget_show (button);
	
#if 1
	uf_scan_filters(scan_path, clist, 0);
#endif
}

void uf_build_notebook(GtkWidget *box)
{
	GtkWidget *notebook;
	notebook = gtk_notebook_new ();
	gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
	gtk_box_pack_start (GTK_BOX(box), notebook, TRUE, TRUE, 0);

	uf_build_page_sliders(notebook);
	uf_build_page_edit(notebook);
	uf_build_page_manager(notebook);
	uf_build_page_about(notebook);
	gtk_widget_show (notebook);
}

void uf_build_menubar(GtkWidget *box)
{
	GtkWidget *menubar;
	GtkWidget *menu;
	GtkWidget *menuitem, *submenuitem;

	menubar = gtk_menu_bar_new();
	gtk_box_pack_start(GTK_BOX(box), menubar, FALSE, TRUE, 0);
	gtk_widget_show(menubar);

	menuitem = gtk_menu_item_new_with_label("File");

		menu = gtk_menu_new();

		submenuitem = gtk_menu_item_new_with_label("Load");
		gtk_menu_append(GTK_MENU(menu), submenuitem);
		gtk_signal_connect (GTK_OBJECT (submenuitem), "activate", 
			(GtkSignalFunc) uf_fileselect_load, (gpointer)dialog);
		gtk_widget_show(submenuitem);

		submenuitem = gtk_menu_item_new_with_label("Save");
		gtk_menu_append(GTK_MENU(menu), submenuitem);
		gtk_signal_connect (GTK_OBJECT (submenuitem), "activate", 
			(GtkSignalFunc) uf_fileselect_save, (gpointer)dialog);
		gtk_widget_show(submenuitem);

		submenuitem = gtk_menu_item_new_with_label("Save as...");
		gtk_menu_append(GTK_MENU(menu), submenuitem);
		gtk_signal_connect (GTK_OBJECT (submenuitem), "activate", 
			(GtkSignalFunc) uf_fileselect_save_as, (gpointer)dialog);
		gtk_widget_show(submenuitem);

		submenuitem = gtk_menu_item_new_with_label("Quit");
		gtk_menu_append(GTK_MENU(menu), submenuitem);
		gtk_signal_connect(GTK_OBJECT(submenuitem), "activate",
			(GtkSignalFunc) cb_cancel, 
			(gpointer)dialog);
		gtk_widget_show(submenuitem);

		gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);

	gtk_menu_bar_append(GTK_MENU_BAR(menubar), menuitem);
	gtk_widget_show(menuitem);

	menuitem = gtk_menu_item_new_with_label("Edit");

		menu = gtk_menu_new();
		submenuitem = gtk_menu_item_new_with_label("Options...");
		gtk_menu_append(GTK_MENU(menu), submenuitem);
		gtk_widget_show(submenuitem);
	
		gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);

	gtk_menu_bar_append(GTK_MENU_BAR(menubar), menuitem);
	gtk_widget_show(menuitem);

	menuitem = gtk_menu_item_new_with_label("Help");

		menu = gtk_menu_new();
		submenuitem = gtk_menu_item_new_with_label("About User Filter...");
		gtk_menu_append(GTK_MENU(menu), submenuitem);
		gtk_widget_show(submenuitem);
	
		gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);

	gtk_menu_bar_append(GTK_MENU_BAR(menubar), menuitem);
	gtk_widget_show(menuitem);

}

void uf_build_dialog()
{
	GtkWidget *hbox, *button;

	/*
	 * Open dialog window 
	 */
	dialog = gtk_dialog_new ();
	gtk_window_set_title (GTK_WINDOW(dialog), data.title);
	gtk_signal_connect (GTK_OBJECT (dialog), "destroy", 
		(GtkSignalFunc) cb_close, 
		NULL);

	uf_build_menubar(GTK_DIALOG(dialog)->vbox);
	
	hbox = gtk_hbox_new(FALSE, 5);
	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0);
	gtk_widget_show(hbox);

	uf_build_preview(hbox);
	uf_build_notebook(hbox);

	/*
	 * Add OK and Cancel buttons for the dialog
	 */
	button = gtk_button_new_with_label ("OK");
	gtk_signal_connect (GTK_OBJECT (button), "clicked", 
		(GtkSignalFunc) cb_ok, (gpointer) dialog);
	GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
	gtk_box_pack_start(GTK_BOX (GTK_DIALOG(dialog)->action_area), button, TRUE, TRUE, 0);
	gtk_widget_grab_default (button);
	gtk_widget_show (button);

	button = gtk_button_new_with_label ("Cancel");
	gtk_signal_connect (GTK_OBJECT (button), "clicked", 
		(GtkSignalFunc) cb_cancel, (gpointer) dialog);
	gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->action_area), button, TRUE, TRUE, 0);
	GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
	gtk_widget_show (button);

	button = gtk_button_new_with_label ("Help");
	gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->action_area), button, TRUE, TRUE, 0);
	GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
	gtk_widget_show (button);

	gtk_widget_show(dialog);

	cb_update_preview(preview, NULL);
}

int uf_gui()
{
	srandom(time(NULL));

	gimp_ui_init ("user_filter", TRUE);

	/*
	 * Get scan_path
	 */
#ifdef GIMP_VERSION
	scan_path = gimp_gimprc_query("userfilter-path");
#else
  {	gint nreturn_vals;
     GParam *return_vals;
	return_vals = gimp_run_procedure ("gimp_gimprc_query",
				    &nreturn_vals,
				    PARAM_STRING, "userfilter-path",
				    PARAM_END);
	if (return_vals[0].data.d_status == STATUS_SUCCESS)
	{	scan_path = return_vals[1].data.d_string;
	}
   }
#endif
	if (scan_path == NULL) {
		/* set default scan path */
		gimp_gimprc_set("userfilter-path", "${gimp_dir}/userfilter:${gimp_data_dir}/userfilter");

#ifdef GIMP_VERSION
	scan_path = gimp_gimprc_query("userfilter-path");
#else
  {	gint nreturn_vals;
     GParam *return_vals;
	return_vals = gimp_run_procedure ("gimp_gimprc_query",
				    &nreturn_vals,
				    PARAM_STRING, "userfilter-path",
				    PARAM_END);
	if (return_vals[0].data.d_status == STATUS_SUCCESS)
	{	scan_path = return_vals[1].data.d_string;
	}
   }
#endif

	}
#if 0
	/* Why does this crash ? */
	gimp_destroy_params(return_vals, nreturn_vals);
#endif

	gui_enable = 1;
	uf_build_dialog();	

	result = 0;
	gtk_main();
	gdk_flush();
	free(scan_path);

	return result;
}
