#include "com_millistream_www_Message.h"
#include "mdf-java.h"

/* called when the Mdf class is loaded so that we can cache the fid of the "handle" member */
JNIEXPORT void JNICALL Java_com_millistream_www_Message_initialize (JNIEnv *env, jclass cls)
{
	message_fid = (*env)->GetFieldID(env, cls, "handle", "J");
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_create(JNIEnv *env, jobject job)
{
	mdf_message_t handle = mdf_message_create();

	if (handle == 0)
		return JNI_FALSE;

	(*env)->SetLongField(env, job, message_fid, (jlong) handle);
	return JNI_TRUE;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_setCompressionLevel (JNIEnv *env, jobject job, jint level)
{
	if (mdf_message_set_property ((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), MDF_MSG_OPT_COMPRESSION, level) == 1)
		return JNI_TRUE;

	return JNI_FALSE;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_setUTF8Validation (JNIEnv *env, jobject job, jint value)
{
	if (mdf_message_set_property ((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), MDF_MSG_OPT_UTF8, value) == 1)
		return JNI_TRUE;

	return JNI_FALSE;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_setDelay (JNIEnv *env, jobject job, jint value)
{
	if (mdf_message_set_property ((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), MDF_MSG_OPT_DELAY, value) == 1)
		return JNI_TRUE;

	return JNI_FALSE;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_add(JNIEnv *env, jobject job, jlong instrument_reference, jint message_reference)
{
	if (mdf_message_add((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), instrument_reference, message_reference) == 1)
		return JNI_TRUE;

	return JNI_FALSE;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_addWithDelayInfo(JNIEnv *env, jobject job, jlong instrument_reference, jint message_reference, jint delay)
{
	if (mdf_message_add2((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), instrument_reference, message_reference, delay) == 1)
		return JNI_TRUE;

	return JNI_FALSE;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_del(JNIEnv *env, jobject job)
{
	if (mdf_message_del((mdf_message_t)((*env)->GetLongField (env, job, message_fid))) == 1)
		return JNI_TRUE;

	return JNI_FALSE;
}

JNIEXPORT void JNICALL Java_com_millistream_www_Message_reset(JNIEnv *env, jobject job)
{
	mdf_message_reset((mdf_message_t)((*env)->GetLongField (env, job, message_fid)));
}

JNIEXPORT void JNICALL Java_com_millistream_www_Message_destroy(JNIEnv *env, jobject job)
{
	mdf_message_t message = (mdf_message_t)((*env)->GetLongField (env, job, message_fid));

	if (message == NULL)
		return;

	mdf_message_destroy(message);
	(*env)->SetLongField(env, job, message_fid, 0);
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_add_1list( JNIEnv *env, jobject job, jint tag, jstring value)
{
	const char *str = (*env)->GetStringUTFChars(env, value, NULL);

	if (str == NULL)
		return JNI_FALSE; /* OutOfMemoryError already thrown */

	jboolean rc = JNI_TRUE;

	if (mdf_message_add_list((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), tag, str) == 0)
		rc = JNI_FALSE;

	(*env)->ReleaseStringUTFChars(env, value, str);
	return rc;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_add_1numeric(JNIEnv *env, jobject job, jint tag, jstring value)
{
	const char *str = (*env)->GetStringUTFChars(env, value, NULL);

	if (str == NULL)
		return JNI_FALSE; /* OutOfMemoryError already thrown */

	jboolean rc = JNI_TRUE;

	if (mdf_message_add_numeric((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), tag, str) == 0)
		rc = JNI_FALSE;

	(*env)->ReleaseStringUTFChars(env, value, str);
	return rc;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_add_1long (JNIEnv *env, jobject job, jint tag, jlong value, jint decimals)
{
	if (mdf_message_add_int ((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), tag, value, decimals) == 1)
		return JNI_TRUE;

	return JNI_FALSE;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_add_1string(JNIEnv *env, jobject job, jint tag, jstring value)
{
	const char *str = (*env)->GetStringUTFChars(env, value, NULL);

	if (str == NULL)
		return JNI_FALSE; /* OutOfMemoryError already thrown */

	jboolean rc = JNI_TRUE;

	if (mdf_message_add_string((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), tag, str) == 0)
		rc = JNI_FALSE;

	(*env)->ReleaseStringUTFChars(env, value, str);
	return rc;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_add_1date(JNIEnv *env, jobject job, jint tag, jstring value)
{
	const char *str = (*env)->GetStringUTFChars(env, value, NULL);

	if (str == NULL)
		return JNI_FALSE; /* OutOfMemoryError already thrown */

	jboolean rc = JNI_TRUE;

	if (mdf_message_add_date((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), tag, str) == 0)
		rc = JNI_FALSE;

	(*env)->ReleaseStringUTFChars(env, value, str);
	return rc;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_add_1date2 (JNIEnv *env, jobject job, jint tag, jint year, jint mon, jint day)
{
	if (mdf_message_add_date2 ((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), tag, year, mon, day) == 1)
		return JNI_TRUE;

	return JNI_FALSE;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_add_1time(JNIEnv *env, jobject job, jint tag, jstring value)
{
	const char *str = (*env)->GetStringUTFChars(env, value, NULL);

	if (str == NULL)
		return JNI_FALSE; /* OutOfMemoryError already thrown */

	jboolean rc = JNI_TRUE;

	if (mdf_message_add_time((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), tag, str) == 0)
		rc = JNI_FALSE;

	(*env)->ReleaseStringUTFChars(env, value, str);
	return rc;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_add_1time2 (JNIEnv *env, jobject job, jint tag, jint hour, jint min, jint sec, jint msec)
{
	if (mdf_message_add_time2 ((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), tag, hour, min, sec, msec) == 1)
		return JNI_TRUE;

	return JNI_FALSE;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_add_1time3 (JNIEnv *env, jobject job, jint tag, jint hour, jint min, jint sec, jint nsec)
{
	if (mdf_message_add_time3 ((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), tag, hour, min, sec, nsec) == 1)
		return JNI_TRUE;

	return JNI_FALSE;
}

JNIEXPORT jint JNICALL Java_com_millistream_www_Message_get_1num(JNIEnv *env, jobject job)
{
	return mdf_message_get_num((mdf_message_t)((*env)->GetLongField (env, job, message_fid)));
}

JNIEXPORT jint JNICALL Java_com_millistream_www_Message_get_1num_1active(JNIEnv *env, jobject job)
{
	return mdf_message_get_num_active((mdf_message_t)((*env)->GetLongField (env, job, message_fid)));
}

JNIEXPORT jstring JNICALL Java_com_millistream_www_Message_toString (JNIEnv *env, jobject job)
{
	char *result;

	if (mdf_message_serialize ((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), &result) == 0)
		return NULL;

	jstring jstr = (*env)->NewStringUTF(env, result);
	free (result);

	return jstr;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_deserialize (JNIEnv *env, jobject job, jstring in_str)
{
	if (in_str == NULL)
		return JNI_FALSE;

	const char *str = (*env)->GetStringUTFChars(env, in_str, NULL);

	if (str == NULL)
		return JNI_FALSE; /* OutOfMemoryError already thrown */

	jboolean rc = JNI_TRUE;

	if (mdf_message_deserialize((mdf_message_t)((*env)->GetLongField (env, job, message_fid)), str) == 0)
		rc = JNI_FALSE;

	(*env)->ReleaseStringUTFChars(env, in_str, str);
	return rc;
}

JNIEXPORT jboolean JNICALL Java_com_millistream_www_Message_move (JNIEnv *env, jobject msg, jobject dst, jlong insrefFrom, jlong insrefTo)
{
	mdf_message_t message_src = (mdf_message_t)((*env)->GetLongField (env, msg, message_fid));
	mdf_message_t message_dst = dst == NULL ? NULL : (mdf_message_t)((*env)->GetLongField (env, dst, message_fid));

	if (mdf_message_move(message_src, message_dst, insrefFrom, insrefTo) == 0)
		return JNI_FALSE;

	return JNI_TRUE;
}

