#include <jni.h>
#include <string>
#include <Superpowered.h>
#include <SuperpoweredAdvancedAudioPlayer.h>
#include "MultiTracksPlayer.h"

MultiTracksPlayer *multiTracksPlayer = nullptr;

extern "C"
JNIEXPORT void JNICALL
Java_com_reactnativesuperpoweredklaas_SuperpoweredKlaasModule_setup(
        JNIEnv __unused *env,
        jobject __unused thiz,
        jstring license_key,
        jboolean enable_audio_analysis,
        jboolean enable_fftand_frequency_domain,
        jboolean enable_audio_time_stretching,
        jboolean enable_audio_effects,
        jboolean enable_audio_player_and_decoder,
        jboolean enable_cryptographics,
        jboolean enable_networking
) {
    const char *license_key_char = env->GetStringUTFChars(license_key, 0);
    Superpowered::Initialize(
            license_key_char,
            static_cast<bool>(enable_audio_analysis),
            static_cast<bool>(enable_fftand_frequency_domain),
            static_cast<bool>(enable_audio_time_stretching),
            static_cast<bool>(enable_audio_effects),
            static_cast<bool>(enable_audio_player_and_decoder),
            static_cast<bool>(enable_cryptographics),
            static_cast<bool>(enable_networking)
    );
    env->ReleaseStringUTFChars(license_key, license_key_char);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_reactnativesuperpoweredklaas_SuperpoweredKlaasModule_multiTracksPlayer(
        JNIEnv *env,
        jobject __unused thiz,
        jobjectArray tracks_paths,
        jint tracks_amount,
        jint sample_rate,
        jint buffer_size,
        jstring temp_dir
) {
    const char *path = env->GetStringUTFChars(temp_dir, JNI_FALSE);
    Superpowered::AdvancedAudioPlayer::setTempFolder(path);
    env->ReleaseStringUTFChars(temp_dir, path);

    const char *tracksPathRaw[tracks_amount];
    for (int i = 0; i < tracks_amount; i++) {
        auto tracksPath = (jstring) (env->GetObjectArrayElement(tracks_paths, i));
        tracksPathRaw[i] = env->GetStringUTFChars(tracksPath, JNI_FALSE);
    }

    multiTracksPlayer = new MultiTracksPlayer(
            tracksPathRaw,
            tracks_amount,
            sample_rate,
            buffer_size
    );

    for (int i = 0; i < tracks_amount; i++) {
        auto tracksPath = (jstring) (env->GetObjectArrayElement(tracks_paths, 0));
        env->ReleaseStringUTFChars(tracksPath, tracksPathRaw[i]);
    }
}

extern "C"
JNIEXPORT void JNICALL
Java_com_reactnativesuperpoweredklaas_SuperpoweredKlaasModule_destroy(
        JNIEnv __unused *env,
        jobject __unused thiz
) {
    delete multiTracksPlayer;
}

extern "C"
JNIEXPORT void JNICALL
Java_com_reactnativesuperpoweredklaas_SuperpoweredKlaasModule_pause(
        JNIEnv __unused *env,
        jobject __unused thiz
) {
    multiTracksPlayer->pause();
}

extern "C"
JNIEXPORT double JNICALL
Java_com_reactnativesuperpoweredklaas_SuperpoweredKlaasModule_play(
        JNIEnv __unused *env,
        jobject __unused thiz
) {
    return multiTracksPlayer->play();
}

extern "C"
JNIEXPORT void JNICALL
Java_com_reactnativesuperpoweredklaas_SuperpoweredKlaasModule_setPosition(
        JNIEnv __unused *env,
        jobject __unused thiz,
        jdouble second,
        jboolean and_stop
) {
    multiTracksPlayer->setPosition(second, and_stop);
}

extern "C"
JNIEXPORT jdouble JNICALL
Java_com_reactnativesuperpoweredklaas_SuperpoweredKlaasModule_getBufferedEndPercent(
        JNIEnv __unused *env,
        jobject __unused thiz,
        jint index) {
    return multiTracksPlayer->getBufferedEndPercent(index);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_reactnativesuperpoweredklaas_SuperpoweredKlaasModule_setVolume(
        JNIEnv __unused *env,
        jobject __unused thiz,
        jint index,
        jfloat left,
        jfloat right
) {
    multiTracksPlayer->setVolume(index, left, right);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_reactnativesuperpoweredklaas_SuperpoweredKlaasModule_setRate(
        JNIEnv __unused *env,
        jobject __unused thiz,
        jfloat rate
) {
    multiTracksPlayer->setRate(rate);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_reactnativesuperpoweredklaas_SuperpoweredKlaasModule_setPitchShiftCents(
        JNIEnv __unused *env,
        jobject __unused thiz,
        jint pitch_shift_cents
) {
    multiTracksPlayer->setPitchShiftCents(pitch_shift_cents);
}

extern "C"
JNIEXPORT jint JNICALL
Java_com_reactnativesuperpoweredklaas_SuperpoweredKlaasModule_getDisplayPosition(
        JNIEnv __unused *env,
        jobject __unused thiz
) {
    return multiTracksPlayer->getDisplayPosition();
}
