/* #include "config.h" */
#include <gtk/gtk.h>

#include <string.h>
#include <stdio.h>

static void
setup_combo_entry (GtkComboBoxText *combo)
{
  gtk_combo_box_text_append_text (combo,
				   "dum de dum");
  gtk_combo_box_text_append_text (combo,
				   "la la la");
  gtk_combo_box_text_append_text (combo,
				   "la la la dum de dum la la la la la la boom de da la la");
  gtk_combo_box_text_append_text (combo,
				   "bloop");
  gtk_combo_box_text_append_text (combo,
				   "bleep");
  gtk_combo_box_text_append_text (combo,
				   "klaas");
  gtk_combo_box_text_append_text (combo,
				   "klaas0");
  gtk_combo_box_text_append_text (combo,
				   "klaas1");
  gtk_combo_box_text_append_text (combo,
				   "klaas2");
  gtk_combo_box_text_append_text (combo,
				   "klaas3");
  gtk_combo_box_text_append_text (combo,
				   "klaas4");
  gtk_combo_box_text_append_text (combo,
				   "klaas5");
  gtk_combo_box_text_append_text (combo,
				   "klaas6");
  gtk_combo_box_text_append_text (combo,
				   "klaas7");
  gtk_combo_box_text_append_text (combo,
				   "klaas8");
  gtk_combo_box_text_append_text (combo,
				   "klaas9");
  gtk_combo_box_text_append_text (combo,
				   "klaasa");
  gtk_combo_box_text_append_text (combo,
				   "klaasb");
  gtk_combo_box_text_append_text (combo,
				   "klaasc");
  gtk_combo_box_text_append_text (combo,
				   "klaasd");
  gtk_combo_box_text_append_text (combo,
				   "klaase");
  gtk_combo_box_text_append_text (combo,
				   "klaasf");
  gtk_combo_box_text_append_text (combo,
				   "klaas10");
  gtk_combo_box_text_append_text (combo,
				   "klaas11");
  gtk_combo_box_text_append_text (combo,
				   "klaas12");
}

/*!! */
static void
on_combo_changed(GtkComboBox* combo, void* data)
{
  GtkEntry* entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combo)));
  if (entry)
  {
    const gint item = gtk_combo_box_get_active(combo);
    const gchar* text = gtk_entry_get_text(entry);
    printf("Combo changed (item %d): %s\n", item, text);
  }
}

static void
on_combo_editing_done(GtkComboBox* combo, void* data)
{
  GtkEntry* entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combo)));
  if (entry)
  {
    const gchar* text = gtk_entry_get_text(entry);
    printf("Combo editing done: %s\n", text);
  }
}

static void
on_combo_entry_changed(GtkEntry* entry, void* data)
{
  const gchar* text = gtk_entry_get_text(entry);
  printf("Combo-entry changed: %s\n", text);
}

static void
on_combo_entry_editing_done(GtkEntry* entry, void* data)
{
  const gchar* text = gtk_entry_get_text(entry);
  printf("Combo-entry editing done: %s\n", text);
}

static void
on_combo_entry_activate(GtkEntry* entry, void* data)
{
  const gchar* text = gtk_entry_get_text(entry);
  printf("Combo-entry activate: %s\n", text);
}

static void
on_entry_changed(GtkEntry* entry, void* data)
{
  const gchar* text = gtk_entry_get_text(entry);
  printf("Entry changed: %s\n", text);
}

static void
on_entry_editing_done(GtkEntry* entry, void* data)
{
  const gchar* text = gtk_entry_get_text(entry);
  printf("Entry editing done: %s\n", text);
}

static void
on_entry_activate(GtkEntry* entry, void* data)
{
  const gchar* text = gtk_entry_get_text(entry);
  printf("Entry activate: %s\n", text);
}

int
main (int argc, char **argv)
{
        GtkWidget *window, *mainbox;
        GtkWidget *comboboxtext, *entry;
        GtkWidget *tmp, *boom;

        gtk_init (&argc, &argv);

        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        gtk_container_set_border_width (GTK_CONTAINER (window), 5);
        g_signal_connect (window, "destroy", gtk_main_quit, NULL);

        /* gtk_vbox_new() exists in both gtk+ 2 and 3 (deprecated in gtk+ 3). */
        /* gtk_box_new() exists in only gtk+ 3. */
        /* mainbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); */
        mainbox = gtk_vbox_new (FALSE, 2);
        gtk_container_add (GTK_CONTAINER (window), mainbox);

        /* GtkComboBoxEntry */
        tmp = gtk_frame_new ("GtkComboBox with entry");
        gtk_box_pack_start (GTK_BOX (mainbox), tmp, FALSE, FALSE, 0);

        /* boom = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); */
        boom = gtk_vbox_new (FALSE, 0);
        gtk_container_set_border_width (GTK_CONTAINER (boom), 5);
        gtk_container_add (GTK_CONTAINER (tmp), boom);

        comboboxtext = gtk_combo_box_text_new_with_entry ();
        setup_combo_entry (GTK_COMBO_BOX_TEXT (comboboxtext));
        gtk_container_add (GTK_CONTAINER (boom), comboboxtext);

        /*!! */
        g_signal_connect (comboboxtext, "changed", G_CALLBACK (on_combo_changed), NULL);
        g_signal_connect (comboboxtext, "editing-done", G_CALLBACK (on_combo_editing_done), NULL);
        tmp = gtk_bin_get_child(GTK_BIN(comboboxtext));
        if (tmp)
        {
          g_signal_connect (tmp, "changed", G_CALLBACK (on_combo_entry_changed), NULL);
          g_signal_connect (tmp, "editing-done", G_CALLBACK (on_combo_entry_editing_done), NULL);
          g_signal_connect (tmp, "activate", G_CALLBACK (on_combo_entry_activate), NULL);
        }

        /* !! GtkEntry */
        tmp = gtk_frame_new ("GtkEntry");
        gtk_box_pack_start (GTK_BOX (mainbox), tmp, FALSE, FALSE, 0);

        /* boom = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); */
        boom = gtk_vbox_new (FALSE, 0);
        gtk_container_set_border_width (GTK_CONTAINER (boom), 5);
        gtk_container_add (GTK_CONTAINER (tmp), boom);

        entry = gtk_entry_new ();
        gtk_container_add (GTK_CONTAINER (boom), entry);

        g_signal_connect (entry, "changed", G_CALLBACK (on_entry_changed), NULL);
        g_signal_connect (entry, "editing-done", G_CALLBACK (on_entry_editing_done), NULL);
        g_signal_connect (entry, "activate", G_CALLBACK (on_entry_activate), NULL);

        gtk_widget_show_all (window);

        gtk_main ();

        return 0;
}

