/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

#include <utils/misc.h>
#include <utils/String8.h>
#include <utils/Log.h>

#include <android/bitmap.h>

#include "jni.h"
#include "JNIHelp.h"

using namespace android;

extern "C"
{
    #include <fd_emb_sdk.h>
}

struct FaceData
{
    float confidence;
    float midpointx;
    float midpointy;
    float eyedist;
};

struct FaceOffsets
{
    jfieldID    confidence;
    jfieldID    midpointx;
    jfieldID    midpointy;
    jfieldID    eyedist;
    jfieldID    eulerx;
    jfieldID    eulery;
    jfieldID    eulerz;
} gFaceOffsets;

struct FaceDetectorOffsets
{
    jfieldID    fd;
    jfieldID    sdk;
    jfieldID    dcr;
    jfieldID    width;
    jfieldID    height;
    jfieldID    maxFaces;
    jfieldID    bwbuffer;
} gFaceDetectorOffsets;

// ---------------------------------------------------------------------------

static void getFaceData(btk_HDCR hdcr, FaceData* fdata)
{
    btk_Node leftEye, rightEye;

    btk_DCR_getNode(hdcr, 0, &leftEye);
    btk_DCR_getNode(hdcr, 1, &rightEye);

    fdata->eyedist = (float)(rightEye.x - leftEye.x) / (1 << 16);
    fdata->midpointx = (float)(rightEye.x + leftEye.x) / (1 << 17);
    fdata->midpointy = (float)(rightEye.y + leftEye.y) / (1 << 17);
    fdata->confidence = (float)btk_DCR_confidence(hdcr) / (1 << 24);
}

// ---------------------------------------------------------------------------

static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
{
    jclass npeClazz = env->FindClass(exc);
    env->ThrowNew(npeClazz, msg);
}

static void
nativeClassInit
(JNIEnv *_env, jclass _this)
{
    gFaceDetectorOffsets.fd             = _env->GetFieldID(_this, "mFD", "J");
    gFaceDetectorOffsets.sdk            = _env->GetFieldID(_this, "mSDK", "J");
    gFaceDetectorOffsets.dcr            = _env->GetFieldID(_this, "mDCR", "J");
    gFaceDetectorOffsets.width          = _env->GetFieldID(_this, "mWidth", "I");
    gFaceDetectorOffsets.height         = _env->GetFieldID(_this, "mHeight", "I");
    gFaceDetectorOffsets.maxFaces       = _env->GetFieldID(_this, "mMaxFaces", "I");
    gFaceDetectorOffsets.bwbuffer       = _env->GetFieldID(_this, "mBWBuffer", "[B");

    jclass faceClass = _env->FindClass("android/media/FaceDetector$Face");
    gFaceOffsets.confidence  = _env->GetFieldID(faceClass, "mConfidence", "F");
    gFaceOffsets.midpointx   = _env->GetFieldID(faceClass, "mMidPointX", "F");
    gFaceOffsets.midpointy   = _env->GetFieldID(faceClass, "mMidPointY", "F");
    gFaceOffsets.eyedist     = _env->GetFieldID(faceClass, "mEyesDist", "F");
    gFaceOffsets.eulerx      = _env->GetFieldID(faceClass, "mPoseEulerX", "F");
    gFaceOffsets.eulery      = _env->GetFieldID(faceClass, "mPoseEulerY", "F");
    gFaceOffsets.eulerz      = _env->GetFieldID(faceClass, "mPoseEulerZ", "F");
}

// ---------------------------------------------------------------------------

static jint
initialize(JNIEnv *_env, jobject _this,
     jint w, jint h, jint maxFaces)
{
    // load the configuration file
    const char* root = getenv("ANDROID_ROOT");
    String8 path(root);
    path.appendPath("usr/share/bmd/RFFstd_501.bmd");
    // path.appendPath("usr/share/bmd/RFFspeed_501.bmd");

    const int MAX_FILE_SIZE = 65536;
    void* initData = malloc( MAX_FILE_SIZE ); /* enough to fit entire file */
    int filedesc = open(path.string(), O_RDONLY);
    int initDataSize = read(filedesc, initData, MAX_FILE_SIZE);
    close(filedesc);

    // --------------------------------------------------------------------
    btk_HSDK sdk = NULL;
    btk_SDKCreateParam sdkParam = btk_SDK_defaultParam();
    sdkParam.fpMalloc = malloc;
    sdkParam.fpFree = free;
    sdkParam.maxImageWidth = w;
    sdkParam.maxImageHeight = h;

    btk_Status status = btk_SDK_create(&sdkParam, &sdk);
    // make sure everything went well
    if (status != btk_STATUS_OK) {
        // XXX: be more precise about what went wrong
        doThrow(_env, "java/lang/OutOfMemoryError", NULL);
        return 0;
    }

    btk_HDCR dcr = NULL;
    btk_DCRCreateParam dcrParam = btk_DCR_defaultParam();
    btk_DCR_create( sdk, &dcrParam, &dcr );

    btk_HFaceFinder fd = NULL;
    btk_FaceFinderCreateParam fdParam = btk_FaceFinder_defaultParam();
    fdParam.pModuleParam = initData;
    fdParam.moduleParamSize = initDataSize;
    fdParam.maxDetectableFaces = maxFaces;
    status = btk_FaceFinder_create( sdk, &fdParam, &fd );
    btk_FaceFinder_setRange(fd, 20, w/2); /* set eye distance range */

    // make sure everything went well
    if (status != btk_STATUS_OK) {
        // XXX: be more precise about what went wrong
        doThrow(_env, "java/lang/OutOfMemoryError", NULL);
        return 0;
    }

    // free the configuration file
    free(initData);

    // initialize the java object
    _env->SetLongField(_this, gFaceDetectorOffsets.fd,  (jlong)fd);
    _env->SetLongField(_this, gFaceDetectorOffsets.sdk, (jlong)sdk);
    _env->SetLongField(_this, gFaceDetectorOffsets.dcr, (jlong)dcr);

    return 1;
}

static void
destroy(JNIEnv *_env, jobject _this)
{
    btk_HFaceFinder hfd =
        (btk_HFaceFinder)(_env->GetLongField(_this, gFaceDetectorOffsets.fd));
    btk_FaceFinder_close( hfd );

    btk_HDCR hdcr = (btk_HDCR)(_env->GetLongField(_this, gFaceDetectorOffsets.dcr));
    btk_DCR_close( hdcr );

    btk_HSDK hsdk = (btk_HSDK)(_env->GetLongField(_this, gFaceDetectorOffsets.sdk));
    btk_SDK_close( hsdk );
}

static jint
detect(JNIEnv *_env, jobject _this,
     jobject bitmap)
{
    // get the fields we need
    btk_HDCR hdcr = (btk_HDCR)(_env->GetLongField(_this, gFaceDetectorOffsets.dcr));
    btk_HFaceFinder hfd =
        (btk_HFaceFinder)(_env->GetLongField(_this, gFaceDetectorOffsets.fd));
    u32 maxFaces = _env->GetIntField(_this, gFaceDetectorOffsets.maxFaces);
    u32 width = _env->GetIntField(_this, gFaceDetectorOffsets.width);
    u32 height = _env->GetIntField(_this, gFaceDetectorOffsets.height);

    jbyteArray bwbufferObject = (jbyteArray)
            _env->GetObjectField(_this, gFaceDetectorOffsets.bwbuffer);

    // get to our BW temporary buffer
    jbyte* bwbuffer = _env->GetByteArrayElements(bwbufferObject, 0);

    // convert the image to B/W
    uint8_t* dst = (uint8_t*)bwbuffer;

    uint16_t const* src;
    AndroidBitmapInfo bitmapInfo;
    AndroidBitmap_getInfo(_env, bitmap, &bitmapInfo);
    AndroidBitmap_lockPixels(_env, bitmap, (void**) &src);

    int wpr = bitmapInfo.stride / 2;
    for (u32 y=0 ; y<height; y++) {
        for (u32 x=0 ; x<width ; x++) {
            uint16_t rgb = src[x];
            int r  = rgb >> 11;
            int g2 = (rgb >> 5) & 0x3F;
            int b  = rgb & 0x1F;
            // L coefficients 0.299 0.587 0.11
            int L = (r<<1) + (g2<<1) + (g2>>1) + b;
            *dst++ = L;
        }
        src += wpr;
    }

    // run detection
    btk_DCR_assignGrayByteImage(hdcr, bwbuffer, width, height);

    int numberOfFaces = 0;
    if (btk_FaceFinder_putDCR(hfd, hdcr) == btk_STATUS_OK) {
        numberOfFaces = btk_FaceFinder_faces(hfd);
    } else {
        ALOGE("ERROR: Return 0 faces because error exists in btk_FaceFinder_putDCR.\n");
    }

    // release the arrays we're using
    AndroidBitmap_unlockPixels(_env, bitmap);
    _env->ReleaseByteArrayElements(bwbufferObject, bwbuffer, 0);
    return numberOfFaces;
}

static void
get_face(JNIEnv *_env, jobject _this,
     jobject face, jint)
{
    btk_HDCR hdcr = (btk_HDCR)(_env->GetLongField(_this, gFaceDetectorOffsets.dcr));
    btk_HFaceFinder hfd =
        (btk_HFaceFinder)(_env->GetLongField(_this, gFaceDetectorOffsets.fd));

    FaceData faceData;
    btk_FaceFinder_getDCR(hfd, hdcr);
    getFaceData(hdcr, &faceData);

    const float X2F = 1.0f / 65536.0f;
    _env->SetFloatField(face, gFaceOffsets.confidence,  faceData.confidence);
    _env->SetFloatField(face, gFaceOffsets.midpointx,   faceData.midpointx);
    _env->SetFloatField(face, gFaceOffsets.midpointy,   faceData.midpointy);
    _env->SetFloatField(face, gFaceOffsets.eyedist,     faceData.eyedist);
    _env->SetFloatField(face, gFaceOffsets.eulerx,      0);
    _env->SetFloatField(face, gFaceOffsets.eulery,      0);
    _env->SetFloatField(face, gFaceOffsets.eulerz,      0);
}

// ---------------------------------------------------------------------------

static const char *classPathName = "android/media/FaceDetector";

static JNINativeMethod methods[] = {
{"nativeClassInit", "()V",                                  (void*)nativeClassInit },
{"fft_initialize",  "(III)I",                               (void*)initialize },
{"fft_detect",      "(Landroid/graphics/Bitmap;)I",         (void*)detect },
{"fft_get_face",    "(Landroid/media/FaceDetector$Face;I)V",(void*)get_face },
{"fft_destroy",     "()V",                                  (void*)destroy },
};

int register_android_media_FaceDetector(JNIEnv *_env)
{
    return jniRegisterNativeMethods(_env, classPathName, methods, NELEM(methods));
}

// ---------------------------------------------------------------------------

jint JNI_OnLoad(JavaVM* vm, void*)
{
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        ALOGE("ERROR: GetEnv failed\n");
        goto bail;
    }
    assert(env != NULL);

    if (register_android_media_FaceDetector(env) < 0) {
        ALOGE("ERROR: MediaPlayer native registration failed\n");
        goto bail;
    }

    /* success -- return valid version number */
    result = JNI_VERSION_1_4;

bail:
    return result;
}
