/* Bug 710471 - Make gtk_scrolled_window_remove() smart */

/* Usage: ./testremove [test_case]
 *
 * Test cases:
 * even     Don't ref_sink and unref.
 * odd      ref_sink and unref.
 * 0 and 1  Don't remove and re-add.
 * 2 and 3  Remove with
 *          gtk_container_remove(GTK_CONTAINER(scrolled_window), button_test)
 * 4 and 5  Remove with
 *          gtk_container_remove(GTK_CONTAINER(scrolled_window),
 *                               gtk_bin_get_child(GTK_BIN(scrolled_window)))
 * 6 and 7  Imitate the gtkmm function Gtk::ScrolledWindow::remove_with_viewport().
 *
 * Cases 0, 1 and 7 work.
 * Case 5 does not work because the GtkButton is destroyed when its parent
 * (the GtkViewport) is destroyed.
 * Cases 3 and 5 work if the patch in bug 710471 comment 5 is applied.
 */

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

int main(int argc, char* argv[])
{
  GtkWidget* main_win;
  GtkWidget* scrolled_window;
  GtkWidget* button_test;
  int test_case = 0;

  gtk_init(&argc, &argv);

  if (argc > 1)
    test_case = atoi(argv[1]);

  /* Create the main window. */
  main_win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(main_win), "Testing gtk_scrolled_window_remove()");
  gtk_widget_set_size_request(main_win, 200, 80);

  /* Create the GtkScrolledWindow. */
  scrolled_window = gtk_scrolled_window_new(NULL, NULL);

  /* Add a button just to show everything works without gtk_container_remove(). */
  button_test = gtk_button_new_with_label("A Button");
  if (test_case & 1)
    g_object_ref_sink(button_test); /* Assume ownership of the button */

  gtk_widget_set_size_request(button_test, 200, 100);

  /* Add the button to the ScrolledWindow; the ScrolledWindow to the main window. */
  gtk_container_add(GTK_CONTAINER(scrolled_window), button_test);
  gtk_container_add(GTK_CONTAINER(main_win), scrolled_window);

  /* Show all widgets on the main window. */
  gtk_widget_show_all(main_win);

  switch (test_case)
    {
    case 0:
    case 1:
      break;

    case 2:
    case 3:
      /* This should simply remove the button from the ScrolledWindow and re-add it. */
      gtk_container_remove(GTK_CONTAINER(scrolled_window), button_test);
      gtk_container_add(GTK_CONTAINER(scrolled_window), button_test);
      break;

    case 4:
    case 5:
      /* This should simply remove the button from the ScrolledWindow and re-add it. */
      gtk_container_remove(GTK_CONTAINER(scrolled_window), gtk_bin_get_child(GTK_BIN(scrolled_window)));
      gtk_container_add(GTK_CONTAINER(scrolled_window), button_test);
      break;

    case 6:
    case 7:
      /* Imitate gtkmm's Gtk::ScrolledWindow::remove_with_viewport(). */
      gtk_container_remove(GTK_CONTAINER(gtk_bin_get_child(GTK_BIN(scrolled_window))), button_test);
      gtk_container_remove(GTK_CONTAINER(scrolled_window), gtk_bin_get_child(GTK_BIN(scrolled_window)));
      gtk_container_add(GTK_CONTAINER(scrolled_window), button_test);
      break;

    default:
      printf("Unknown test case: %s\n", argv[1]);
      return 1;
    }

  g_signal_connect(main_win, "destroy", G_CALLBACK (gtk_main_quit), NULL);
  gtk_main();
  if (test_case & 1)
    g_object_unref(button_test);

  return 0;
}
