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

GstElement *pipeline;
GstElement *src, *sink;
GstElement *demux, *mux;

static void
event_loop (void)
{
	GstBus *bus;
	gboolean running = TRUE;

	bus = gst_element_get_bus (pipeline);
	while (running) {
		GstMessage *message;
		
		message = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
		if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_EOS)
			running = FALSE;

		gst_message_unref (message);
	}
}

static void
tagger_pad_added (GstElement *demuxer, GstPad *pad, GstTagList *taglist)
{
	GstCaps *caps;
	GstStructure *structure;
	const gchar *mimetype;
	GstPad *conn_pad = NULL;

	caps = gst_pad_get_caps (pad);
	structure = gst_caps_get_structure (caps, 0);
	mimetype = gst_structure_get_name (structure);

	if (strcmp (mimetype, "audio/x-vorbis") == 0) {
		GstElement *tagger;

		g_print ("found vorbis stream, using vorbistag\n");

		tagger = gst_element_factory_make ("vorbistag", NULL);
		gst_tag_setter_merge_tags (GST_TAG_SETTER (tagger), taglist, GST_TAG_MERGE_REPLACE);

		gst_bin_add (GST_BIN (pipeline), tagger);
		gst_element_link (tagger, mux);
		conn_pad = gst_element_get_compatible_pad (tagger, pad, NULL);
	} else {
		GstPad *conn_pad;

		conn_pad = gst_element_get_compatible_pad (mux, pad, NULL);
		g_print ("found stream with no available tagging element\n");
	}

	gst_pad_link (pad, conn_pad);

	gst_caps_unref (caps);
}

int
main (int argc, char *argv[])
{
	GstTagList *taglist;
	int i;

	gst_init (&argc, &argv);

	pipeline = gst_pipeline_new (NULL);

	if (argc <= 2) {
		g_print ("usage: %s orig.ogg tagged.ogg tag1 value1 tag2 value2 ...\n", argv[0]);
		return 1;
	}

	/* source and sink */
	src = gst_element_factory_make ("filesrc", NULL);
	g_object_set (src, "location", argv[1], NULL);

	sink = gst_element_factory_make ("filesink", NULL);
	g_object_set (sink, "location", argv[2], NULL);

	/* muxer and demuxer */
	demux = gst_element_factory_make ("oggdemux", NULL);
	mux = gst_element_factory_make ("oggmux", NULL);


	/* setup tags */
	taglist = gst_tag_list_new ();
	for (i = 4; i < argc; i+= 2)
		gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, argv[i-1], argv[i], NULL);

	/* linking */
	gst_bin_add_many (GST_BIN (pipeline), src, demux, mux, sink, NULL);
	gst_element_link (src, demux);
	g_signal_connect (demux, "pad-added", G_CALLBACK (tagger_pad_added), taglist);
	gst_element_link (mux, sink);

	gst_element_set_state (pipeline, GST_STATE_PLAYING);
	event_loop ();

	return 0;
}

