#include <glib.h>
#include <gst/gst.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>

static void connectCallback(GstElement *elem,GstPad *pad,gpointer other){
    GstPad *sinkPad = (GstPad*)other;
    if(GST_PAD_LINK_FAILED(gst_pad_link(pad,sinkPad))){
        printf("Failed to link pad\n");
    }
    gst_object_unref(sinkPad);
}

static gboolean busCallback(GstBus *bus,GstMessage *msg,gpointer data){
    GMainLoop *loop = (GMainLoop *) data;
    switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_EOS:
        g_print ("End of stream\n");
        g_main_loop_quit (loop);
        break;
    case GST_MESSAGE_ERROR: {
        gchar  *debug;
        GError *error;
        gst_message_parse_error (msg, &error, &debug);
        g_free (debug);
        g_printerr ("Error: %s\n", error->message);
        g_error_free (error);
        g_main_loop_quit (loop);
        break;
    }
    default:
        break;
    }

    return TRUE;
}

int main(int argc, char** argv){
    if(!XInitThreads()){
        printf("init went wrong\n");
    }
    gst_init(&argc,&argv);

    GMainLoop *loop = g_main_loop_new(NULL,FALSE);
    GstPipeline *pipeline = GST_PIPELINE(gst_pipeline_new("overflowRunner"));

    GstBus *bus = gst_pipeline_get_bus(pipeline);
    gst_bus_add_watch(bus,busCallback,loop);


    GstElement *fileSrc = gst_element_factory_make("filesrc","file");
    g_object_set(G_OBJECT(fileSrc),"location","./test.png",NULL);
    GstElement *decode = gst_element_factory_make("decodebin","decode");
    GstElement *convert = gst_element_factory_make("videoconvert","convert");
    GstElement *imageFreeze = gst_element_factory_make("imagefreeze","freeze");
    GstElement *videoSink = gst_element_factory_make("autovideosink","video");
    gst_bin_add_many(GST_BIN(pipeline),fileSrc,decode,convert,imageFreeze,videoSink,NULL);

    gst_element_link(fileSrc,decode);
    gst_element_link_many(convert,imageFreeze,videoSink,NULL);

    GstPad *sinkPad = gst_element_get_static_pad(convert,"sink");
    //gst_object_ref(GST_OBJECT(sinkPad));

    g_signal_connect(decode,"pad-added",G_CALLBACK(connectCallback),sinkPad);

    gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
    gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
    gst_element_seek(imageFreeze,1.0,GST_FORMAT_TIME,GST_SEEK_FLAG_FLUSH,GST_SEEK_TYPE_SET,0LL,GST_SEEK_TYPE_SET,10*GST_SECOND);
    g_main_loop_run(loop);

}
