/* FAudioGMS - Game Maker FAudio bindings in C
 *
 * Copyright (c) 2021 Evan Hemsley
 *
 * This software is provided 'as-is', without any express or implied warranty.
 * In no event will the authors be held liable for any damages arising from
 * the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 * claim that you wrote the original software. If you use this software in a
 * product, an acknowledgment in the product documentation would be
 * appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and must not be
 * misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source distribution.
 *
 * Evan "cosmonaut" Hemsley <evan@moonside.games>
 *
 */

/* These are the Native -> JNI conv wrappers, they must only be built for Android */
#ifdef __ANDROID__

#include <jni.h>
#include <FAudioGMS.h>

/*
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1Init

JNIEXPORT: export this function for JNI
jdouble: return type, a GameMaker function must always return something
JNICALL: JNI calling convention

Java_class_path_here_classNameHere_Function_Name_Here

classpath: org.screwyoyo.faudiogms
classname: FAudioGMSNative
function name: FAudioGMSNative_FAudioGMS_1Init

underscores must be escaped with _1
*/

/* replace this with -1.0 or NAN if you wish... */
/* ideally, a jdouble should map to a double */
#define NOTHING ((jdouble)0.0)

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1Init
(JNIEnv* jniEnv, jclass jniThis, jdouble _spatialDistanceScale, jdouble _timestep)
{
    FAudioGMS_Init(_spatialDistanceScale, _timestep);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1StaticSound_1LoadWAV
(JNIEnv* jniEnv, jclass jniThis, jstring _filePath)
{
    jboolean isCopy;
    const char* filePath;
    jdouble ret;

    filePath = (*jniEnv)->GetStringUTFChars(jniEnv, _filePath, &isCopy);
    ret = FAudioGMS_StaticSound_LoadWAV((char *)filePath);
    (*jniEnv)->ReleaseStringUTFChars(jniEnv, _filePath, filePath);
    return ret;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1StaticSound_1CreateSoundInstance
(JNIEnv* jniEnv, jclass jniThis, jdouble _staticSoundID)
{
    return (jdouble)FAudioGMS_StaticSound_CreateSoundInstance(_staticSoundID);
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1StaticSound_1Destroy
(JNIEnv* jniEnv, jclass jniThis, jdouble _staticSoundID)
{
    FAudioGMS_StaticSound_Destroy(_staticSoundID);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1StreamingSound_1LoadOGG
(JNIEnv* jniEnv, jclass jniThis, jstring _filepath)
{
    jboolean isCopy;
    const char* filepath;
    jdouble ret;

    filepath = (*jniEnv)->GetStringUTFChars(jniEnv, _filepath, &isCopy);
    ret = FAudioGMS_StreamingSound_LoadOGG((char *)filepath);
    (*jniEnv)->ReleaseStringUTFChars(jniEnv, _filepath, filepath);
    return ret;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1Play
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID, jdouble _loop)
{
    FAudioGMS_SoundInstance_Play(_soundInstanceID, _loop);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1Pause
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID)
{
    FAudioGMS_SoundInstance_Pause(_soundInstanceID);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1Stop
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID)
{
    FAudioGMS_SoundInstance_Stop(_soundInstanceID);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1SetPan
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID, jdouble _pan)
{
    FAudioGMS_SoundInstance_SetPan(_soundInstanceID, _pan);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1SetPitch
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID, jdouble _pitch)
{
    FAudioGMS_SoundInstance_SetPitch(_soundInstanceID, _pitch);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1SetVolume
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID, jdouble _volume)
{
    FAudioGMS_SoundInstance_SetVolume(_soundInstanceID, _volume);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1Set3DPosition
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID, jdouble _x, jdouble _y, jdouble _z)
{
    FAudioGMS_SoundInstance_Set3DPosition(_soundInstanceID, _x, _y, _z);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1Set3DVelocity
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID, jdouble _xVelocity, jdouble _yVelocity, jdouble _zVelocity)
{
    FAudioGMS_SoundInstance_Set3DVelocity(_soundInstanceID, _xVelocity, _yVelocity, _zVelocity);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1SetTrackPositionInSeconds
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID, jdouble _trackPositionInSeconds)
{
    FAudioGMS_SoundInstance_SetTrackPositionInSeconds(_soundInstanceID, _trackPositionInSeconds);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1SetVolumeOverTime
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID, jdouble _volume, jdouble _milliseconds)
{
    FAudioGMS_SoundInstance_SetVolumeOverTime(_soundInstanceID, _volume, _milliseconds);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1SetLowPassFilter
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID, jdouble _lowPassFilter, jdouble _Q)
{
    FAudioGMS_SoundInstance_SetLowPassFilter(_soundInstanceID, _lowPassFilter, _Q);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1SetHighPassFilter
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID, jdouble _highPassFilter, jdouble _Q)
{
    FAudioGMS_SoundInstance_SetHighPassFilter(_soundInstanceID, _highPassFilter, _Q);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1SetBandPassFilter
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID, jdouble _bandPassFilter, jdouble _Q)
{
    FAudioGMS_SoundInstance_SetBandPassFilter(_soundInstanceID, _bandPassFilter, _Q);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1GetPitch
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID)
{
    return (jdouble)FAudioGMS_SoundInstance_GetPitch(_soundInstanceID);
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1GetVolume
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID)
{
    return (jdouble)FAudioGMS_SoundInstance_GetVolume(_soundInstanceID);
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1GetTrackLengthInSeconds
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID)
{
    return (jdouble)FAudioGMS_SoundInstance_GetTrackLengthInSeconds(_soundInstanceID);
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1GetTrackPositionInSeconds
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID)
{
    return (jdouble)FAudioGMS_SoundInstance_GetTrackPositionInSeconds(_soundInstanceID);
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1Destroy
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID)
{
    FAudioGMS_SoundInstance_Destroy(_soundInstanceID);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1DestroyWhenFinished
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID)
{
    FAudioGMS_SoundInstance_DestroyWhenFinished(_soundInstanceID);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1EffectChain_1Create
(JNIEnv* jniEnv, jclass jniThis)
{
    return (jdouble)FAudioGMS_EffectChain_Create();
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1EffectChain_1AddDefaultReverb
(JNIEnv* jniEnv, jclass jniThis, jdouble _effectChainID)
{
    FAudioGMS_EffectChain_AddDefaultReverb(_effectChainID);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1EffectChain_1AddReverb
(JNIEnv* jniEnv, jclass jniThis,
    jdouble _effectChainID,
    jdouble _wetDryMix,
    jdouble _reflectionsDelay,
    jdouble _reverbDelay,
    jdouble _earlyDiffusion,
    jdouble _lateDiffusion,
    jdouble _lowEQGain,
    jdouble _lowEQCutoff,
    jdouble _highEQGain,
    jdouble _highEQCutoff,
    jdouble _reflectionsGain,
    jdouble _reverbGain,
    jdouble _decayTime,
    jdouble _density,
    jdouble _roomSize)
{
    FAudioGMS_EffectChain_AddReverb(
    _effectChainID,
    _wetDryMix,
    _reflectionsDelay,
    _reverbDelay,
    _earlyDiffusion,
    _lateDiffusion,
    _lowEQGain,
    _lowEQCutoff,
    _highEQGain,
    _highEQCutoff,
    _reflectionsGain,
    _reverbGain,
    _decayTime,
    _density,
    _roomSize
    );
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1EffectChain_1Destroy
(JNIEnv* jniEnv, jclass jniThis, jdouble _effectChainID)
{
    FAudioGMS_EffectChain_Destroy(_effectChainID);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1SetEffectChain
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID, jdouble _effectChainID, jdouble _effectGain)
{
    FAudioGMS_SoundInstance_SetEffectChain(_soundInstanceID, _effectChainID, _effectGain);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SoundInstance_1SetEffectGain
(JNIEnv* jniEnv, jclass jniThis, jdouble _soundInstanceID, jdouble _effectGain)
{
    FAudioGMS_SoundInstance_SetEffectGain(_soundInstanceID, _effectGain);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SetListenerPosition
(JNIEnv* jniEnv, jclass jniThis, jdouble _x, jdouble _y, jdouble _z)
{
    FAudioGMS_SetListenerPosition(_x, _y, _z);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1SetListenerVelocity
(JNIEnv* jniEnv, jclass jniThis, jdouble _xVelocity, jdouble _yVelocity, jdouble _zVelocity)
{
    FAudioGMS_SetListenerVelocity(_xVelocity, _yVelocity, _zVelocity);
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1PauseAll
(JNIEnv* jniEnv, jclass jniThis)
{
    FAudioGMS_PauseAll();
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1ResumeAll
(JNIEnv* jniEnv, jclass jniThis)
{
    FAudioGMS_ResumeAll();
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1StopAll
(JNIEnv* jniEnv, jclass jniThis)
{
    FAudioGMS_StopAll();
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1Update
(JNIEnv* jniEnv, jclass jniThis)
{
    FAudioGMS_Update();
    return NOTHING;
}

JNIEXPORT jdouble JNICALL
Java_org_screwyoyo_faudiogms_FAudioGMSNative_FAudioGMS_1Destroy
(JNIEnv* jniEnv, jclass jniThis)
{
    FAudioGMS_Destroy();
    return NOTHING;
}

#endif /* __ANDROID__ */

/* Do nothing for other platforms, because they, thankly, do not require JNI bindings... */
