#include <gtk/gtk.h>

typedef struct
{
    GtkWidget *image;
    GdkPixbufAnimationIter *iter;
} ImageData;

gboolean advance_frame(gpointer ptr)
{
    // Get our data back
    ImageData* data = static_cast<ImageData*>(ptr);

    // Advance and display if necessary
    if(gdk_pixbuf_animation_iter_advance(data->iter, NULL))
    {
        gtk_image_set_from_pixbuf(GTK_IMAGE(data->image),
                                  gdk_pixbuf_animation_iter_get_pixbuf(data->iter));
    }

    // Setup next delay
    int delay = gdk_pixbuf_animation_iter_get_delay_time(data->iter);
    g_print("Delay: %d\n", delay);
    g_timeout_add(delay, (GSourceFunc)advance_frame, ptr);

    // Remove old delay/callback
    return FALSE;
}

int main(int argc, char **argv)
{
    // Initialize options
    gtk_init(&argc, &argv);

    // Get initial image
    GdkPixbufAnimation* anim = gdk_pixbuf_animation_new_from_file("test.gif", NULL);
    GdkPixbufAnimationIter* iter = gdk_pixbuf_animation_get_iter(anim, NULL);
    GtkWidget* image = gtk_image_new_from_pixbuf(gdk_pixbuf_animation_iter_get_pixbuf(iter));

    // Add to window and make visible
    GtkWidget* win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_container_add(GTK_CONTAINER(win), image);
    gtk_widget_show(image);

    // Setup data we'll need in the callback
    ImageData data;
    data.image = image;
    data.iter = iter;

    // Setup initial delay
    int delay = gdk_pixbuf_animation_iter_get_delay_time(iter);
    g_print("Delay: %d\n", delay);
    g_timeout_add(delay, (GSourceFunc)advance_frame, (gpointer)&data);

    // Show the window
    g_signal_connect(G_OBJECT(win), "delete-event", G_CALLBACK(gtk_main_quit), NULL);
    gtk_widget_show(win);

    // Main loop
    gtk_main();

    return 0;
}
