/*
 * WriteOpts.c
 *
 * Copyright (c) 2007  Vreixo Formoso
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * See COPYING file for details.
 */

#include "org_pykix_libburnia_libburn_WriteOpts.h"
#include "BindingsUtil.h"

#include "libburn.h"


/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_free
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1free
(
	JNIEnv *env, jclass cls, jlong opts
)
{
	burn_write_opts_free( (struct burn_write_opts *) opts);
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_set_write_type
 * Signature: (JII)Z
 */
JNIEXPORT jboolean JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1set_1write_1type
(
	JNIEnv *env, jclass cls, jlong opts, jint write_type, jint block_type
)
{
	return burn_write_opts_set_write_type( (struct burn_write_opts *) opts,
		write_type, block_type);
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_auto_write_type
 * Signature: (JJI)I
 */
JNIEXPORT jint JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1auto_1write_1type
(
	JNIEnv *env, jclass cls, jlong opts, jlong disc, jint flag
)
{
	char reasons[BURN_REASONS_LEN];

	return burn_write_opts_auto_write_type( (struct burn_write_opts *) opts, 
		(struct burn_disc *) disc, reasons, flag);
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_set_simulate
 * Signature: (JZ)Z
 */
JNIEXPORT jboolean JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1set_1simulate
(
	JNIEnv *env, jclass cls, jlong opts, jboolean sim
)
{
	return burn_write_opts_set_simulate( (struct burn_write_opts *) opts, sim);
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_set_underrun_proof
 * Signature: (JZ)Z
 */
JNIEXPORT jboolean JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1set_1underrun_1proof
(
	JNIEnv *env, jclass cls, jlong opts, jboolean underrun_proof
)
{
	return burn_write_opts_set_underrun_proof( (struct burn_write_opts *) opts, underrun_proof);
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_set_perform_opc
 * Signature: (JZ)V
 */
JNIEXPORT void JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1set_1perform_1opc
(
	JNIEnv *env, jclass cls, jlong opts, jboolean opc
)
{
	burn_write_opts_set_perform_opc( (struct burn_write_opts *) opts, opc);
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_set_multi
 * Signature: (JZ)V
 */
JNIEXPORT void JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1set_1multi
(
	JNIEnv *env, jclass cls, jlong opts, jboolean multi
)
{
	burn_write_opts_set_multi( (struct burn_write_opts *) opts, multi);
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_set_force
 * Signature: (JI)V
 */
JNIEXPORT void JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1set_1force
(
	JNIEnv *env, jclass cls, jlong opts, jint use_force
)
{
	burn_write_opts_set_force( (struct burn_write_opts *) opts, use_force);
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_set_start_byte
 * Signature: (JJ)V
 */
JNIEXPORT void JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1set_1start_1byte
(
	JNIEnv *env, jclass cls, jlong opts, jlong value
)
{
	burn_write_opts_set_start_byte( (struct burn_write_opts *) opts, value);
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_set_format
 * Signature: (JI)V
 */
JNIEXPORT void JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1set_1format
(
	JNIEnv *env, jclass cls, jlong opts, jint format
)
{
	burn_write_opts_set_format( (struct burn_write_opts *) opts, format);
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_set_has_mediacatalog
 * Signature: (JZ)V
 */
JNIEXPORT void JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1set_1has_1mediacatalog
(
	JNIEnv *env, jclass cls, jlong opts, jboolean has_mediacatalog
)
{
	burn_write_opts_set_has_mediacatalog( (struct burn_write_opts *)opts, has_mediacatalog);
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_set_mediacatalog
 * Signature: (JLjava/lang/String;)V
 */
JNIEXPORT void JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1set_1mediacatalog
(
	JNIEnv *env, jclass cls, jlong opts, jstring mediaCatalog
)
{
	const char *mediacatalog;

	mediacatalog = (*env)->GetStringUTFChars(env, mediaCatalog, NULL);
	if ( mediacatalog == NULL ) {
		return; /* OutOfMemoryError already thrown */
	}
	
	burn_write_opts_set_mediacatalog( (struct burn_write_opts *) opts, (unsigned char*) mediacatalog);

	(*env)->ReleaseStringUTFChars(env, mediaCatalog, mediacatalog);
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_precheck_write
 * Signature: (JJI)V
 */
JNIEXPORT void JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1precheck_1write
(
	JNIEnv *env, jclass cls, jlong o, jlong disc, jint silent
)
{
	char reasons[BURN_REASONS_LEN];

	if ( burn_precheck_write( (struct burn_write_opts *) o, (struct burn_disc *) disc,
                        reasons, silent) != 1 ) {
		
		java_libburn_throw_burn_exception(env, reasons);
	}
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_set_fillup
 * Signature: (JZ)V
 */
JNIEXPORT void JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1set_1fillup
(
	JNIEnv *env, jclass cls, jlong o, jboolean fill_up
)
{
	burn_write_opts_set_fillup( (struct burn_write_opts *) o, fill_up);
}

/*
 * Class:     org_pykix_libburnia_libburn_WriteOpts
 * Method:    burn_write_opts_set_toc_entries
 * Signature: (JI[Lorg/pykix/libburnia/libburn/TocEntry;)V
 */
JNIEXPORT void JNICALL 
Java_org_pykix_libburnia_libburn_WriteOpts_burn_1write_1opts_1set_1toc_1entries
(
	JNIEnv *env, jclass cls, jlong o, jint count, jobjectArray ents
)
{
	struct burn_toc_entry entries[count];
	static jclass tocEntryCls = NULL;
	static jfieldID sessionid, adrid, controlid, pointid, minid, secid,
		frameid, zeroid, pminid, psecid, pframeid, extvid, smsbid, pmsbid, 
		slbaid, blocksid;
	int i;

	if ( tocEntryCls == NULL ) {
		tocEntryCls = java_libburn_find_class(env, "org/pykix/libburnia/libburn/TocEntry");
		if ( tocEntryCls == NULL ) {
			return;
		}

		/* TODO: check for NULL?? */
		sessionid = (*env)->GetFieldID(env, cls, "session", "B");
		adrid = (*env)->GetFieldID(env, cls, "adr", "B");
		controlid = (*env)->GetFieldID(env, cls, "control", "B");
		pointid = (*env)->GetFieldID(env, cls, "point", "B");
		minid = (*env)->GetFieldID(env, cls, "min", "B");
		secid = (*env)->GetFieldID(env, cls, "sec", "B");
		frameid = (*env)->GetFieldID(env, cls, "frame", "B");
		zeroid = (*env)->GetFieldID(env, cls, "zero", "B");
		pminid = (*env)->GetFieldID(env, cls, "pmin", "B");
		psecid = (*env)->GetFieldID(env, cls, "psec", "B");
		pframeid = (*env)->GetFieldID(env, cls, "pframe", "B");
		extvid = (*env)->GetFieldID(env, cls, "extensionsValid", "B");
		smsbid = (*env)->GetFieldID(env, cls, "sessionMsb", "B");
		pmsbid = (*env)->GetFieldID(env, cls, "pointMsb", "B");
		slbaid = (*env)->GetFieldID(env, cls, "startLba", "I");
		blocksid = (*env)->GetFieldID(env, cls, "trackBlocks", "I");
	}

	for ( i = 0; i < count; ++i ) {
	
		struct burn_toc_entry entry = entries[i];
		jobject obj = (*env)->GetObjectArrayElement(env, ents, i);

		entry.session = (*env)->GetByteField(env, obj, sessionid);
		entry.adr = (*env)->GetByteField(env, obj, adrid);
		entry.control = (*env)->GetByteField(env, obj, controlid);
		entry.tno = 0; //tno is always 0
		entry.point = (*env)->GetByteField(env, obj, pointid);
		entry.min = (*env)->GetByteField(env, obj, minid);
		entry.sec = (*env)->GetByteField(env, obj, secid);
		entry.frame = (*env)->GetByteField(env, obj, frameid);
		entry.zero = (*env)->GetByteField(env, obj, zeroid);
		entry.pmin = (*env)->GetByteField(env, obj, pminid);
		entry.psec = (*env)->GetByteField(env, obj, psecid);
		entry.pframe = (*env)->GetByteField(env, obj, pframeid);
		entry.extensions_valid = (*env)->GetByteField(env, obj, extvid);  
		entry.session_msb = (*env)->GetByteField(env, obj, smsbid);
		entry.point_msb = (*env)->GetByteField(env, obj, pmsbid);
		entry.start_lba = (*env)->GetIntField(env, obj, slbaid); 
		entry.track_blocks = (*env)->GetIntField(env, obj, blocksid);
	}

	burn_write_opts_set_toc_entries( (struct burn_write_opts *) o,
				     count, entries);

}

