/*
    Tucnak - VHF contest log
    Copyright (C) 2012-2023 Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/

#include "header.h"

#include "edi.h"
#include "main.h"
#include "state.h"
#include "tsdl.h"

#include <jni.h>
#include <android/log.h>

int android_main(int argc, char *argv[]){
	GString *gs;
	SDL_version sdl_compiled;

	gs = g_string_new("------ Settings: --------\n");
	g_string_sprintfa(gs, "   version: %s-%s %s\n", PACKAGE, Z_PLATFORM, VERSION);
	g_string_sprintfa(gs, "  compiler: gcc %d.%d.%d\n", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
	g_string_sprintfa(gs, "     sizes: int=%d, long=%d, long long=%d, void*=%d\n", (int)sizeof(int), (int)sizeof(long), (int)sizeof(long long), (int)sizeof(void *));
	g_string_sprintfa(gs, "  libglib2: yes %d.%d.%d\n", glib_major_version, glib_minor_version, glib_micro_version);  
	SDL_VERSION(&sdl_compiled);
	g_string_sprintfa(gs, "    libsdl: yes %d.%d.%d\n", sdl_compiled.major, sdl_compiled.minor, sdl_compiled.patch);
#ifdef Z_HAVE_LIBPNG
	g_string_sprintfa(gs, "    libpng: yes ");
	zpng_get_version(gs);
	g_string_append(gs, "\n");
#else
	g_string_sprintfa(gs, "    libpng: no\n");
#endif
	g_string_sprintfa(gs, "     iconv: %d.%d\n", _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 0xff);
	g_string_sprintfa(gs, "    libgpm: no \n");
#ifdef HAVE_SNDFILE
	g_string_sprintfa(gs, "libsndfile: yes %s\n", sf_version_string());
#else
	g_string_sprintfa(gs, "libsndfile: no\n");
#endif
	g_string_sprintfa(gs, "      alsa: no\n");
#ifdef Z_HAVE_LIBFTDI
	g_string_sprintfa(gs, "   libftdi: yes 0.19\n");
#else
	g_string_sprintfa(gs, "   libftdi: no\n");
#endif
#ifdef HAVE_HAMLIB
	g_string_sprintfa(gs, " libhamlib: yes %s\n", hamlib_version);   
#else
	g_string_sprintfa(gs, " libhamlib: no\n");
#endif
#ifdef USE_FFT
	g_string_sprintfa(gs, "  libfftw3: yes\n");
//	g_string_sprintfa(gs, "  libfftw3: yes %s\n", fftw_version);
#else
	g_string_sprintfa(gs, "  libfftw3: no\n");
#endif
#ifdef HAVE_PORTAUDIO
	g_string_sprintfa(gs, " portaudio: yes %d.%02d\n", Pa_GetVersion() / 100, Pa_GetVersion() % 100);
#else
	g_string_sprintfa(gs, " portaudio: no\n");
#endif
	g_string_sprintfa(gs, "    inpout: yes\n");
	g_string_sprintfa(gs, "leak debug: no\n");
	g_string_sprintfa(gs, "instrument: no\n");
	g_string_sprintfa(gs, "      opts:");
#ifdef _MT
	g_string_sprintfa(gs, " MULTITHREAD");
#endif
#ifdef _DLL
	g_string_sprintfa(gs, " DLL");
#endif
#ifdef _DEBUG
	g_string_sprintfa(gs, " DEBUG");
#endif
	g_string_append(gs, "\n");

	txt_settings = g_strdup(gs->str);
	g_string_free(gs, TRUE);
	

    return 0;
}

char *txt_settings;

/* ntpq */
struct ntpq *ntpq;

struct ntpq *init_ntpq(){
	//progress("Initializing NTP monitor");		

	return NULL;
}

void free_ntpq(struct ntpq *ntpq){ 
	//progress("Terminating NTP monitor");		
}


// http://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html
static JNIEnv *genv;
//static jobject gMainActivity;
//static jclass gMainActivityClass;
static jobject gbundle;
static jmethodID gputString;
//#static jstring gjstr;
//static const char *gstr = NULL;
struct state *gstate = NULL;

JNIEXPORT void JNICALL Java_cz_nagano_tucnak_MainActivity_nativeSetState(JNIEnv *env, jobject thiz, jobject jkey, jobject jval){
    if (!gstate) gstate = init_state();

    const char *key = (*env)->GetStringUTFChars(env, jkey, NULL);
    const char *val = (*env)->GetStringUTFChars(env, jval, NULL);
    
    __android_log_print(ANDROID_LOG_DEBUG, "tucnak", "nativeSetState(key='%s' val='%s')\n", key, val);
    state_dupstr(gstate, key, val);

    (*env)->ReleaseStringUTFChars(env, jkey, key); 
    (*env)->ReleaseStringUTFChars(env, jval, val); 
}


/*static void android_restore_one(gpointer key, gpointer val, gpointer user_data){
    dbg("android_restore_one('%s', '%s')\n", key, val);
} */

void android_restore_state(){
    
    dbg("android_restore_state started\n");

    if (!gstate){
        dbg("gstate=null, returning\n");
        return;
    }
    
	progress("Restoring state");
//    state_foreach(gstate, android_restore_one, NULL);
    state_restore(gstate);
    free_state(gstate);
    gstate = NULL;

    dbg("android_restore_state finished\n");
}

static void android_save_one(gpointer key, gpointer val, gpointer user_data){
    jstring jkey, jvalue;
    struct state *state = (struct state *)user_data;
    JNIEnv *env = state->env;

    jkey = (*env)->NewStringUTF(env, key);
    jvalue = (*env)->NewStringUTF(env, val);
    (*env)->CallVoidMethod(env, gbundle, gputString, jkey, jvalue);
//    dbg("putStr('%s', '%s')\n", key, val);
}

int updating = 0;


JNIEXPORT void JNICALL Java_cz_nagano_tucnak_MainActivity_nativeOnSaveInstanceState(JNIEnv *env, jobject thiz, jobject bundle){
    dbg("Java_cz_nagano_tucnak_MainActivity_nativeOnSaveInstance started bundle=%p genv=%p env=%p\n", bundle, genv, env);
	save_all_bands_txt(0); 
    if (updating){
        dbg("updating is active, exiting app\n");
        exit(0);
    }

    gbundle = bundle;
    jclass bundleClass = (*env)->GetObjectClass(env, bundle); 
//    gputInt = (*env)->GetMethodID(env, bundleClass, "putInt", "(Ljava/lang/String;I)V");
    gputString = (*env)->GetMethodID(env, bundleClass, "putString", "(Ljava/lang/String;Ljava/lang/String;)V");

    struct state *state = init_state();
    state->env = env;
    state_save(state);
    dbg("state saved to hash\n");
    state_foreach(state, android_save_one, state);
    dbg("state saved to bundle\n");
    free_state(state);
    state = NULL;

    dbg("Java_cz_nagano_tucnak_MainActivity_nativeOnSaveInstance finished\n");
}


void android_update_package(char *filename){
    updating = 1;
    zandroid_update_package(filename);
}



JNIEXPORT void JNICALL Java_cz_nagano_tucnak_MainActivity_nativeWavPlayed(JNIEnv *env, jobject thiz){
    dbg("nativeWavPlayed\n");
	zselect_msg_send(zsel, "SSBP;%s", "e");
}

JNIEXPORT void JNICALL Java_cz_nagano_tucnak_MainActivity_nativeWavError(JNIEnv *env, jobject thiz, jobject jstr){
    dbg("nativeWavError...\n");
    const char *str = (*env)->GetStringUTFChars(env, jstr, NULL);
    dbg("nativeWavError('%s')\n", str);
	zselect_msg_send(zsel, "SSBP;!%s", str);
    dbg("after send\n");
    (*env)->ReleaseStringUTFChars(env, jstr, str); 
    dbg("after release\n");
} 




/*JNIEXPORT void JNICALL Java_cz_nagano_tucnak_MainActivity_nativeMsgSend(JNIEnv *env, jobject thiz, jobject jstr){
    const char *str = (*genv)->GetStringUTFChars(genv, jkey, NULL);
    dbg("nativeMsgSend('%s')\n", str);
    zselect_msg_send(zsel, str);
    (*env)->ReleaseStringUTFChars(env, jstr, str); 
} */


