#include <gst/gst.h>
#include <gtk/gtk.h>

static GstElement *pipeline = NULL;

static void
mount_cb (GObject *obj, GAsyncResult *res, gpointer user_data)
{
  gboolean ret;
  const gchar *uri;

  ret = g_file_mount_enclosing_volume_finish (G_FILE (obj), res, NULL);

  g_assert (ret == TRUE);

  g_print ("mounted\n");
  gst_bus_set_flushing ((GstBus *) user_data, FALSE);

  /* This works around bug #588078 */
#if 0
  g_object_get (G_OBJECT (pipeline), "uri", &uri, NULL);
  g_object_set (G_OBJECT (pipeline), "uri", uri, NULL);
#endif

  gst_element_set_state (pipeline, GST_STATE_PLAYING);
}

gboolean
message_handler (GstBus * bus, GstMessage * message, gpointer user_data)
{

  switch (message->type) {
    case GST_MESSAGE_ELEMENT: {
    const GstStructure *s = gst_message_get_structure (message);
    const gchar *name = gst_structure_get_name (s);

    if (strcmp (name, "not-mounted") == 0) {
      GMountOperation *mop = gtk_mount_operation_new (NULL);
      GFile *file = G_FILE (g_value_get_object (gst_structure_get_value (message->structure, "file")));

      g_print ("not-mounted\n");
      gst_element_set_state (pipeline, GST_STATE_NULL);
      gst_bus_set_flushing (bus, TRUE);

      g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE,
        mop, NULL, mount_cb, bus);

      g_object_unref (mop);
    }
    break;
    }

    case GST_MESSAGE_EOS:
      gtk_main_quit ();
      break;
    case GST_MESSAGE_ERROR:
      g_assert_not_reached ();
      break;
  }
  /* we handled the message we want, and ignored the ones we didn't want.
   * so the core can unref the message for us */
  return TRUE;
}

static void
pad_added_cb (GstElement * element, GstPad * pad, gpointer user_data)
{
  /* Link remaining pad after decodebin does its magic. */
  GstPad *sink_pad;

  g_print ("linking\n");

  sink_pad = gst_element_get_static_pad ((GstElement *) user_data, "sink");

  g_assert (!GST_PAD_IS_LINKED (sink_pad));

  gst_pad_link (pad, sink_pad);
}

int
main (int argc, char *argv[])
{
  GstElement *uridecodebin, *fakesink;
  GstBus *bus;
  gint watch_id;

  g_assert (argc == 2);

  gst_init (NULL, NULL);
  gtk_init (NULL, NULL);

#if 0
  pipeline = gst_pipeline_new (NULL);
  g_assert (pipeline);
  uridecodebin = gst_element_factory_make ("uridecodebin", NULL);
  g_object_set (G_OBJECT (pipeline), "uri", argv[1],NULL);
  g_assert (uridecodebin);
  fakesink = gst_element_factory_make ("fakesink", NULL);
  g_assert (fakesink);

  gst_bin_add_many (GST_BIN (pipeline), uridecodebin, fakesink, NULL);

  g_signal_connect (uridecodebin, "pad-added",
		    G_CALLBACK (pad_added_cb), fakesink);
#else
  pipeline = gst_element_factory_make ("playbin2", NULL);
  g_assert (pipeline);
  g_object_set (G_OBJECT (pipeline), "uri", argv[1],NULL);
#endif
  bus = gst_element_get_bus (pipeline);
  watch_id = gst_bus_add_watch (bus, message_handler, NULL);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  /* we need to run a GLib main loop to get the messages */
  gtk_main ();

  return 0;
}
