#include <stdio.h>
#include <glib-2.0/glib.h>


int mci_CallbackCount = 0;
int mci_PrepareCount = 0;
int mci_CheckCount = 0;
int mci_DispatchCount = 0;
int mci_PollCount = 0;

gboolean mci_CallbackRetValue = FALSE;
gboolean mci_PrepareRetValue = FALSE;
gboolean mci_CheckRetValue = FALSE;

gint mci_Timeout = 0;

int mci_cb_status[4] = {0, 0, 0, 0};

gboolean mci_callback_P1(gpointer data)
    {mci_cb_status[0]++; return mci_CallbackRetValue;}
gboolean mci_callback_P2(gpointer data)
    {mci_cb_status[1]++; return mci_CallbackRetValue;}
gboolean mci_callback_P3(gpointer data)
    {mci_cb_status[2]++; return mci_CallbackRetValue;}
gboolean mci_callback_P4(gpointer data)
    {mci_cb_status[3]++; return mci_CallbackRetValue;}
gboolean (*mci_cbArray[4])(gpointer data) = 
    {mci_callback_P1, mci_callback_P2, mci_callback_P3, mci_callback_P4};



gboolean mci_prepare(GSource    *source, gint       *timeout_)
    {mci_PrepareCount++;*timeout_=mci_Timeout;return mci_PrepareRetValue; }
gboolean mci_check(GSource    *source)
    {mci_CheckCount++;return mci_CheckRetValue;}
gboolean mci_dispatch(GSource    *source, GSourceFunc callback, 
                                gpointer user_data)
    {mci_DispatchCount++;return callback(user_data);}


GSourceFuncs mci_funcs =
{
  mci_prepare,
  mci_check,
  mci_dispatch,
  NULL
};



int mci_status = 0;
GSource* mci_SourceArray[4] = {NULL, NULL, NULL, NULL};




int main()
{
    printf("Glib version %d.%d.%d \n\n", glib_major_version, glib_minor_version,
                    glib_micro_version );

    mci_Timeout = -1;

    mci_status = 0;
    mci_CallbackRetValue = TRUE;
    mci_PrepareRetValue = FALSE;
    mci_CheckRetValue = TRUE;

    GMainContext *mcp_MainContext =  g_main_context_new();


    for(int i = 0; i < 4; ++i)
    {

        GSource *mci_source = (GSource*)g_source_new(&mci_funcs, 
                                                sizeof (GSource));
        mci_SourceArray[i] = mci_source;
        g_source_set_callback (mci_source, mci_cbArray[i], NULL, NULL);
        g_source_set_priority(mci_source, i < 2 ? -1 : i - 1);
        g_source_attach(mci_source, mcp_MainContext);
        g_source_unref(mci_source);
    }

   	g_main_context_pending(mcp_MainContext);

    /*
     * if g_main_context_pending() would not have called here, after the
     * following lines "g_main_context_unref()" would give 2 warning like:
     *
     * --------
     * (process:7320): GLib-WARNING **: gmain.c:1417: ref_count == 0, 
     *                      but source is still attached to a context!
     *
     * (process:7320): GLib-WARNING **: gmain.c:1417: ref_count == 0, 
     *                      but source is still attached to a context!
     * --------
     *
     * which means that reference count for ready sources was increased upon
     * calling "g_main_context_pending()".
     *
     *
     */

    for(int i = 0; i < 2; ++i)
    {
        g_source_unref(mci_SourceArray[i]);
    }

    if(mcp_MainContext)
       g_main_context_unref(mcp_MainContext);


    return 0;
}