/*
 * Java-Gnome Bindings Library
 *
 * Copyright 1998-2004 the Java-Gnome Team, all rights reserved.
 *
 * The Java-Gnome bindings library is free software distributed under
 * the terms of the GNU Library General Public License version 2.
 */

#include <jni.h>
#include <sys/types.h>
#include <gtk/gtk.h>
#include <string.h>

#ifndef _Included_org_gnu_gtk_ActionGroup
#define _Included_org_gnu_gtk_ActionGroup
#ifdef __cplusplus
extern "C" {
#endif


typedef struct {
    JNIEnv *env;
    jobject obj;  /* object to recieve the signal */
    jmethodID methodID;  /* methodID of callback method */
} CallbackInfo;

/*
 * Callback method to handle all signals.
 */
void handleCallback(GtkRadioAction* action, GtkRadioAction* current, gpointer userData) 
{
  	CallbackInfo *cbi = userData;
  	jvalue *jargs = g_new(jvalue, 1);

  	if (userData == NULL) {
    	printf("*** ERROR ***:  Java-GNOME - unable to determine the callback method\n");
    	return;
  	}

  	jargs->i = (jint)action;
    (* cbi->env)->CallVoidMethodA(cbi->env, cbi->obj, cbi->methodID, jargs);
}

/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    gtk_action_group_get_type
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gtk_ActionGroup_gtk_1action_1group_1get_1type
  (JNIEnv *env, jclass cls)
{
	return (jint)gtk_action_group_get_type();
}

/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    gtk_action_group_new
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gtk_ActionGroup_gtk_1action_1group_1new
  (JNIEnv *env, jclass cls, jstring name)
{
	const gchar* n = (*env)->GetStringUTFChars(env, name, NULL);
	jint ret = (jint)gtk_action_group_new(n);
	(*env)->ReleaseStringUTFChars(env, name, n);
	return ret;
}

/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    gtk_action_group_get_name
 * Signature: (I)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_org_gnu_gtk_ActionGroup_gtk_1action_1group_1get_1name
  (JNIEnv *env, jclass cls, jint group)
{
	const gchar* name = gtk_action_group_get_name((GtkActionGroup*)group);
	return (*env)->NewStringUTF(env, name);
}

/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    gtk_action_group_get_sensitive
 * Signature: (I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gtk_ActionGroup_gtk_1action_1group_1get_1sensitive
  (JNIEnv *env, jclass cls, jint group)
{
	return (jboolean)gtk_action_group_get_sensitive((GtkActionGroup*)group);
}
                                                                                
/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    gtk_action_group_set_sensitive
 * Signature: (IZ)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gtk_ActionGroup_gtk_1action_1group_1set_1sensitive
  (JNIEnv *env, jclass cls, jint group, jboolean value)
{
	gtk_action_group_set_sensitive((GtkActionGroup*)group, (gboolean)value);
}
                                                                                
/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    gtk_action_group_get_visible
 * Signature: (I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gtk_ActionGroup_gtk_1action_1group_1get_1visible
  (JNIEnv *env, jclass cls, jint group)
{
	return (jboolean)gtk_action_group_get_visible((GtkActionGroup*)group);
}
                                                                                
/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    gtk_action_group_set_visible
 * Signature: (IZ)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gtk_ActionGroup_gtk_1action_1group_1set_1visible
  (JNIEnv *env, jclass cls, jint group, jboolean value)
{
	gtk_action_group_set_sensitive((GtkActionGroup*)group, (gboolean)value);
}
                                                                                
/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    gtk_action_group_get_action
 * Signature: (ILjava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gtk_ActionGroup_gtk_1action_1group_1get_1action
  (JNIEnv *env, jclass cls, jint group, jstring name)
{
	const gchar* n = (*env)->GetStringUTFChars(env, name, NULL);
	GtkAction* action = gtk_action_group_get_action((GtkActionGroup*)group, n);
	(*env)->ReleaseStringUTFChars(env, name, n);
	if (NULL == action)
		return (jint)-1;
	return (jint)action;
}

/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    gtk_action_group_list_actions
 * Signature: (I)[I
 */
JNIEXPORT jintArray JNICALL Java_org_gnu_gtk_ActionGroup_gtk_1action_1group_1list_1actions
  (JNIEnv *env, jclass cls, jint group)
{
	GList *list = gtk_action_group_list_actions((GtkActionGroup*)group);
	guint len;
	jintArray ar;
	int i = 0;
 	if (NULL == list)
		return NULL;
	 len = g_list_length(list);
	 ar = (*env)->NewIntArray(env, len);
	for (i = 0; i < len; i++) {
		GList *item = g_list_nth(list, i);
		(*env)->SetIntArrayRegion(env, ar, i, 1, (jint*)item->data);
	}
	return ar;
}

/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    gtk_action_group_add_action
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gtk_ActionGroup_gtk_1action_1group_1add_1action
  (JNIEnv *env, jclass cls, jint group, jint action)
{
	gtk_action_group_add_action((GtkActionGroup*)group, (GtkAction*)action);
}

/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    gtk_action_group_remove_action
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gtk_ActionGroup_gtk_1action_1group_1remove_1action
  (JNIEnv *env, jclass cls, jint group, jint action)
{
	gtk_action_group_remove_action((GtkActionGroup*)group, (GtkAction*)action);
}

/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    gtk_action_group_set_translation_domain
 * Signature: (ILjava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gtk_ActionGroup_gtk_1action_1group_1set_1translation_1domain
  (JNIEnv *env, jclass cls, jint group, jstring domain)
{
	const gchar* d = (*env)->GetStringUTFChars(env, domain, NULL);
	gtk_action_group_set_translation_domain((GtkActionGroup*)group, d);
	(*env)->ReleaseStringUTFChars(env, domain, d);
}

/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    gtk_action_group_add_action_with_accel
 * Signature: (IILjava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gtk_ActionGroup_gtk_1action_1group_1add_1action_1with_1accel
  (JNIEnv *env, jclass cls, jint group, jint action, jstring accel)
{
	const gchar* a = (*env)->GetStringUTFChars(env, accel, NULL);
	gtk_action_group_add_action_with_accel((GtkActionGroup*)group, (GtkAction*)action, a);
	(*env)->ReleaseStringUTFChars(env, accel, a);
}
                                                                                
/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    addActions
 * Signature: (I[I[Ljava/lang/Object;)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gtk_ActionGroup_addActions
  (JNIEnv *env, jclass cls, jint group,  jintArray entries, jobjectArray objs)
{
	CallbackInfo *cbData;
  	jthrowable exc;
	jsize len;
	int index;
	jint* ents;

	len = (*env)->GetArrayLength(env, entries);
	ents = (*env)->GetIntArrayElements(env, entries, NULL);
	for (index = 0; index < len; index++) {
		GtkActionEntry* entry = (GtkActionEntry*)ents[index];
		jobject obj = (*env)->GetObjectArrayElement(env, objs, (jsize)index);
		cbData = g_new(CallbackInfo, 1);
		cbData->env = env;
		cbData->obj = (*env)->NewGlobalRef(env, obj);
		cbData->methodID = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, obj),
				"handleCallback", "(I)V");
	 	exc = (*env)->ExceptionOccurred(env);
  		if (exc) {
	   		printf("*** ERROR ***:  Java-GNOME - exception is:\n");
	    	(*env)->ExceptionDescribe(env);
    		(*env)->ExceptionClear(env);
	   		printf("\n** WARNING **:  Java-GNOME - signal will not be mapped\n\n");
	   	 	return;
		}
		gtk_action_group_add_actions((GtkActionGroup*)group, entry, 1, cbData);
	}
}

/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    addToggleActions
 * Signature: (I[I[Ljava/lang/Object;)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gtk_ActionGroup_addToggleActions
  (JNIEnv *env, jclass cls, jint group, jintArray entries, jobjectArray objs)
{
	CallbackInfo *cbData;
  	jthrowable exc;
	jsize len;
	int index;
	jint* ents;

	len = (*env)->GetArrayLength(env, entries);
	ents = (*env)->GetIntArrayElements(env, entries, NULL);
	for (index = 0; index < len; index++) {
		GtkToggleActionEntry* entry = (GtkToggleActionEntry*)ents[index];
		jobject obj = (*env)->GetObjectArrayElement(env, objs, (jsize)index);
		cbData = g_new(CallbackInfo, 1);
		cbData->env = env;
		cbData->obj = (*env)->NewGlobalRef(env, obj);
		cbData->methodID = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, obj),
				"handleCallback", "(I)V");
  		exc = (*env)->ExceptionOccurred(env);
	  	if (exc) {
	    	printf("*** ERROR ***:  Java-GNOME - exception is:\n");
    		(*env)->ExceptionDescribe(env);
    		(*env)->ExceptionClear(env);
	    	printf("\n** WARNING **:  Java-GNOME - signal will not be mapped\n\n");
   		 	return;
	 	}
		gtk_action_group_add_toggle_actions((GtkActionGroup*)group, entry, 1, cbData);
	}
}

/*
 * Class:     org_gnu_gtk_ActionGroup
 * Method:    addRadioActions
 * Signature: (I[IILjava/lang/Object;)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gtk_ActionGroup_addRadioActions
  (JNIEnv *env, jclass cks, jint group, jintArray entries, int value, jobject listener)
{
	CallbackInfo *cbData;
  	jthrowable exc;
	jsize len;
	int index;
	GtkRadioActionEntry* ents;
	GtkRadioActionEntry* ptr;

	len = (*env)->GetArrayLength(env, entries);
	ents = (GtkRadioActionEntry*)g_malloc(sizeof(GtkRadioActionEntry) * len);
	ptr = ents;
	for (index = 0; index < len; index++) {
		jint tmp;
		(*env)->GetIntArrayRegion(env, entries, index, 1, &tmp);
		memcpy(ptr, (GtkRadioActionEntry*)tmp, sizeof(GtkRadioActionEntry));
		ptr++;
	}
	
	cbData = g_malloc(sizeof(CallbackInfo));
	cbData->env = env;
	cbData->obj = listener;
	cbData->methodID = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, listener),
			"handleRadioAction", "(II)V");
  	exc = (*env)->ExceptionOccurred(env);
	if (exc) {
	   	printf("*** ERROR ***:  Java-GNOME - exception is:\n");
    	(*env)->ExceptionDescribe(env);
    	(*env)->ExceptionClear(env);
	   	printf("\n** WARNING **:  Java-GNOME - signal will not be mapped\n\n");
   	 	return;
	}
	gtk_action_group_add_radio_actions((GtkActionGroup*)group, ents, len, (guint)value, G_CALLBACK(handleCallback), (gpointer)cbData);
}


#ifdef __cplusplus
}
#endif
#endif
