#include <gtk/gtk.h>

/* compile with gcc `pkg-config --cflags --libs gtk+-3.0` -o app app.c */

static gchar **remaining_args = NULL;
static gboolean version = FALSE;

static const GOptionEntry options [] =
{
  { "version", 'v', 0, G_OPTION_ARG_NONE, &version,
    "Show the program version and exit", NULL },

  { 
    G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &remaining_args,
    NULL, "args..." },

  { NULL }
};

static void
update_text (GtkTextView *text, const gchar **args)
{
  int i;
  GtkTextIter iter;
  GtkTextBuffer *buffer = gtk_text_view_get_buffer (text);

  for (i = 0; args && args[i]; i++)
    {
      gtk_text_buffer_get_end_iter (buffer, &iter);
      gtk_text_buffer_insert (buffer, &iter, args[i], -1);
      gtk_text_buffer_insert (buffer, &iter, "\n", 1);
    }

  gtk_text_buffer_get_end_iter (buffer, &iter);
  gtk_text_view_scroll_to_iter (text, &iter, 0, FALSE, 0, 0); 
}

static void
app_action_received (GApplication *app, gchar *action, GVariant *data, GtkTextView *text)
{
  GVariantIter iter;
  gchar *key;
  GVariant *value;
  const gchar **argv;

  g_variant_iter_init (&iter, data);
  g_variant_iter_loop (&iter, "{sv}", &key, &value);

  argv = g_variant_get_bytestring_array (value, NULL);
  update_text (text, argv);
  g_free (argv);
}

int main (int argc, char **argv)
{
  GOptionContext *context;
  GtkApplication *app;
  GtkWidget *window, *text;
  gboolean success;

  context = g_option_context_new ("- Sample program");
  g_option_context_add_main_entries (context, options, NULL);
  g_option_context_add_group (context, gtk_get_option_group (FALSE));
  success = g_option_context_parse (context, &argc, &argv, NULL);
  g_option_context_free (context);

  if (!success)
    {
      g_print ("run app --help\n");
      return 1;
    }

  if (version)
    {
      g_print ("sample 0.1\n");
      return 0;
    }

  app = gtk_application_new_without_quit ("org.gnome.Sample");
  if (g_application_is_remote (G_APPLICATION (app)))
    {
      GVariantBuilder builder;
      GVariant *platform_data;

      if (!remaining_args)
        remaining_args = g_new0 (gchar *, 1);

      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
      g_variant_builder_add (&builder, "{sv}",
				       "args",
				       g_variant_new_bytestring_array ((const gchar * const*)remaining_args, -1));
      platform_data = g_variant_builder_end (&builder);

      g_application_invoke_action (G_APPLICATION (app), "uri", platform_data);
      g_variant_unref (platform_data);
      return 0;
    }
  g_application_add_action (G_APPLICATION (app), "uri", "");

  window = GTK_WIDGET (gtk_application_create_window (app));
  gtk_widget_set_size_request (window, 300, 300);

  text = gtk_text_view_new ();
  gtk_container_add (GTK_CONTAINER (window), text);
  gtk_widget_show_all (window);

  update_text (GTK_TEXT_VIEW (text), (const gchar **)remaining_args);
  g_strfreev (remaining_args);

  g_signal_connect (app, "action-with-data", G_CALLBACK (app_action_received), text);

  gtk_application_run (app);

  return 0;
}
