#include <jni.h>
#include <android/binder_ibinder_jni.h>
#include <android/hardware_buffer.h>
#include <aidl/com/omixlab/mosis/BnMosisService.h>
#include <aidl/com/omixlab/mosis/IMosisListener.h>
#include <aidl/com/omixlab/mosis/BnMosisListener.h>
#include "logger.h"
#include "kernel.h"
#include "assets_manager.h"
#include <glad/egl.h>
#include <glad/gles2.h>
#include <thread>
#include <android/asset_manager_jni.h>

using namespace aidl::com::omixlab::mosis;
using namespace aidl::android::hardware;

class Texture
{
    GLuint id;
public:
    bool create(uint32_t width, uint32_t height)
    {
        glGenTextures(1, &id);
        return true;
    }
};

class NativeService : public BnMosisService
{
    std::unique_ptr<Kernel> m_kernel;
public:
    NativeService() = default;
    ndk::ScopedAStatus initOS(const std::shared_ptr<IMosisListener>& listener,
        bool *_aidl_return) override
    {
        if (!m_kernel)
        {
            m_kernel = std::make_unique<Kernel>(listener);
            *_aidl_return = true;
        }
        else
        {
            m_kernel->add_listener(listener);
            *_aidl_return = true;
        }
        return ndk::ScopedAStatus::ok();
    }

    ndk::ScopedAStatus onTouchDown(float in_x, float in_y) override
    {
        if (m_kernel)
            m_kernel->on_touch_down(in_x, in_y);
        return ndk::ScopedAStatus::ok();
    }

    ndk::ScopedAStatus onTouchMove(float in_x, float in_y) override
    {
        if (m_kernel)
            m_kernel->on_touch_move(in_x, in_y);
        return ndk::ScopedAStatus::ok();
    }

    ndk::ScopedAStatus onTouchUp(float in_x, float in_y) override
    {
        if (m_kernel)
            m_kernel->on_touch_up(in_x, in_y);
        return ndk::ScopedAStatus::ok();
    }
};

extern "C"
JNIEXPORT jobject JNICALL
Java_com_omixlab_mosis_NativeService_getBinderNative(JNIEnv *env, jobject thiz)
{
    static std::shared_ptr<NativeService> g_service = ndk::SharedRefBase::make<NativeService>();
    return AIBinder_toJavaBinder(env, g_service->asBinder().get());
}

extern "C"
JNIEXPORT void JNICALL
Java_com_omixlab_mosis_NativeService_setAssetManager(JNIEnv *env, jobject thiz,
    jobject asset_manager)
{
    AssetsManager::Init(AAssetManager_fromJava(env, asset_manager));
}