#include <assert.h>
#include <gst/gst.h>
#include <glib.h>
#include <string.h>
#include <stdio.h>

struct NextStreamData {
	GstElement *pipeline;
	const char *next_uri;
};

static gboolean handleBusMessage(GstBus     *bus,
        GstMessage *msg,
        gpointer    data)
 {

    switch (GST_MESSAGE_TYPE (msg)) {

    case GST_MESSAGE_EOS:
        printf("handleBusMessage: End of stream\n");

        break;

    case GST_MESSAGE_ERROR:
        gchar  *debug;
        GError *error;

        gst_message_parse_error (msg, &error, &debug);
        g_free (debug);
        printf("handleBusMessage: An error has occured with element %s: %s.\n", GST_OBJECT_NAME (msg->src), error->message);


    case GST_MESSAGE_STATE_CHANGED:
        GstState old_state, new_state, pending_state;
        gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
        //printf("handleBusMessage: Message state changed from %s is not handled!",GST_OBJECT_NAME(GST_MESSAGE_SRC(msg)));
        break;
    case GST_MESSAGE_TAG: {
        //printf ("handleBusMessage: GST_MESSAGE_TAG");
        /*GstTagList *tags = NULL;
        gchar* codec = NULL;
        gst_message_parse_tag (msg, &tags);

        if (gst_tag_list_get_string (tags, GST_TAG_AUDIO_CODEC, &codec)) {
            CL_DEBUG("got audiocodec tag %s",codec);
            core->setCurrentCodec(codec);
        }
        CL_SAFE_FREE(codec);
        gst_tag_list_free (tags);*/
        break;
    }
    case GST_MESSAGE_STREAM_STATUS: {

        break;}
    default:
        //printf("handleBusMessage: unsupported message %s",gst_message_type_get_name(GST_MESSAGE_TYPE (msg)));
      break;
    }
    return TRUE;
 }

static void prepare_next_stream(GstElement *obj, gpointer userdata) {
	struct NextStreamData *data = (struct NextStreamData*) userdata;
	assert(data->next_uri);
	g_print("about-to-finish; setting next to %s\n", data->next_uri);
	g_object_set(G_OBJECT(data->pipeline), "uri", data->next_uri, NULL);
}

int main (int argc, char *argv[]) {
	GMainLoop *loop;
	GstElement *pipeline;

	/* Initialisation */
	gst_init (&argc, &argv);

	loop = g_main_loop_new (NULL, FALSE);

	/* Check input arguments */
	if (argc < 3) {
		g_printerr ("Usage: %s <filenames or URLs>\n", argv[0]);
		return -1;
	}

	/* Create playbin. Different names in different versions  */
#if (GST_VERSION_MAJOR < 1)
	pipeline = gst_element_factory_make("playbin2", "play");
#else
	pipeline = gst_element_factory_make("playbin", "play");
#endif

	/* Register about-to-finish callback to re-set the URI */
	struct NextStreamData replay_data;
	replay_data.pipeline = pipeline;
	replay_data.next_uri = argv[2];   // let's loop forever the same URI
	g_signal_connect(pipeline, "about-to-finish",
		G_CALLBACK(prepare_next_stream), &replay_data);

	/* Set initial URI */
	g_object_set (G_OBJECT (pipeline), "uri", argv[1], NULL);



	GstElement* audio_sink = gst_element_factory_make("alsasink","alsasink");
//	g_object_set (audio_sink, "device", "default", NULL);

	g_object_set(G_OBJECT(pipeline), "audio-sink", audio_sink, NULL);

	GstBus* bus  = gst_element_get_bus(pipeline);
	gst_bus_add_watch (bus, handleBusMessage, &replay_data);

	g_print ("Now playing: %s\n", argv[1]);
	gst_element_set_state (pipeline, GST_STATE_PLAYING);



	/* Iterate */
	g_print ("Running...\n");
	g_main_loop_run (loop);

	/* since we loop endlessly, the follwing is never reached */

	/* Out of the main loop, clean up nicely */
	g_print ("Returned, stopping playback\n");
	gst_element_set_state (pipeline, GST_STATE_NULL);

	g_print ("Deleting pipeline\n");
	gst_object_unref (GST_OBJECT (pipeline));
	g_main_loop_unref (loop);

	return 0;
}
