/*
 * Java-Gnome Bindings Library
 *
 * Copyright 1998-2002 the Java-Gnome Team, all rights reserved.
 *
 * The Java-Gnome Team Members:
 *   Jean Van Wyk <jeanvanwyk@iname.com>
 *   Jeffrey S. Morgan <jeffrey.morgan@bristolwest.com>
 *   Dan Bornstein <danfuzz@milk.com>
 *
 * 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 <gconf/gconf.h>

#ifndef _Included_org_gnu_gconf_ConfValue
#define _Included_org_gnu_gconf_ConfValue
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_new
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1new
  (JNIEnv *env, jclass cls, jint type)
{
	return (jint)gconf_value_new((GConfValueType) type);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_copy
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1copy
  (JNIEnv *env, jclass cls, jint value)
{
	return (jint)gconf_value_copy((GConfValue*)value);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_free
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1free
  (JNIEnv *env, jclass cls, jint value)
{
	gconf_value_free((GConfValue*)value);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_get_string
 * Signature: (I)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1get_1string
  (JNIEnv *env, jclass cls, jint value)
{
	gchar* result = (gchar*)gconf_value_get_string((GConfValue*)value);
	return (*env)->NewStringUTF(env, result);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_get_int
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1get_1int
  (JNIEnv *env, jclass cls, jint value)
{
	return (jint)gconf_value_get_int((GConfValue*)value);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_get_float
 * Signature: (I)D
 */
JNIEXPORT jdouble JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1get_1float
  (JNIEnv *env, jclass cls, jint value)
{
	return (jdouble)gconf_value_get_float((GConfValue*)value);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_get_list_type
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1get_1list_1type
  (JNIEnv *env, jclass cls, jint value)
{
	return (jint)gconf_value_get_list_type((GConfValue*)value);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_get_list
 * Signature: (I)[Ljava/lang/Object;
 */
JNIEXPORT jobjectArray JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1get_1list
  (JNIEnv *env, jclass cls, jint value)
{
	GSList* list = gconf_value_get_list((GConfValue*)value);
	int i = 0;
	jclass aCls = NULL;
	guint len;
	jobjectArray ar;
	len = g_slist_length(list);
	GConfValueType vt = gconf_value_get_list_type((GConfValue*)value);
	if (vt == GCONF_VALUE_STRING)
		aCls = (*env)->FindClass(env, "java/lang/String");
	else if (vt == GCONF_VALUE_INT)
		aCls = (*env)->FindClass(env, "java/lang/Integer");
	else if (vt == GCONF_VALUE_FLOAT)
		aCls = (*env)->FindClass(env, "java/lang/Double");
	else if (vt == GCONF_VALUE_BOOL)
		aCls = (*env)->FindClass(env, "java/lang/Boolean");
	else if (vt == GCONF_VALUE_SCHEMA)
		aCls = (*env)->FindClass(env, "org/gnu/gconf/ConfSchema");
	if (NULL == aCls)
		return NULL;
	ar = (*env)->NewObjectArray(env, len, aCls, NULL);
	for (i = 0; i < len; i++) {
		GSList *item = g_slist_nth(list, i);
		if (vt == GCONF_VALUE_STRING) {
			jstring str = (*env)->NewStringUTF(env, item->data);
			(*env)->SetObjectArrayElement(env, ar, i, str);
		} else if (vt == GCONF_VALUE_INT) {
			jmethodID mid = (*env)->GetMethodID(env, aCls, "<init>", "(I)V");
			jobject obj;
			if (mid == NULL)
				return NULL;
			obj = (*env)->NewObject(env, aCls, mid, (jint)item->data);
			(*env)->SetObjectArrayElement(env, ar, i, obj);
		} else if (vt == GCONF_VALUE_FLOAT) {
			jmethodID mid = (*env)->GetMethodID(env, aCls, "<init>", "(D)V");
			jobject obj;
			if (mid == NULL)
				return NULL;
			obj = (*env)->NewObject(env, aCls, mid, (jdouble*)item->data);
			(*env)->SetObjectArrayElement(env, ar, i, obj);
		} else if (vt == GCONF_VALUE_BOOL) {
			jmethodID mid = (*env)->GetMethodID(env, aCls, "<init>", "(Z)V");
			jobject obj;
			if (mid == NULL)
				return NULL;
			obj = (*env)->NewObject(env, aCls, mid, (jboolean)((gboolean)item->data));
			(*env)->SetObjectArrayElement(env, ar, i, obj);
		} else if (vt == GCONF_VALUE_SCHEMA) {
			jmethodID mid = (*env)->GetMethodID(env, aCls, "<init>", "(I)V");
			jobject obj;
			if (mid == NULL)
				return NULL;
			obj = (*env)->NewObject(env, aCls, mid, (jint)item->data);
			(*env)->SetObjectArrayElement(env, ar, i, obj);
		}
	}
	return ar;
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_get_car
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1get_1car
  (JNIEnv *env, jclass cls, jint value)
{
	return (jint)gconf_value_get_car((GConfValue*)value);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_get_cdr
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1get_1cdr
  (JNIEnv *env, jclass cls, jint value)
{
	return (jint)gconf_value_get_cdr((GConfValue*)value);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_get_bool
 * Signature: (I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1get_1bool
  (JNIEnv *env, jclass cls, jint value)
{
	return (jboolean)gconf_value_get_bool((GConfValue*)value);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_get_schema
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1get_1schema
  (JNIEnv *env, jclass cls, jint value)
{
	return (jint)gconf_value_get_schema((GConfValue*)value);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_set_int
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1set_1int
  (JNIEnv *env, jclass cls, jint value, jint theInt)
{
	gconf_value_set_int((GConfValue*)value, (int)theInt);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_set_string
 * Signature: (ILjava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1set_1string
  (JNIEnv *env, jclass cls, jint value, jstring theString)
{
	const gchar* str = (*env)->GetStringUTFChars(env, theString, NULL);
	gconf_value_set_string((GConfValue*)value, str);
	(*env)->ReleaseStringUTFChars(env, theString, str);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_set_bool
 * Signature: (IZ)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1set_1bool
  (JNIEnv *env, jclass cls, jint value, jboolean theBool)
{
	gconf_value_set_bool((GConfValue*)value, (gboolean)theBool);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_set_float
 * Signature: (ID)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1set_1float
  (JNIEnv *env, jclass cls, jint value, jdouble theDouble)
{
	gconf_value_set_float((GConfValue*)value, (gdouble)theDouble);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_set_schema
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1set_1schema
  (JNIEnv *env, jclass cls, jint value, jint schema)
{
	gconf_value_set_schema((GConfValue*)value, (GConfSchema*)schema);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_set_car
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1set_1car
  (JNIEnv *env, jclass cls, jint value, jint car)
{
	gconf_value_set_car((GConfValue*)value, (GConfValue*)car);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_set_cdr
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1set_1cdr
  (JNIEnv *env, jclass cls, jint value, jint cdr)
{
	gconf_value_set_cdr((GConfValue*)value, (GConfValue*)cdr);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_set_list_type
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1set_1list_1type
  (JNIEnv *env, jclass cls, jint value, jint type)
{
	gconf_value_set_list_type((GConfValue*)value, (GConfValueType)type);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_set_list
 * Signature: (I[Ljava/lang/Object;)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1set_1list
  (JNIEnv *env, jclass cls, jint value, jobjectArray list)
{
	GConfValueType vt = gconf_value_get_list_type((GConfValue*)value);
	int i = 0;
	jclass aCls = NULL;
	jobject obj;
	jfieldID fid;
	jmethodID mid;
	jsize len;
	GSList* gslist;
	gpointer data = NULL;
	
	len = (*env)->GetArrayLength(env, list);
	gslist = g_slist_alloc();
	for (i = 0; i < len; i++) {
		obj = (*env)->GetObjectArrayElement(env, list, i);
		if (vt == GCONF_VALUE_STRING) {
			jstring value = (jstring)obj;
			const gchar* v = (*env)->GetStringUTFChars(env, value, NULL);
			data = (gpointer)v;
		}
		else if (vt == GCONF_VALUE_INT) {
			jint value;
			aCls = (*env)->FindClass(env, "java/lang/Integer");
			mid = (*env)->GetMethodID(env, cls, "intValue", "()I");
			if (NULL == mid)
				return;
			value = (*env)->CallIntMethod(env, obj, mid);
			data = (gpointer)&value;
		}
		else if (vt == GCONF_VALUE_FLOAT) {
			jdouble value;
			aCls = (*env)->FindClass(env, "java/lang/Double");
			mid = (*env)->GetMethodID(env, cls, "doubleValue", "()D");
			if (NULL == mid)
				return;
			value = (*env)->CallDoubleMethod(env, obj, mid);
			data = (gpointer)&value;
		}
		else if (vt == GCONF_VALUE_BOOL) {
			jboolean value;
			aCls = (*env)->FindClass(env, "java/lang/Boolean");
			mid = (*env)->GetMethodID(env, cls, "booleanValue", "()Z");
			if (NULL == mid)
				return;
			value = (*env)->CallBooleanMethod(env, obj, mid);
			data = (gpointer)&value;
		}
		else if (vt == GCONF_VALUE_SCHEMA) {
			jint value;
			aCls = (*env)->FindClass(env, "org/gnu/gconf/ConfSchema");
			fid = (*env)->GetFieldID(env, aCls, "handle", "I");
			if (fid == NULL)
				return;
			value = (jint)(*env)->GetObjectField(env, obj, fid);
			data = (gpointer)value;
		}
		gslist = g_slist_append(gslist, data);
	}
	gconf_value_set_list((GConfValue*)value, gslist);
}

/*
 * Class:     org_gnu_gconf_ConfValue
 * Method:    gconf_value_to_string
 * Signature: (I)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_org_gnu_gconf_ConfValue_gconf_1value_1to_1string
  (JNIEnv *env, jclass cls, jint value)
{
	gchar *str = gconf_value_to_string((GConfValue*)value);
	return (*env)->NewStringUTF(env, str);
}

#ifdef __cplusplus
}
#endif
#endif
