/*
 * 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_native_frame.h"
#include "jni/jni_native_buffer.h"
#include "jni/jni_util.h"

#include "native/base/logging.h"
#include "native/core/gl_frame.h"
#include "native/core/native_frame.h"

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

typedef union {
    uint32_t value;
    uint8_t  rgba[4];
} Pixel;

jboolean Java_android_filterfw_core_NativeFrame_nativeAllocate(JNIEnv* env,
                                                               jobject thiz,
                                                               jint size) {
  std::unique_ptr<NativeFrame> frame(new NativeFrame(size));
  return ToJBool(WrapOwnedObjectInJava(std::move(frame), env, thiz, true));
}

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

jint Java_android_filterfw_core_NativeFrame_nativeIntSize(JNIEnv*, jclass) {
  return sizeof(jint);
}

jint Java_android_filterfw_core_NativeFrame_nativeFloatSize(JNIEnv*, jclass) {
  return sizeof(jfloat);
}

jboolean Java_android_filterfw_core_NativeFrame_setNativeData(JNIEnv* env,
                                                              jobject thiz,
                                                              jbyteArray data,
                                                              jint offset,
                                                              jint length) {
  NativeFrame* frame = ConvertFromJava<NativeFrame>(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),
                                            0,
                                            length);
      env->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
      return ToJBool(success);
    }
  }
  return JNI_FALSE;
}

jbyteArray Java_android_filterfw_core_NativeFrame_getNativeData(JNIEnv* env,
                                                                jobject thiz,
                                                                jint size) {
  NativeFrame* frame = ConvertFromJava<NativeFrame>(env, thiz);
  if (frame) {
    const uint8_t* data = frame->Data();
    if (!data || size > frame->Size())
      return NULL;
    jbyteArray result = env->NewByteArray(size);
    env->SetByteArrayRegion(result, 0, size, reinterpret_cast<const jbyte*>(data));
    return result;
  }
  return NULL;
}

jboolean Java_android_filterfw_core_NativeFrame_getNativeBuffer(JNIEnv* env,
                                                                jobject thiz,
                                                                jobject buffer) {
  NativeFrame* frame = ConvertFromJava<NativeFrame>(env, thiz);
  if (frame) {
    char* data = reinterpret_cast<char*>(frame->MutableData());
    return ToJBool(AttachDataToJBuffer(env, buffer, data, frame->Size()));
  }
  return JNI_FALSE;
}

jboolean Java_android_filterfw_core_NativeFrame_setNativeInts(JNIEnv* env,
                                                              jobject thiz,
                                                              jintArray ints) {
  NativeFrame* frame = ConvertFromJava<NativeFrame>(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),
                                            0,
                                            length * sizeof(jint));
      env->ReleaseIntArrayElements(ints, int_ptr, JNI_ABORT);
      return ToJBool(success);
    }
  }
  return JNI_FALSE;
}

jintArray Java_android_filterfw_core_NativeFrame_getNativeInts(JNIEnv* env,
                                                               jobject thiz,
                                                               jint size) {
  NativeFrame* frame = ConvertFromJava<NativeFrame>(env, thiz);
  if (frame) {
    const uint8_t* data = frame->Data();
    if (!data || size > frame->Size() || (size % sizeof(jint)) != 0)
      return NULL;
    const int count = size / sizeof(jint);
    jintArray result = env->NewIntArray(count);
    env->SetIntArrayRegion(result, 0, count, reinterpret_cast<const jint*>(data));
    return result;
  }
  return NULL;
}

jboolean Java_android_filterfw_core_NativeFrame_setNativeFloats(JNIEnv* env,
                                                                jobject thiz,
                                                                jfloatArray floats) {
  NativeFrame* frame = ConvertFromJava<NativeFrame>(env, thiz);
  if (frame && floats) {
    jfloat* float_ptr = env->GetFloatArrayElements(floats, NULL);
    const int length = env->GetArrayLength(floats);
    if (float_ptr) {
      const bool success = frame->WriteData(reinterpret_cast<const uint8_t*>(float_ptr),
                                            0,
                                            length * sizeof(jfloat));
      env->ReleaseFloatArrayElements(floats, float_ptr, JNI_ABORT);
      return ToJBool(success);
    }
  }
  return JNI_FALSE;
}

jfloatArray Java_android_filterfw_core_NativeFrame_getNativeFloats(JNIEnv* env,
                                                                   jobject thiz,
                                                                   jint size) {
  NativeFrame* frame = ConvertFromJava<NativeFrame>(env, thiz);
  if (frame) {
    const uint8_t* data = frame->Data();
    if (!data || size > frame->Size() || (size % sizeof(jfloat)) != 0)
      return NULL;
    const int count = size / sizeof(jfloat);
    jfloatArray result = env->NewFloatArray(count);
    env->SetFloatArrayRegion(result, 0, count, reinterpret_cast<const jfloat*>(data));
    return result;
  }
  return NULL;
}

jboolean Java_android_filterfw_core_NativeFrame_setNativeBitmap(JNIEnv* env,
                                                                jobject thiz,
                                                                jobject bitmap,
                                                                jint size,
                                                                jint bytes_per_sample) {
  NativeFrame* frame = ConvertFromJava<NativeFrame>(env, thiz);
  if (frame && bitmap) {
    // Make sure frame size matches bitmap size
    if ((size / 4) != (frame->Size() / bytes_per_sample)) {
      ALOGE("Size mismatch in native setBitmap()!");
      return JNI_FALSE;
    }

    Pixel* src_ptr;
    const int result = AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void**>(&src_ptr));
    if (result == ANDROID_BITMAP_RESULT_SUCCESS) {
      // Create destination pointers
      uint8_t* dst_ptr = reinterpret_cast<uint8_t*>(frame->MutableData());
      const uint8_t* end_ptr = dst_ptr + frame->Size();
      switch (bytes_per_sample) {
        case 1: { // RGBA -> GRAY
          while (dst_ptr < end_ptr) {
            const Pixel pixel = *(src_ptr++);
            *(dst_ptr++) = (pixel.rgba[0] + pixel.rgba[1] + pixel.rgba[2]) / 3;
          }
          break;
        }
        case 3: { // RGBA -> RGB
          while (dst_ptr < end_ptr) {
            const Pixel pixel = *(src_ptr++);
            *(dst_ptr++) = pixel.rgba[0];
            *(dst_ptr++) = pixel.rgba[1];
            *(dst_ptr++) = pixel.rgba[2];
          }
          break;
        }
        case 4: { // RGBA -> RGBA
          memcpy(dst_ptr, src_ptr, frame->Size());
          break;
        }
        default:
          ALOGE("Unsupported bytes-per-pixel %d in setBitmap!", bytes_per_sample);
          break;
      }
      return (AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESULT_SUCCESS);
    }
  }
  return JNI_FALSE;
}

jboolean Java_android_filterfw_core_NativeFrame_getNativeBitmap(JNIEnv* env,
                                                                jobject thiz,
                                                                jobject bitmap,
                                                                jint size,
                                                                jint bytes_per_sample) {
  NativeFrame* frame = ConvertFromJava<NativeFrame>(env, thiz);
  if (frame && bitmap) {
    Pixel* dst_ptr;
    const int result = AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void**>(&dst_ptr));
    if (result == ANDROID_BITMAP_RESULT_SUCCESS) {
      // Make sure frame size matches bitmap size
      if ((size / 4) != (frame->Size() / bytes_per_sample)) {
        ALOGE("Size mismatch in native getBitmap()!");
        return JNI_FALSE;
      }

      const uint8_t* src_ptr = frame->Data();
      const uint8_t* end_ptr = src_ptr + frame->Size();
      switch (bytes_per_sample) {
        case 1: { // GRAY -> RGBA
          while (src_ptr < end_ptr) {
            const uint8_t value = *(src_ptr++);
            dst_ptr->rgba[0] = dst_ptr->rgba[1] = dst_ptr->rgba[2] = value;
            dst_ptr->rgba[3] = 255;
            ++dst_ptr;
          }
          break;
        }
        case 3: { // RGB -> RGBA
          while (src_ptr < end_ptr) {
            dst_ptr->rgba[0] = *(src_ptr++);
            dst_ptr->rgba[1] = *(src_ptr++);
            dst_ptr->rgba[2] = *(src_ptr++);
            dst_ptr->rgba[3] = 255;
            ++dst_ptr;
          }
          break;
        }
        case 4: { // RGBA -> RGBA
          memcpy(dst_ptr, src_ptr, frame->Size());
          break;
        }
        default:
          ALOGE("Unsupported bytes-per-pixel %d in getBitmap!", bytes_per_sample);
          break;
      }
      return (AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESULT_SUCCESS);
    }
  }
  return JNI_FALSE;
}

jint Java_android_filterfw_core_NativeFrame_getNativeCapacity(JNIEnv* env, jobject thiz) {
  NativeFrame* frame = ConvertFromJava<NativeFrame>(env, thiz);
  return frame ? frame->Capacity() : -1;
}

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

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