/*
 * Copyright (C) 2011 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 "android/bitmap.h"

#include "jni/jni_gl_frame.h"
#include "jni/jni_util.h"

#include "native/core/gl_env.h"
#include "native/core/gl_frame.h"
#include "native/core/native_frame.h"

using android::filterfw::GLEnv;
using android::filterfw::GLFrame;
using android::filterfw::NativeFrame;

// Helper functions ////////////////////////////////////////////////////////////////////////////////
void ConvertFloatsToRGBA(const float* floats, int length, uint8_t* result) {
  for (int i = 0; i < length; ++i) {
    result[i] = static_cast<uint8_t>(floats[i] * 255.0);
  }
}

void ConvertRGBAToFloats(const uint8_t* rgba, int length, float* result) {
  for (int i = 0; i < length; ++i) {
    result[i] = rgba[i] / 255.0;
  }
}

// GLFrame JNI implementation //////////////////////////////////////////////////////////////////////
jboolean Java_android_filterfw_core_GLFrame_nativeAllocate(JNIEnv* env,
                                                           jobject thiz,
                                                           jobject gl_env,
                                                           jint width,
                                                           jint height) {
  GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
  if (!gl_env_ptr) return JNI_FALSE;
  GLFrame* frame = new GLFrame(gl_env_ptr);
  if (frame->Init(width, height)) {
    return ToJBool(WrapObjectInJava(frame, env, thiz, true));
  } else {
    delete frame;
    return JNI_FALSE;
  }
}

jboolean Java_android_filterfw_core_GLFrame_nativeAllocateWithTexture(JNIEnv* env,
                                                                      jobject thiz,
                                                                      jobject gl_env,
                                                                      jint tex_id,
                                                                      jint width,
                                                                      jint height) {
  GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
  if (!gl_env_ptr) return JNI_FALSE;
  GLFrame* frame = new GLFrame(gl_env_ptr);
  if (frame->InitWithTexture(tex_id, width, height)) {
    return ToJBool(WrapObjectInJava(frame, env, thiz, true));
  } else {
    delete frame;
    return JNI_FALSE;
  }
}

jboolean Java_android_filterfw_core_GLFrame_nativeAllocateWithFbo(JNIEnv* env,
                                                                  jobject thiz,
                                                                  jobject gl_env,
                                                                  jint fbo_id,
                                                                  jint width,
                                                                  jint height) {
  GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
  if (!gl_env_ptr) return JNI_FALSE;
  GLFrame* frame = new GLFrame(gl_env_ptr);
  if (frame->InitWithFbo(fbo_id, width, height)) {
    return ToJBool(WrapObjectInJava(frame, env, thiz, true));
  } else {
    delete frame;
    return JNI_FALSE;
  }
}

jboolean Java_android_filterfw_core_GLFrame_nativeAllocateExternal(JNIEnv* env,
                                                                   jobject thiz,
                                                                   jobject gl_env) {
  GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
  if (!gl_env_ptr) return JNI_FALSE;
  GLFrame* frame = new GLFrame(gl_env_ptr);
  if (frame->InitWithExternalTexture()) {
    return ToJBool(WrapObjectInJava(frame, env, thiz, true));
  } else {
    delete frame;
    return JNI_FALSE;
  }
}

jboolean Java_android_filterfw_core_GLFrame_nativeDeallocate(JNIEnv* env, jobject thiz) {
  return ToJBool(DeleteNativeObject<GLFrame>(env, thiz));
}

jboolean Java_android_filterfw_core_GLFrame_setNativeData(JNIEnv* env,
                                                          jobject thiz,
                                                          jbyteArray data,
                                                          jint offset,
                                                          jint length) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  if (frame && data) {
    jbyte* bytes = env->GetByteArrayElements(data, NULL);
    if (bytes) {
      const bool success = frame->WriteData(reinterpret_cast<const uint8_t*>(bytes + offset), length);
      env->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
      return ToJBool(success);
    }
  }
  return JNI_FALSE;
}

jbyteArray Java_android_filterfw_core_GLFrame_getNativeData(JNIEnv* env, jobject thiz) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  if (frame && frame->Size() > 0) {
    jbyteArray result = env->NewByteArray(frame->Size());
    jbyte* data = env->GetByteArrayElements(result, NULL);
    frame->CopyDataTo(reinterpret_cast<uint8_t*>(data), frame->Size());
    env->ReleaseByteArrayElements(result, data, 0);
    return result;
  }
  return NULL;
}

jboolean Java_android_filterfw_core_GLFrame_setNativeInts(JNIEnv* env,
                                                          jobject thiz,
                                                          jintArray ints) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  if (frame && ints) {
    jint* int_ptr = env->GetIntArrayElements(ints, NULL);
    const int length = env->GetArrayLength(ints);
    if (int_ptr) {
      const bool success = frame->WriteData(reinterpret_cast<const uint8_t*>(int_ptr),
                                            length * sizeof(jint));
      env->ReleaseIntArrayElements(ints, int_ptr, JNI_ABORT);
      return ToJBool(success);
    }
  }
  return JNI_FALSE;
}

jintArray Java_android_filterfw_core_GLFrame_getNativeInts(JNIEnv* env, jobject thiz) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  if (frame && frame->Size() > 0 && (frame->Size() % sizeof(jint) == 0)) {
    jintArray result = env->NewIntArray(frame->Size() / sizeof(jint));
    jint* data = env->GetIntArrayElements(result, NULL);
    frame->CopyDataTo(reinterpret_cast<uint8_t*>(data), frame->Size());
    env->ReleaseIntArrayElements(result, data, 0);
    return result;
   }
   return NULL;
}

jboolean Java_android_filterfw_core_GLFrame_setNativeFloats(JNIEnv* env,
                                                            jobject thiz,
                                                            jfloatArray floats) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  if (frame && floats) {
    jfloat* float_ptr = env->GetFloatArrayElements(floats, NULL);
    const int length = env->GetArrayLength(floats);
    if (float_ptr) {
      // Convert floats to RGBA buffer
      uint8_t* rgba_buffer = new uint8_t[length];
      ConvertFloatsToRGBA(float_ptr, length, rgba_buffer);
      env->ReleaseFloatArrayElements(floats, float_ptr, JNI_ABORT);

      // Write RGBA buffer to frame
      const bool success = frame->WriteData(rgba_buffer, length);

      // Clean-up
      delete[] rgba_buffer;
      return ToJBool(success);
    }
  }
  return JNI_FALSE;
}

jfloatArray Java_android_filterfw_core_GLFrame_getNativeFloats(JNIEnv* env, jobject thiz) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  if (frame && frame->Size() > 0) {
    // Create the result array
    jfloatArray result = env->NewFloatArray(frame->Size());
    jfloat* float_array = env->GetFloatArrayElements(result, NULL);

    // Read the frame pixels
    uint8_t* pixels = new uint8_t[frame->Size()];
    frame->CopyDataTo(pixels, frame->Size());

    // Convert them to floats
    ConvertRGBAToFloats(pixels, frame->Size(), float_array);

    // Clean-up
    delete[] pixels;
    env->ReleaseFloatArrayElements(result, float_array, 0);
    return result;
  }
  return NULL;
}

jboolean Java_android_filterfw_core_GLFrame_setNativeBitmap(JNIEnv* env,
                                                            jobject thiz,
                                                            jobject bitmap,
                                                            jint size) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  if (frame && bitmap) {
    uint8_t* pixels;
    const int result = AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void**>(&pixels));
    if (result == ANDROID_BITMAP_RESULT_SUCCESS) {
      const bool success = frame->WriteData(pixels, size);
      return ToJBool(success &&
                     AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESULT_SUCCESS);
    }
  }
  return JNI_FALSE;
}

jboolean Java_android_filterfw_core_GLFrame_getNativeBitmap(JNIEnv* env,
                                                            jobject thiz,
                                                            jobject bitmap) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  if (frame && bitmap) {
    uint8_t* pixels;
    const int result = AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void**>(&pixels));
    if (result == ANDROID_BITMAP_RESULT_SUCCESS) {
      frame->CopyDataTo(pixels, frame->Size());
      return (AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESULT_SUCCESS);
    }
  }
  return JNI_FALSE;
}

jboolean Java_android_filterfw_core_GLFrame_setNativeViewport(JNIEnv* env,
                                                              jobject thiz,
                                                              jint x,
                                                              jint y,
                                                              jint width,
                                                              jint height) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  return frame ? ToJBool(frame->SetViewport(x, y, width, height)) : JNI_FALSE;
}

jint Java_android_filterfw_core_GLFrame_getNativeTextureId(JNIEnv* env, jobject thiz) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  return frame ? frame->GetTextureId() : -1;
}

jint Java_android_filterfw_core_GLFrame_getNativeFboId(JNIEnv* env, jobject thiz) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  return frame ? frame->GetFboId() : -1;
}

jboolean Java_android_filterfw_core_GLFrame_generateNativeMipMap(JNIEnv* env, jobject thiz) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  return frame ? ToJBool(frame->GenerateMipMap()) : JNI_FALSE;
}

jboolean Java_android_filterfw_core_GLFrame_setNativeTextureParam(JNIEnv* env,
                                                                  jobject thiz,
                                                                  jint param,
                                                                  jint value) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  return frame ? ToJBool(frame->SetTextureParameter(param, value)) : JNI_FALSE;
}

jboolean Java_android_filterfw_core_GLFrame_nativeResetParams(JNIEnv* env, jobject thiz) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  return frame ? ToJBool(frame->ResetTexParameters()) : JNI_FALSE;
}

jboolean Java_android_filterfw_core_GLFrame_nativeCopyFromNative(JNIEnv* env,
                                                                 jobject thiz,
                                                                 jobject frame) {
  GLFrame* this_frame = ConvertFromJava<GLFrame>(env, thiz);
  NativeFrame* other_frame = ConvertFromJava<NativeFrame>(env, frame);
  if (this_frame && other_frame) {
    return ToJBool(this_frame->WriteData(other_frame->Data(), other_frame->Size()));
  }
  return JNI_FALSE;
}

jboolean Java_android_filterfw_core_GLFrame_nativeCopyFromGL(JNIEnv* env,
                                                             jobject thiz,
                                                             jobject frame) {
  GLFrame* this_frame = ConvertFromJava<GLFrame>(env, thiz);
  GLFrame* other_frame = ConvertFromJava<GLFrame>(env, frame);
  if (this_frame && other_frame) {
    return ToJBool(this_frame->CopyPixelsFrom(other_frame));
  }
  return JNI_FALSE;
}

jboolean Java_android_filterfw_core_GLFrame_nativeFocus(JNIEnv* env, jobject thiz) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  return ToJBool(frame && frame->FocusFrameBuffer());
}

jboolean Java_android_filterfw_core_GLFrame_nativeReattachTexToFbo(JNIEnv* env, jobject thiz) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  return ToJBool(frame && frame->ReattachTextureToFbo());
}

jboolean Java_android_filterfw_core_GLFrame_nativeDetachTexFromFbo(JNIEnv* env, jobject thiz) {
  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
  return ToJBool(frame && frame->DetachTextureFromFbo());
}

