#include <gtk/gtk.h>

GtkWidget* main_window = 0;
GtkWidget* container = 0;
GtkWidget* new_win_button = 0;
GtkWidget* toolbar = 0;

/*
 * Callback to reparent child window to/from main window
 */
void dock_cb( GtkWidget* button,
	      GtkWidget* vb )
{
    GtkWidget* parent_widget;
    gpointer* user_data;
    GtkWidget* window;

    user_data = g_object_steal_data( G_OBJECT( vb ), "child_widget" );
    if( user_data )
    {
	parent_widget = GTK_WIDGET( user_data );
	window = GTK_WIDGET( g_object_get_data( G_OBJECT( parent_widget ),
						"window" ) );
	gtk_widget_reparent( vb, window );
	gtk_widget_show( window );
    }
    else
    {
	window = gtk_widget_get_toplevel( vb );
	parent_widget = container;
	g_object_set_data( G_OBJECT( vb ), "child_widget", parent_widget );
	g_object_set_data( G_OBJECT( parent_widget ), "window", window );
	gtk_widget_reparent( vb, parent_widget );
	gtk_widget_hide( window );

/*
 * Uncomment those lines to get toolbuttons activatable
 * 
	gtk_widget_hide( toolbar );
	gtk_widget_show( toolbar );
 */
    }
}

/*
 * Show which toolbutton was pressed
 */
void toolbar_cb( GtkToolButton* tb, gpointer data )
{
    puts( (gchar*)data );
}

/*
 * Create child window with toolbar;
 * button - to reparent window content to/from main window
 */
void new_win_cb( GtkWidget* button,
		 gpointer* data )
{
    GtkWidget* window;
    GtkWidget* vb;
    GtkWidget* but;
    GtkToolItem* item;

    window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    g_signal_connect( main_window, "destroy",
		      G_CALLBACK( gtk_widget_destroyed ),
		      window );
    g_signal_connect( window, "delete-event",
		      G_CALLBACK( gtk_widget_destroy ),
		      window );

    vb = gtk_vbox_new( FALSE, 5 );
    gtk_container_add( GTK_CONTAINER( window ), vb );

    toolbar = gtk_toolbar_new();
    gtk_box_pack_start( GTK_BOX( vb ), toolbar, FALSE, FALSE, 0 );

    item = gtk_tool_button_new_from_stock( GTK_STOCK_ADD );
    g_signal_connect( GTK_WIDGET( item ), "clicked",
		      G_CALLBACK( toolbar_cb ),
		      "add toolbar" );
    gtk_toolbar_insert( GTK_TOOLBAR( toolbar ),
			item,
			-1 );

    item = gtk_tool_button_new_from_stock( GTK_STOCK_REMOVE );
    g_signal_connect( GTK_WIDGET( item ), "clicked",
		      G_CALLBACK( toolbar_cb ),
		      "remove toolbar" );
    gtk_toolbar_insert( GTK_TOOLBAR( toolbar ),
			item,
			-1 );

    but = gtk_button_new_with_label( "(UN)DOCK" );
    gtk_box_pack_start( GTK_BOX( vb ), but, FALSE, FALSE, 0 );
    g_signal_connect( but, "clicked",
		      G_CALLBACK( dock_cb ),
		      vb );

    gtk_widget_set_usize( window, 200, 100 );
    gtk_widget_show_all( window );

    // avoiding crash
    gtk_widget_set_sensitive( new_win_button, FALSE );
}

/*
 * Create main window;
 * frame container - where to reparent child windows;
 * button - to create child windows
 */
void create_window()
{
    GtkWidget* vb;

    main_window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    g_signal_connect( main_window, "destroy",
		      G_CALLBACK( gtk_main_quit ),
		      NULL );
    g_signal_connect( main_window, "delete-event",
		      G_CALLBACK( gtk_false ),
		      NULL );

    vb = gtk_vbox_new( FALSE, 5 );
    gtk_container_add( GTK_CONTAINER( main_window ), vb );

    container = gtk_frame_new( 0 );
    gtk_box_pack_start( GTK_BOX( vb ), container, TRUE, TRUE, 0 );

    new_win_button = gtk_button_new_with_label( "NEW WINDOW" );
    gtk_box_pack_start( GTK_BOX( vb ), new_win_button, FALSE, FALSE, 0 );
    g_signal_connect( new_win_button, "clicked",
		      G_CALLBACK( new_win_cb ),
		      NULL );

    gtk_widget_set_usize( main_window, 200, 200 );
    gtk_widget_show_all( main_window );
}

int main( int argc, char* argv[] )
{
    gtk_init( &argc, &argv );
    create_window();
    gtk_main();

    return 0;
}
