#include <gtk/gtk.h>

const gchar *menu_ui =
  "<interface>"
  "  <menu id='menu'>"
  "    <section>"
  "      <item>"
  "        <attribute name='label'>flip</attribute>"
  "        <attribute name='action'>thing.flip</attribute>"
  "      </item>"
  "    </section>"
  "  </menu>"
  "  <menu id='submenu-one'>"
  "    <section>"
  "      <item>"
  "        <attribute name='label'>Hi</attribute>"
  "        <attribute name='action'>thing.hi</attribute>"
  "      </item>"
  "    </section>"
  "  </menu>"
  "  <menu id='submenu-two'>"
  "    <section>"
  "      <item>"
  "        <attribute name='label'>Yes</attribute>"
  "        <attribute name='action'>thing.yes</attribute>"
  "      </item>"
  "    </section>"
  "  </menu>"
  "</interface>";


struct things {
	GtkBuilder *builder;
	GMenu *button_menu;
	GMenuItem *submenu_item;
	int flap;
} stuff;

static void
action_activated (GSimpleAction *action,
                  GVariant      *parameter,
                  gpointer       user_data)
{
  GtkWindow *parent = user_data;
  GtkWidget *dialog;

  dialog = gtk_message_dialog_new (parent,
                                   GTK_DIALOG_DESTROY_WITH_PARENT,
                                   GTK_MESSAGE_INFO,
                                   GTK_BUTTONS_CLOSE,
                                   "Activated action `%s`",
                                   g_action_get_name (G_ACTION (action)));

  g_signal_connect_swapped (dialog, "response",
                            G_CALLBACK (gtk_widget_destroy), dialog);

  gtk_widget_show_all (dialog);
}

static void
flip_activated (GSimpleAction 	*action,
		GVariant 	*parameter,
		gpointer	 user_data)
{
  GMenu *menu;
  GMenuItem *sub;

  if (g_menu_model_get_n_items (G_MENU_MODEL (stuff.button_menu)) > 1)
    g_menu_remove (stuff.button_menu, 1);

  menu = G_MENU (gtk_builder_get_object (stuff.builder, stuff.flap ? "submenu-two" : "submenu-one"));
  sub = g_menu_item_new ("thing",  NULL);
  g_menu_item_set_link (sub, G_MENU_LINK_SUBMENU, G_MENU_MODEL (menu));
  g_menu_insert_item (stuff.button_menu, 1, sub);

  stuff.flap = !stuff.flap;
}

static GActionEntry flip_entries[] = {
  { "flip", flip_activated },
};

static GActionEntry thing_entries[] = {
  { "hi", action_activated },
  { "yes", action_activated },
};

static void
activate (GApplication *app,
          gpointer      user_data)
{
  GtkWidget *win;
  GtkWidget *button;
  GSimpleActionGroup *actions;
  GtkBuilder *builder;
  GMenu *menu;
  GMenuItem *section;

  if (gtk_application_get_windows (GTK_APPLICATION (app)) != NULL)
    return;

  win = gtk_application_window_new (GTK_APPLICATION (app));
  gtk_window_set_default_size (GTK_WINDOW (win), 200, 300);

  actions = g_simple_action_group_new ();
  g_action_map_add_action_entries (G_ACTION_MAP (actions), flip_entries, G_N_ELEMENTS (flip_entries), win);
  g_action_map_add_action_entries (G_ACTION_MAP (actions), thing_entries, G_N_ELEMENTS (thing_entries), win);

  stuff.builder = gtk_builder_new ();
  gtk_builder_add_from_string (stuff.builder, menu_ui, -1, NULL);

  stuff.button_menu = g_menu_new ();

  section = g_menu_item_new ("", NULL);
  menu = G_MENU (gtk_builder_get_object (stuff.builder, "menu"));
  g_menu_item_set_link (section, G_MENU_LINK_SECTION, G_MENU_MODEL (menu));
  g_menu_insert_item (stuff.button_menu, 0, section);

  button = gtk_menu_button_new ();
  gtk_button_set_label (GTK_BUTTON (button), "Menu");
  gtk_widget_insert_action_group (button, "thing", G_ACTION_GROUP (actions));
  gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), G_MENU_MODEL (stuff.button_menu));
  gtk_widget_set_halign (GTK_WIDGET (button), GTK_ALIGN_CENTER);
  gtk_widget_set_valign (GTK_WIDGET (button), GTK_ALIGN_START);
  gtk_container_add (GTK_CONTAINER (win), button);
  gtk_container_set_border_width (GTK_CONTAINER (win), 12);
  gtk_widget_show_all (win);

  g_object_unref (actions);
}

int
main(int    argc,
     char **argv)
{
  GtkApplication *app;

  app = gtk_application_new ("org.gtk.Example", 0);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);

  return g_application_run (G_APPLICATION (app), argc, argv);
}
