#include <gst/gst.h>

GstElement *pipeline;

static void
show_error (GstMessage *msg)
{
  GError *err = NULL;
  gchar *dbg = NULL;

  gst_message_parse_error (msg, &err, &dbg);
  g_error ("Error: %s\n%s\n", err->message, (dbg) ? dbg : "(no debug details)");
}

int
main (int argc, char ** argv)
{
  GstClockTime pos;
  GstMessage *msg;
  gfloat fdiff;
  gchar *uri;

  gst_init (&argc, &argv);

  if (argc != 3) {
    g_printerr ("Usage: %s SEEK-STEP URI\n", argv[0]);
    exit (-1);
  }

  if (sscanf (argv[1], "%f", &fdiff) != 1 || fdiff < 0.0) {
    g_printerr ("Could not parse seek step '%s'\n", argv[1]);
    g_printerr ("Usage: %s SEEK-STEP URI\n", argv[0]);
    exit (-1);
  }

  fdiff *= GST_SECOND;

  pipeline = gst_element_factory_make ("playbin2", NULL);
  if (g_str_has_prefix (argv[2], "file://") || g_str_has_prefix (argv[2], "http://")) {
    uri = g_strdup (argv[2]);
  } else {
    GError *err = NULL;

    uri = g_filename_to_uri (argv[2], NULL, &err);
    if (err) {
      g_printerr ("Could not parse file or uri '%s': %s\n", argv[2], err->message);
      g_printerr ("Usage: %s URI SEEK-STEP\n", argv[0]);
      exit (-1);
    }
  }

  g_print ("uri: %s\n", uri);
  g_object_set (pipeline, "uri", uri, NULL);
  g_free (uri);

  g_print ("Prerolling...\n");
  gst_element_set_state (pipeline, GST_STATE_PAUSED);

  msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (pipeline), -1,
      GST_MESSAGE_ERROR | GST_MESSAGE_ASYNC_DONE);

  if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR)
    show_error (msg);

  gst_message_unref (msg);

  g_print ("Prerolled. Now playing!\n");
  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  g_usleep (3 * G_USEC_PER_SEC);

  for (pos = fdiff; pos <= 10 * fdiff;  pos += fdiff) {
    GstFormat fmt = GST_FORMAT_TIME;
    gint64 cur = -1;

    g_print ("Seeking to %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (pos));

    if (!gst_element_seek_simple (pipeline, GST_FORMAT_TIME,
         GST_SEEK_FLAG_FLUSH, pos)) {
      g_error ("Seek failed.\n");
    }

    msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (pipeline), -1,
        GST_MESSAGE_ERROR | GST_MESSAGE_ASYNC_DONE);

    if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR)
      show_error (msg);

    gst_message_unref (msg);
 
    g_print ("Done.\n");

    if (!gst_element_query_position (pipeline, &fmt, &cur))
      g_error ("Position query failed!\n");

    g_print ("Current position: %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (cur));

    g_usleep (3 * G_USEC_PER_SEC);
  }

  /* exit without shut down, makes it easier to read the log */
#if 0
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
#endif

#if 0
  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  g_usleep (3 * G_USEC_PER_SEC);
#endif

  return 0;
}
