#include <stdio.h>
#include <sys/time.h>
#include <time.h>

#include <gst/gst.h>

int main (int argc, char *argv[])
{
	if (argc != 2) {
		printf ("%s: Detect media type.\nUsage: %s <filename>\n",
			argv[0], argv[0]);
		exit (1);
	}

	gst_init (&argc, &argv);
	
	GstElement  *playbin;
	GstBus      *bus;
	const gchar *uri;
	int i = 0;

        // while (i++ < 1000) {

	playbin = gst_element_factory_make ("playbin", "play");
	if (!playbin) {
		printf ("Can't create playbin\n");
		exit (2);
	}

	bus = gst_element_get_bus (playbin);

	if (g_path_is_absolute (argv[1]))
		uri = g_strdup_printf ("file://%s", argv[1]);
	else {
		gchar *cur_dir = g_get_current_dir ();
		uri = g_strdup_printf ("file://%s/%s", cur_dir, argv[1]);
		g_free (cur_dir);
	}

	while (i++ < 1000) {
	struct timeval tv, tv2;

	gettimeofday (&tv, NULL);
	printf ("%s\n", gst_version_string ());

	g_object_set (playbin, "uri", uri, NULL);

	gst_element_set_state (playbin, GST_STATE_PAUSED);	

	do {
		GstMessage *message;
		GstMessageType events;

		events = GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR;
		message = gst_bus_poll (bus, events, -1);

                if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR) {
			gst_message_unref (message);
			break;
		}

		if ((GstElement *)GST_MESSAGE_SRC (message) != playbin) {
			gst_message_unref (message);
			continue;
		}

		if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STATE_CHANGED) {
	                GstState old, new, pending;
        	        gst_message_parse_state_changed (message, 
							 &old, &new, &pending);
			
			if (new == GST_STATE_PAUSED) {
				gst_message_unref (message);
				break;
			}
		}
		gst_message_unref (message);
	} while (TRUE);

	GValueArray *info_arr = NULL;
	g_object_get (playbin, "stream-info-value-array", &info_arr, NULL);

	if (!info_arr) {
		printf ("No stream-info-value-array\n");
		exit (3);
	}

	guint i;
	for (i = 0; i < info_arr->n_values; ++i) {
		GObject *info_obj;
		GValue *val;

		val = g_value_array_get_nth (info_arr, i);
		info_obj = g_value_get_object (val);
		if (info_obj) {
			GParamSpec *pspec;
			GEnumValue *val;
			gint type = -1;

			g_object_get (info_obj, "type", &type, NULL);
			pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (info_obj), "type");
			val = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, type);
			if (val) {
				printf ("nick: %s name: %s\n",
					val->value_nick, val->value_name);
			}
		}
	}

	g_value_array_free (info_arr);

        gst_element_set_state (playbin, GST_STATE_NULL);

	gettimeofday (&tv2, NULL);
	printf ("This took: %lu\n", (tv2.tv_sec - tv.tv_sec)*1000000 + tv2.tv_usec - tv.tv_usec);
	}

        gst_object_unref (playbin);
        gst_object_unref (bus); 

	return 0;
}
