/* 
 * pview - Simple GIMP palette (.gpl) viewer
 *
 * Compile with gcc: `pkg-config gtk+-2.0 --cflags --libs` pview.c -o pview
 *
 * This program is free software. It comes without any warranty, to
 * the extent permitted by applicable law. You can redistribute it
 * and/or modify it under the terms of the Do What The Fuck You Want
 * To Public License, Version 2, as published by Sam Hocevar. See
 * http://sam.zoy.org/wtfpl/COPYING for more details.
 */
#include <gtk/gtk.h>

static void selection_changed(GtkIconView *view, gpointer user_data)
{
	GtkTreeModel *m = gtk_icon_view_get_model(view);
	GList *s = gtk_icon_view_get_selected_items(view);
	GtkTreeIter iter;
	GtkClipboard *cb;
	gchar *color;

	(void)user_data;

	if (!s) return;

	gtk_tree_model_get_iter(m, &iter, s->data);
	gtk_tree_model_get(m, &iter, 2, &color, -1);

	cb = gtk_widget_get_clipboard(GTK_WIDGET(view), GDK_SELECTION_CLIPBOARD);
	gtk_clipboard_set_text(cb, color, -1);

	g_free(color);
	g_list_foreach(s, (GFunc)gtk_tree_path_free, NULL);
	g_list_free(s);
}

static void append_color(GtkListStore *store,
			 guint32 color, const gchar *name)
{
	gchar *code = g_strdup_printf("#%06X", color & 0xffffff);
	GtkTreeIter iter;
	GdkPixbuf *buf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
			     32, 32);
	gdk_pixbuf_fill(buf, (color << 8) | 0xff);

	gtk_list_store_append(store, &iter);
	gtk_list_store_set(store, &iter,
			   0, name,
			   1, buf,
			   2, code,
			   -1);

	g_object_unref(buf);
	g_free(code);
}

int main(int argc, char **argv)
{
	GtkWidget *window;
	GtkWidget *view;
	GtkListStore *store;
	FILE *f;
	gchar *pname = NULL;
	guint32 r, g, b, c = 0;

	gtk_init(&argc, &argv);

	if (argc < 2) {
		fprintf(stderr, "Usage: %s <palette file>\n", argv[0]);
		return 0;
	}

	store = gtk_list_store_new(3,
				   G_TYPE_STRING,
				   GDK_TYPE_PIXBUF,
				   G_TYPE_STRING);

	view = gtk_icon_view_new_with_model(GTK_TREE_MODEL(store));
	gtk_icon_view_set_text_column(GTK_ICON_VIEW(view), -1);
	gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(view), 1);

	f = fopen(argv[1], "r");
	while (!feof(f)) {
		static char buffer[1024];
		static char cname[1024];
		if (!fgets(buffer, 1024, f)) break;
		if (*buffer == '#') continue;
		if (sscanf(buffer, "Columns: %u", &c));
		else if (g_str_has_prefix(buffer, "Name: ")) {
			if (pname) g_free(pname);
			pname = g_strdup(buffer + 6);
		}
		else if (sscanf(buffer, "%u %u %u %s", &r, &g, &b, cname) > 2)
		{
			append_color(store, (r << 16) | (g << 8) | b, cname);
		}
	}
	fclose(f);

	if (c > 0)
		gtk_icon_view_set_columns(GTK_ICON_VIEW(view), c);

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

	if (pname) {
		gtk_window_set_title(GTK_WINDOW(window), pname);
	} else {
		gtk_window_set_title(GTK_WINDOW(window), "Palette viewer");
	}

	gtk_container_add(GTK_CONTAINER(window), view);

	g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
	g_signal_connect(view, "selection-changed", G_CALLBACK(selection_changed), NULL);

	gtk_widget_show_all(window);

	gtk_main();

	return 0;
}
