#include <com_sun_glass_ui_gtk_GtkTimer.h>
#include "glass_general.h"

#include <glib.h>
#include <gdk/gdk.h>
#include <stdlib.h>

static gboolean call_runnable_in_timer
  (gpointer);
/*
 * Class:     com_sun_glass_ui_gtk_GtkTimer
 * Method:    _start
 * Signature: (Ljava/lang/Runnable;I)J
 */
JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_gtk_GtkTimer__1start
  (JNIEnv * env, jobject obj, jobject runnable, jint period)
{
    RunnableContext* context = malloc(sizeof(RunnableContext));
    context->runnable = (*env)->NewGlobalRef(env, runnable);
    context->flag = 0;
    gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE, period, call_runnable_in_timer, context, NULL);
    return PTR_TO_JLONG(context);
}

/*
 * Class:     com_sun_glass_ui_gtk_GtkTimer
 * Method:    _stop
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_com_sun_glass_ui_gtk_GtkTimer__1stop
  (JNIEnv * env, jobject obj, jlong ptr)
{
    RunnableContext* context = JLONG_TO_PTR(ptr);
    context->flag = 1;
    (*env)->DeleteGlobalRef(env, context->runnable);
    context->runnable = NULL;
}


static gboolean call_runnable_in_timer
  (gpointer data)
{
    RunnableContext* context = data;
    if (context->flag) {
        free(context);
        return FALSE;
    }
    else if (context->runnable) {
        (*mainEnv)->CallVoidMethod(mainEnv, context->runnable, jRunnableRun, NULL);
        LOG_EXCEPTION(mainEnv);
        (*mainEnv)->ExceptionClear(mainEnv);
    }
    return TRUE;
}
