// Bug 685739
// Test ref counts of managed widgets that are repeatedly added to and removed from a countainer.

#include <gtkmm.h>
#include <iostream>

int main (int argc, char *argv[])
{
	// Create the window
	Gtk::Main kit(argc, argv);
	Gtk::Window main_win(Gtk::WINDOW_TOPLEVEL);
	main_win.set_title ("test");
	main_win.set_size_request (200, 100);

  // Create a managed ButtonBox and a managed Button.
  Gtk::ButtonBox* button_box = Gtk::manage(new Gtk::ButtonBox());
  Gtk::Button* button = Gtk::manage(new Gtk::Button("Test"));
  Glib::Object* button_box_object = button_box;
  Glib::Object* button_object = button;

  // Add and remove the button box in the window and the button in the button box.
  // Do this a few times, and notice if the ref counts increase.
  const int n = 3;
  for (int i = 1; i <= n; ++i)
  {
    std::cout << "Before add    " << i
      << ": ButtonBox floating = " << g_object_is_floating(button_box_object->gobj())
      << ", ref-count = " << button_box_object->gobj()->ref_count << std::endl
      << "                 Button    floating = " << g_object_is_floating(button_object->gobj())
      << ", ref-count = " << button_object->gobj()->ref_count << std::endl;
    main_win.add(*button_box);
    button_box->pack_start(*button);
    std::cout << "Before remove " << i
      << ": ButtonBox floating = " << g_object_is_floating(button_box_object->gobj())
      << ", ref-count = " << button_box_object->gobj()->ref_count << std::endl
      << "                 Button    floating = " << g_object_is_floating(button_object->gobj())
      << ", ref-count = " << button_object->gobj()->ref_count << std::endl;
    main_win.remove();
    button_box->remove(*button);
  }
  std::cout << "After  remove " << n
    << ": ButtonBox floating = " << g_object_is_floating(button_box_object->gobj())
    << ", ref-count = " << button_box_object->gobj()->ref_count << std::endl
    << "                 Button    floating = " << g_object_is_floating(button_object->gobj())
    << ", ref-count = " << button_object->gobj()->ref_count << std::endl;

	// Create a ScrolledWindow
	Gtk::ScrolledWindow main_area;

	// Add and remove the button a few times in the scrolledWindow.
	// Use remove() and possibly remove_with_viewport(),
  Gtk::Bin* child = button;
  for (int i = 1; i <= n; ++i)
  {
    main_area.add(*child);
    child = dynamic_cast<Gtk::Bin*>(main_area.get_child());
    Glib::Object* child_object = child;
    std::cout << "Before ScrolledWindow remove " << i
      << ": Viewport floating = " << g_object_is_floating(child_object->gobj())
      << ", ref-count = " << child_object->gobj()->ref_count << std::endl;
    main_area.remove();
    std::cout << "After  ScrolledWindow remove " << i
      << ": Viewport floating = " << g_object_is_floating(child_object->gobj())
      << ", ref-count = " << child_object->gobj()->ref_count << std::endl;
  }

  // Remove the button from the automatically added viewport.
  child->remove();
  std::cout << "After  Viewport       remove  "
    << ": Button floating = " << g_object_is_floating(button_object->gobj())
    << ", ref-count = " << button_object->gobj()->ref_count << std::endl;

#if 0
  // Compiles only if Gtk::ScrolledWindow::remove_with_viewport() exists.
  for (int i = 1; i <= n; ++i)
  {
    main_area.add(*button);
    std::cout << "Before ScrolledWindow remove " << i
      << ": Button floating = " << g_object_is_floating(button_object->gobj())
      << ", ref-count = " << button_object->gobj()->ref_count << std::endl;
    main_area.remove_with_viewport();
    std::cout << "After  ScrolledWindow remove " << i
      << ": Button floating = " << g_object_is_floating(button_object->gobj())
      << ", ref-count = " << button_object->gobj()->ref_count << std::endl;
  }
#endif

	// Add the button to the ScrolledWindow; the ScrolledWindow to the main window.
	button->set_size_request (150, 50);
	main_area.add(*button);
	main_win.add(main_area);

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

	kit.run(main_win);
	return 0;
}
