#include <stdlib.h>
#include <glib.h>
#include <gtk/gtk.h>

static GtkWidget *
get_test_page (const gchar *text)
{
  return gtk_label_new (text);
}


static void
cancel_callback (GtkAssistant *assistant, GtkWidget *page, GtkWidget *window)
{
  if (GTK_IS_LABEL (page))
    g_print ("prepare %s\n", gtk_label_get_text (GTK_LABEL (page)));
  else 
    g_print ("prepare page %d\n", gtk_assistant_get_current_page_num (assistant));
  gtk_widget_hide (window);
}

static gboolean
finish_callback (GtkAssistant *assistant, GtkWidget *page, GtkWidget *window)
{
  if (GTK_IS_LABEL (page))
    g_print ("finish %s\n", gtk_label_get_text (GTK_LABEL (page)));
  else 
    g_print ("finish page %d\n", gtk_assistant_get_current_page_num (assistant));
  gtk_widget_hide (window);

  return FALSE;
}

static gboolean
confirm_callback (GtkAssistant *assistant, GtkWidget *page, GtkWidget *window)
{
  g_print ("confirm %s\n", gtk_label_get_text (GTK_LABEL (page)));

  return FALSE;
}


static void
prepare_callback (GtkAssistant *assistant, GtkWidget *page)
{
  if (GTK_IS_LABEL (page))
    g_print ("prepare %s\n", gtk_label_get_text (GTK_LABEL (page)));
  else 
    g_print ("prepare page %d\n", gtk_assistant_get_current_page_num (assistant));
}

static gboolean
back_callback (GtkAssistant *assistant, GtkWidget *page)
{
  g_print ("back %s\n", gtk_label_get_text (GTK_LABEL (page)));

  return FALSE;
}

static gboolean
next_callback (GtkAssistant *assistant, GtkWidget *page)
{
  g_print ("next %s\n", gtk_label_get_text (GTK_LABEL (page)));

  return FALSE;
}

static gboolean
close_callback (GtkAssistant *assistant, GtkWidget *page, GtkWidget *window)
{
  g_print ("close %s\n", gtk_label_get_text (GTK_LABEL (page)));
  gtk_widget_hide (window);

  return FALSE;
}

static void
create_simple_assistant (GtkWidget *widget)
{
  static GtkWidget *window = NULL;
  GtkWidget *assistant, *page;
  GdkColor color;

  if (!window)
    {
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);

      g_signal_connect (window, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
      
      assistant = gtk_assistant_new ();
      
      gdk_color_parse ("#ce0000", &color);
      gtk_assistant_set_sidebar_color (GTK_ASSISTANT (assistant), &color);
      gtk_assistant_set_header_color (GTK_ASSISTANT (assistant), &color);
      
      gdk_color_parse ("white", &color);
      gtk_assistant_set_header_text_color (GTK_ASSISTANT (assistant), &color);
      
      gtk_container_add (GTK_CONTAINER (window), assistant);
  
      page = get_test_page ("Page 1");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 1");
      
      page = get_test_page ("Page 2");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 2");
      
      g_signal_connect (assistant, "cancel", G_CALLBACK (cancel_callback), window);
      g_signal_connect (assistant, "finish", G_CALLBACK (finish_callback), window);
      g_signal_connect (assistant, "back", G_CALLBACK (back_callback), NULL);
      g_signal_connect (assistant, "next", G_CALLBACK (next_callback), NULL);
      g_signal_connect (assistant, "prepare", G_CALLBACK (prepare_callback), NULL);
    }
  if (!GTK_WIDGET_VISIBLE (window))
    {
      assistant = gtk_bin_get_child (GTK_BIN (window));
      gtk_assistant_set_current_page (GTK_ASSISTANT (assistant), NULL);
      gtk_widget_show_all (window);
    }
  else
    {
      gtk_widget_destroy (window);
      window = NULL;
    }
}

static void
generous_prepare_callback (GtkAssistant *assistant, GtkWidget *page)
{
  gint idx = gtk_assistant_get_current_page_num (assistant);
  g_print ("prepare page %d\n", idx);

  if (idx == 2) 
    gtk_assistant_set_buttons_sensitive (assistant, TRUE, FALSE, TRUE);
}

static void 
generous_complete (GtkWidget *button, GtkAssistant *assistant)
{
  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
    gtk_assistant_set_buttons_sensitive (assistant, TRUE, TRUE, TRUE);
  else
    gtk_assistant_set_buttons_sensitive (assistant, TRUE, FALSE, TRUE);
}

static void
create_generous_assistant (GtkWidget *widget)
{
  static GtkWidget *window = NULL;
  GtkWidget *assistant, *page;
  GtkWidget *button;
  GdkPixbuf *sidebar_pixbuf, *header_pixbuf;
  GdkColor color;

  if (!window)
    {
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);

      g_signal_connect (window, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
      
      assistant = gtk_assistant_new ();
      
      sidebar_pixbuf = gdk_pixbuf_new_from_file ("circles.xbm", NULL);
      gtk_assistant_set_sidebar_image (GTK_ASSISTANT (assistant), sidebar_pixbuf);
      
      gtk_assistant_set_sidebar_image_alignment (GTK_ASSISTANT (assistant), 0.5);
      gdk_color_parse ("#ce0000", &color);
      gtk_assistant_set_sidebar_color (GTK_ASSISTANT (assistant), &color);
      
      header_pixbuf = gdk_pixbuf_new_from_file ("3DRings.xpm", NULL);
      gtk_assistant_set_header_image (GTK_ASSISTANT (assistant), header_pixbuf);
      
      gdk_color_parse ("#ce0000", &color);
      gtk_assistant_set_header_color (GTK_ASSISTANT (assistant), &color);
      
      gdk_color_parse ("white", &color);
      gtk_assistant_set_header_text_color (GTK_ASSISTANT (assistant), &color);
      
      gtk_container_add (GTK_CONTAINER (window), assistant);
  
      page = get_test_page ("Introduction");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Introduction");
      
      page = get_test_page ("Content");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Content");
      
      page = gtk_vbox_new (FALSE, 5);
      gtk_box_pack_start (GTK_BOX (page), gtk_label_new ("More Content"), TRUE, TRUE, 0);
      button = gtk_check_button_new_with_label ("Complete");
      gtk_box_pack_start (GTK_BOX (page), button, TRUE, TRUE, 0);
      g_signal_connect (button, "clicked", G_CALLBACK (generous_complete), assistant);
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "More Content");

      page = get_test_page ("Confirmation");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Confirmation");
      gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_CONFIRM);

      page = get_test_page ("Progress");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Progress");

      page = get_test_page ("Summary");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Summary");
      gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_SUMMARY);
      
      g_signal_connect (assistant, "cancel", G_CALLBACK (cancel_callback), window);
      g_signal_connect (assistant, "finish", G_CALLBACK (confirm_callback), window);
      g_signal_connect (assistant, "close", G_CALLBACK (close_callback), window);
      g_signal_connect (assistant, "back", G_CALLBACK (back_callback), NULL);
      g_signal_connect (assistant, "next", G_CALLBACK (next_callback), NULL);
      g_signal_connect (assistant, "prepare", G_CALLBACK (generous_prepare_callback), NULL);
    }
  if (!GTK_WIDGET_VISIBLE (window))
    {
      assistant = gtk_bin_get_child (GTK_BIN (window));
      gtk_assistant_set_current_page (GTK_ASSISTANT (assistant), NULL);
      gtk_widget_show_all (window);
    }
  else
    {
      gtk_widget_destroy (window);
      window = NULL;
    }
}

static gchar selected_branch = 'B';

static void 
select_branch (GtkWidget *button, gchar *branch)
{
  selected_branch = branch[0];
}

static gboolean
nonlinear_next_callback (GtkAssistant *assistant, GtkWidget *page)
{
  gint idx = gtk_assistant_get_current_page_num (assistant);

  if (GTK_IS_LABEL (page))
    g_print ("next %s\n", gtk_label_get_text (GTK_LABEL (page)));
  else 
    g_print ("next page %d\n", idx);
  
  switch (idx)
    {
    case 0:
      if (selected_branch == 'A')
	gtk_assistant_set_current_page_num (assistant, 1);
      else
	gtk_assistant_set_current_page_num (assistant, 2);
      break;
    case 1:
    case 2:
      gtk_assistant_set_current_page_num (assistant, 3);
      break;
    case 3:
      if (selected_branch == 'A')
	gtk_assistant_set_current_page_num (assistant, 4);
      else
	gtk_assistant_set_current_page_num (assistant, 5);
      break;
    }

  return TRUE;
}

static gboolean
nonlinear_back_callback (GtkAssistant *assistant, GtkWidget *page)
{
  gint idx = gtk_assistant_get_current_page_num (assistant);
  
  if (GTK_IS_LABEL (page))
    g_print ("back %s\n", gtk_label_get_text (GTK_LABEL (page)));
  else 
    g_print ("back page %d\n", idx);

  switch (idx)
    {
    case 1:
    case 2:
      gtk_assistant_set_current_page_num (assistant, 0);
      break;
    case 3:
      if (selected_branch == 'A')
	gtk_assistant_set_current_page_num (assistant, 1);
      else
	gtk_assistant_set_current_page_num (assistant, 2);
      break;
    case 4:
    case 5:
      gtk_assistant_set_current_page_num (assistant, 3);
      break;
    }

  return TRUE;
}

static gboolean
nonlinear_finish_callback (GtkAssistant *assistant, GtkWidget *page, GtkWidget *window)
{
  if (GTK_IS_LABEL (page))
    g_print ("finish %s\n", gtk_label_get_text (GTK_LABEL (page)));
  else 
    g_print ("finish page %d\n", gtk_assistant_get_current_page_num (assistant));
  gtk_widget_hide (window);

  return TRUE;
}

static void
create_nonlinear_assistant (GtkWidget *widget)
{
  static GtkWidget *window = NULL;
  GtkWidget *assistant, *page, *button;
  GdkPixbuf *sidebar_pixbuf, *header_pixbuf;
  GdkColor color;

  if (!window)
    {
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);

      g_signal_connect (window, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
      
      assistant = gtk_assistant_new ();
      
      sidebar_pixbuf = gdk_pixbuf_new_from_file ("circles.xbm", NULL);
      gtk_assistant_set_sidebar_image (GTK_ASSISTANT (assistant), sidebar_pixbuf);
      
      gtk_assistant_set_sidebar_image_alignment (GTK_ASSISTANT (assistant), 0.5);
      gdk_color_parse ("#ce0000", &color);
      gtk_assistant_set_sidebar_color (GTK_ASSISTANT (assistant), &color);
      
      header_pixbuf = gdk_pixbuf_new_from_file ("3DRings.xpm", NULL);
      gtk_assistant_set_header_image (GTK_ASSISTANT (assistant), header_pixbuf);
      
      gdk_color_parse ("#ce0000", &color);
      gtk_assistant_set_header_color (GTK_ASSISTANT (assistant), &color);
      
      gdk_color_parse ("white", &color);
      gtk_assistant_set_header_text_color (GTK_ASSISTANT (assistant), &color);
      
      gtk_container_add (GTK_CONTAINER (window), assistant);
  
      page = gtk_vbox_new (FALSE, 5);
      
      button = gtk_radio_button_new_with_label (NULL, "Branch A");
      gtk_box_pack_start (GTK_BOX (page), button, TRUE, TRUE, 0);
      g_signal_connect (button, "clicked", G_CALLBACK (select_branch), "A");

      button = gtk_radio_button_new_with_label (
						gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
						"Branch B");
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
      gtk_box_pack_start (GTK_BOX (page), button, TRUE, TRUE, 0);
      g_signal_connect (button, "clicked", G_CALLBACK (select_branch), "B");

      gtk_widget_show_all (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 1");
      
      page = get_test_page ("Page 2A");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 2A");

      page = get_test_page ("Page 2B");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 2B");

      page = get_test_page ("Page 3");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 3");

      page = get_test_page ("Page 4A");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 4A");
      gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_CONFIRM);

      page = get_test_page ("Page 4B");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Page 4B");
      gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_CONFIRM);
      
      g_signal_connect (assistant, "cancel", G_CALLBACK (cancel_callback), window);
      g_signal_connect (assistant, "finish", G_CALLBACK (nonlinear_finish_callback), window);
      g_signal_connect (assistant, "back", G_CALLBACK (nonlinear_back_callback), NULL);
      g_signal_connect (assistant, "next", G_CALLBACK (nonlinear_next_callback), NULL);
      g_signal_connect (assistant, "prepare", G_CALLBACK (prepare_callback), NULL);
    }
  if (!GTK_WIDGET_VISIBLE (window))
    {
      assistant = gtk_bin_get_child (GTK_BIN (window));
      gtk_assistant_set_current_page (GTK_ASSISTANT (assistant), NULL);
      gtk_widget_show_all (window);
    }
  else
    {
      gtk_widget_destroy (window);
      window = NULL;
    }
}

static GtkWidget *loop;

static gboolean
loop_next_callback (GtkAssistant *assistant, GtkWidget *page)
{
  gint idx = gtk_assistant_get_current_page_num (assistant);

  if (GTK_IS_LABEL (page))
    g_print ("next %s\n", gtk_label_get_text (GTK_LABEL (page)));
  else 
    g_print ("next page %d\n", idx);
  
  if (idx == 3 && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (loop)))
    {
      gtk_assistant_set_current_page_num (assistant, 1);

      return TRUE;
    }

  return FALSE;
}

static void
create_looping_assistant (GtkWidget *widget)
{
  static GtkWidget *window = NULL;
  GtkWidget *assistant, *page, *button;
  GdkPixbuf *sidebar_pixbuf, *header_pixbuf;
  GdkColor color;

  if (!window)
    {
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);

      g_signal_connect (window, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
      
      assistant = gtk_assistant_new ();
      
      sidebar_pixbuf = gdk_pixbuf_new_from_file ("circles.xbm", NULL);
      gtk_assistant_set_sidebar_image (GTK_ASSISTANT (assistant), sidebar_pixbuf);
      
      gtk_assistant_set_sidebar_image_alignment (GTK_ASSISTANT (assistant), 0.5);
      gdk_color_parse ("#ce0000", &color);
      gtk_assistant_set_sidebar_color (GTK_ASSISTANT (assistant), &color);
      
      header_pixbuf = gdk_pixbuf_new_from_file ("3DRings.xpm", NULL);
      gtk_assistant_set_header_image (GTK_ASSISTANT (assistant), header_pixbuf);
      
      gdk_color_parse ("#ce0000", &color);
      gtk_assistant_set_header_color (GTK_ASSISTANT (assistant), &color);
      
      gdk_color_parse ("white", &color);
      gtk_assistant_set_header_text_color (GTK_ASSISTANT (assistant), &color);
      
      gtk_container_add (GTK_CONTAINER (window), assistant);

      page = get_test_page ("Introduction");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Introduction");

      page = get_test_page ("Content");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Content");

      page = get_test_page ("More Content");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "More Content");

      page = gtk_vbox_new (FALSE, 5);      
      button = gtk_check_button_new_with_label ("Loop");
      gtk_box_pack_start (GTK_BOX (page), button, TRUE, TRUE, 0);
      gtk_widget_show_all (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Loop ?");
      loop = button;

      page = get_test_page ("Confirm");
      gtk_widget_show (GTK_WIDGET (page));
      gtk_assistant_append_page (GTK_ASSISTANT (assistant), page);
      gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page, "Confirm");
      gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), page, GTK_ASSISTANT_PAGE_CONFIRM);
      
      g_signal_connect (assistant, "cancel", G_CALLBACK (cancel_callback), window);
      g_signal_connect (assistant, "finish", G_CALLBACK (finish_callback), window);
      g_signal_connect (assistant, "back", G_CALLBACK (back_callback), NULL);
      g_signal_connect (assistant, "next", G_CALLBACK (loop_next_callback), NULL);
      g_signal_connect (assistant, "prepare", G_CALLBACK (prepare_callback), NULL);
    }
  if (!GTK_WIDGET_VISIBLE (window))
    {
      assistant = gtk_bin_get_child (GTK_BIN (window));
      gtk_assistant_set_current_page (GTK_ASSISTANT (assistant), NULL);
      gtk_widget_show_all (window);
    }
  else
    {
      gtk_widget_destroy (window);
      window = NULL;
    }
}

struct {
  char *label;
  void (*func) (GtkWidget *widget);
} buttons[] =
  {
    { "simple assistant", create_simple_assistant },
    { "generous assistant", create_generous_assistant },
    { "nonlinear assistant", create_nonlinear_assistant },
    { "looping assistant", create_looping_assistant }
  };
int nbuttons = sizeof (buttons) / sizeof (buttons[0]);

int
main (gint argc, gchar **argv)
{
  GtkWidget *window;
  GtkWidget *vbox;
  GtkWidget *button;
  gint i;

  gtk_init (&argc, &argv);

  if (g_getenv ("RTL")) 
    gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  g_signal_connect (window, "destroy",
		    G_CALLBACK (gtk_main_quit),
		    NULL);  
  g_signal_connect (window, "delete-event",
		    G_CALLBACK (gtk_false),
		    NULL);
      
  vbox = gtk_vbox_new (FALSE, 5);
  gtk_container_add (GTK_CONTAINER (window), vbox);

  for (i = 0; i < nbuttons; i++)
    {
      button = gtk_button_new_with_label (buttons[i].label);
      if (buttons[i].func)
        g_signal_connect (button, 
			  "clicked", 
			  G_CALLBACK(buttons[i].func),
			  NULL);
      else
        gtk_widget_set_sensitive (button, FALSE);
      gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
    }

  gtk_widget_show_all (window);
  gtk_main ();
  
  return 0;
}
