/* logjam - a GTK client for LiveJournal.
 * Copyright (C) 2000-2003 Evan Martin <evan@livejournal.com>
 *
 * vim: tabstop=4 shiftwidth=4 noexpandtab :
 */

#include "config.h"
#include "gtk-all.h"


#ifdef HAVE_LIBRSVG
  #include <librsvg/rsvg.h>
  #include "logo-svg.h"
#else
  #include "icons.h"
#endif

#include "network-throbber.h"
#include "util.h"

struct _NetThrobber {
	GtkImage   parent;
	guint      tag;

#ifdef HAVE_LIBRSVG
	int        angle;
#else
	int        state;
	GdkPixbuf *pb[THROBBER_COUNT];
#endif
};


#ifdef HAVE_LIBRSVG
/* delay in ms between frames of the throbber */
#define THROBBER_FRAME_DELAY 20
static void update_svg(NetThrobber *t);

void
net_throbber_reset(NetThrobber *t) {
	t->angle = 0;
	update_svg(t);
}

static void
net_throbber_finalize(GObject *object) {
	GObjectClass *parent_class;

	net_throbber_stop(NET_THROBBER(object));

	parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
	parent_class->finalize(object);
}

static void
size_cb(gint *width, gint *height, gpointer data) {
	*width = *height = 48;
}

static void
update_svg(NetThrobber *t) {
	RsvgHandle *handle;
	GdkPixbuf *pb;
	char *transform;
	GError *err = NULL;

	handle = rsvg_handle_new();
	rsvg_handle_set_size_callback(handle, size_cb, NULL, NULL);
	
	if (!rsvg_handle_write(handle,
				logo_svg_data_1, sizeof(logo_svg_data_1)-1,
				&err)) {
		g_print("error: %s\n", err->message);
		g_error_free(err);
		return;
	}

	transform = g_strdup_printf(
			"transform=\"translate(%d, %d) rotate(%d) translate(%d, %d)\"\n",
			logo_svg_translate2_x, logo_svg_translate2_y,
			t->angle,
			logo_svg_translate1_x, logo_svg_translate1_y);
	rsvg_handle_write(handle, transform, strlen(transform), NULL);
	g_free(transform);

	if (!rsvg_handle_write(handle,
				logo_svg_data_2, sizeof(logo_svg_data_2)-1,
				&err)) {
		g_print("error: %s\n", err->message);
		g_error_free(err);
		return;
	}
	if (!rsvg_handle_close(handle, &err)) {
		g_print("error: %s\n", err->message);
		g_error_free(err);
		return;
	}

	pb = rsvg_handle_get_pixbuf(handle);

	gtk_image_set_from_pixbuf(GTK_IMAGE(t), pb);
	g_object_unref(G_OBJECT(pb));
	rsvg_handle_free(handle);
}

static gboolean
throbber_cb(NetThrobber *t) {
	t->angle += 3;
	update_svg(t);
	return TRUE;
}

#else
/* we're doing the image-based throbber. */

/* delay in ms between frames of the throbber */
#define THROBBER_FRAME_DELAY 400

void
net_throbber_reset(NetThrobber *t) {
	icons_load_throbber(t->pb);
	gtk_image_set_from_pixbuf(GTK_IMAGE(t), t->pb[0]);
}

static gboolean
throbber_cb(NetThrobber *t) {
	t->state = (t->state + 1) % THROBBER_COUNT;
	gtk_image_set_from_pixbuf(GTK_IMAGE(t), t->pb[t->state]);
	return TRUE;
}

static void
net_throbber_finalize(GObject *object) {
	GObjectClass *parent_class;
	int i;

	net_throbber_stop(NET_THROBBER(object));
	for (i = 0; i < THROBBER_COUNT; i++)
		g_object_unref(G_OBJECT(NET_THROBBER(object)->pb[i]));

	parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
	parent_class->finalize(object);
}


#endif

static void
throbber_init(NetThrobber *t) {
	net_throbber_reset(t);
}

void
net_throbber_start(NetThrobber *t) {
	if (t->tag)
		return;
	t->tag = gtk_timeout_add(THROBBER_FRAME_DELAY,
			(GSourceFunc)throbber_cb, t);
}
void
net_throbber_stop(NetThrobber *t) {
	if (!t->tag)
		return;
	gtk_timeout_remove(t->tag);
	t->tag = 0;
}

static void
throbber_class_init(gpointer klass, gpointer class_data) {
	GObjectClass *gclass = G_OBJECT_CLASS(klass);

	gclass->finalize = net_throbber_finalize;
}

GType
net_throbber_get_type(void) {
	static GType throbber_type = 0;
	if (!throbber_type) {
		static const GTypeInfo throbber_info = {
			sizeof (GtkImageClass),
			NULL,
			NULL,
			(GClassInitFunc) throbber_class_init,
			NULL,
			NULL,
			sizeof (NetThrobber),
			0,
			(GInstanceInitFunc) throbber_init,
		};
		throbber_type = g_type_register_static(GTK_TYPE_IMAGE, "Throbber",
				&throbber_info, 0);
	}
	return throbber_type;
}

GtkWidget*
net_throbber_new(void) {
	NetThrobber *throbber =
		NET_THROBBER(g_object_new(net_throbber_get_type(), NULL));
	return GTK_WIDGET(throbber);
}


