/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/modules/video_render/android/video_render_android_surface_view.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/tick_util.h"

#ifdef ANDROID_LOG
#include <android/log.h>
#include <stdio.h>

#undef WEBRTC_TRACE
#define WEBRTC_TRACE(a,b,c,...)  __android_log_print(ANDROID_LOG_DEBUG, "*WEBRTC*", __VA_ARGS__)
#else
#include "webrtc/system_wrappers/include/trace.h"
#endif

namespace webrtc {

AndroidSurfaceViewRenderer::AndroidSurfaceViewRenderer(
    const int32_t id,
    const VideoRenderType videoRenderType,
    void* window,
    const bool fullscreen) :
    VideoRenderAndroid(id,videoRenderType,window,fullscreen),
    _javaRenderObj(NULL),
    _javaRenderClass(NULL) {
}

AndroidSurfaceViewRenderer::~AndroidSurfaceViewRenderer() {
  WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id,
               "AndroidSurfaceViewRenderer dtor");
  if(g_jvm) {
    // get the JNI env for this thread
    bool isAttached = false;
    JNIEnv* env = NULL;
    if (g_jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
      // try to attach the thread and get the env
      // Attach this thread to JVM
      jint res = g_jvm->AttachCurrentThread(&env, NULL);

      // Get the JNI env for this thread
      if ((res < 0) || !env) {
        WEBRTC_TRACE(kTraceError,
                     kTraceVideoRenderer,
                     _id,
                     "%s: Could not attach thread to JVM (%d, %p)",
                     __FUNCTION__,
                     res,
                     env);
        env=NULL;
      }
      else {
        isAttached = true;
      }
    }
    env->DeleteGlobalRef(_javaRenderObj);
    env->DeleteGlobalRef(_javaRenderClass);

    if (isAttached) {
      if (g_jvm->DetachCurrentThread() < 0) {
        WEBRTC_TRACE(kTraceWarning,
                     kTraceVideoRenderer,
                     _id,
                     "%s: Could not detach thread from JVM",
                     __FUNCTION__);
      }
    }
  }
}

int32_t AndroidSurfaceViewRenderer::Init() {
  WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "%s", __FUNCTION__);
  if (!g_jvm) {
    WEBRTC_TRACE(kTraceError,
                 kTraceVideoRenderer,
                 _id,
                 "(%s): Not a valid Java VM pointer.",
                 __FUNCTION__);
    return -1;
  }
  if(!_ptrWindow) {
    WEBRTC_TRACE(kTraceWarning,
                 kTraceVideoRenderer,
                 _id,
                 "(%s): No window have been provided.",
                 __FUNCTION__);
    return -1;
  }

  // get the JNI env for this thread
  bool isAttached = false;
  JNIEnv* env = NULL;
  if (g_jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
    // try to attach the thread and get the env
    // Attach this thread to JVM
    jint res = g_jvm->AttachCurrentThread(&env, NULL);

    // Get the JNI env for this thread
    if ((res < 0) || !env) {
      WEBRTC_TRACE(kTraceError,
                   kTraceVideoRenderer,
                   _id,
                   "%s: Could not attach thread to JVM (%d, %p)",
                   __FUNCTION__,
                   res,
                   env);
      return -1;
    }
    isAttached = true;
  }

  // get the ViESurfaceRender class
  jclass javaRenderClassLocal =
      env->FindClass("org/webrtc/videoengine/ViESurfaceRenderer");
  if (!javaRenderClassLocal) {
    WEBRTC_TRACE(kTraceError,
                 kTraceVideoRenderer,
                 _id,
                 "%s: could not find ViESurfaceRenderer",
                 __FUNCTION__);
    return -1;
  }

  // create a global reference to the class (to tell JNI that
  // we are referencing it after this function has returned)
  _javaRenderClass =
      reinterpret_cast<jclass>(env->NewGlobalRef(javaRenderClassLocal));
  if (!_javaRenderClass) {
    WEBRTC_TRACE(kTraceError,
                 kTraceVideoRenderer,
                 _id,
                 "%s: could not create Java ViESurfaceRenderer class reference",
                 __FUNCTION__);
    return -1;
  }

  // Delete local class ref, we only use the global ref
  env->DeleteLocalRef(javaRenderClassLocal);

  // get the method ID for the constructor
  jmethodID cid = env->GetMethodID(_javaRenderClass,
                                   "<init>",
                                   "(Landroid/view/SurfaceView;)V");
  if (cid == NULL) {
    WEBRTC_TRACE(kTraceError,
                 kTraceVideoRenderer,
                 _id,
                 "%s: could not get constructor ID",
                 __FUNCTION__);
    return -1; /* exception thrown */
  }

  // construct the object
  jobject javaRenderObjLocal = env->NewObject(_javaRenderClass,
                                              cid,
                                              _ptrWindow);
  if (!javaRenderObjLocal) {
    WEBRTC_TRACE(kTraceError,
                 kTraceVideoRenderer,
                 _id,
                 "%s: could not create Java Render",
                 __FUNCTION__);
    return -1;
  }

  // create a reference to the object (to tell JNI that we are referencing it
  // after this function has returned)
  _javaRenderObj = env->NewGlobalRef(javaRenderObjLocal);
  if (!_javaRenderObj) {
    WEBRTC_TRACE(kTraceError,
                 kTraceVideoRenderer,
                 _id,
                 "%s: could not create Java SurfaceRender object reference",
                 __FUNCTION__);
    return -1;
  }

  // Detach this thread if it was attached
  if (isAttached) {
    if (g_jvm->DetachCurrentThread() < 0) {
      WEBRTC_TRACE(kTraceWarning,
                   kTraceVideoRenderer,
                   _id,
                   "%s: Could not detach thread from JVM", __FUNCTION__);
    }
  }

  WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "%s done", __FUNCTION__);
  return 0;
}

AndroidStream*
AndroidSurfaceViewRenderer::CreateAndroidRenderChannel(
    int32_t streamId,
    int32_t zOrder,
    const float left,
    const float top,
    const float right,
    const float bottom,
    VideoRenderAndroid& renderer) {
  WEBRTC_TRACE(kTraceDebug,
               kTraceVideoRenderer,
               _id,
               "%s: Id %d",
               __FUNCTION__,
               streamId);
  AndroidSurfaceViewChannel* stream =
      new AndroidSurfaceViewChannel(streamId, g_jvm, renderer, _javaRenderObj);
  if(stream && stream->Init(zOrder, left, top, right, bottom) == 0)
    return stream;
  else
    delete stream;
  return NULL;
}

AndroidSurfaceViewChannel::AndroidSurfaceViewChannel(
    uint32_t streamId,
    JavaVM* jvm,
    VideoRenderAndroid& renderer,
    jobject javaRenderObj) :
    _id(streamId),
    _renderCritSect(*CriticalSectionWrapper::CreateCriticalSection()),
    _renderer(renderer),
    _jvm(jvm),
    _javaRenderObj(javaRenderObj),
#ifndef ANDROID_NDK_8_OR_ABOVE
    _javaByteBufferObj(NULL),
    _directBuffer(NULL),
#endif
    _bitmapWidth(0),
    _bitmapHeight(0) {
}

AndroidSurfaceViewChannel::~AndroidSurfaceViewChannel() {
  WEBRTC_TRACE(kTraceInfo,
               kTraceVideoRenderer,
               _id,
               "AndroidSurfaceViewChannel dtor");
  delete &_renderCritSect;
  if(_jvm) {
    // get the JNI env for this thread
    bool isAttached = false;
    JNIEnv* env = NULL;
    if ( _jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
      // try to attach the thread and get the env
      // Attach this thread to JVM
      jint res = _jvm->AttachCurrentThread(&env, NULL);

      // Get the JNI env for this thread
      if ((res < 0) || !env) {
        WEBRTC_TRACE(kTraceError,
                     kTraceVideoRenderer,
                     _id,
                     "%s: Could not attach thread to JVM (%d, %p)",
                     __FUNCTION__,
                     res,
                     env);
        env=NULL;
      }
      else {
        isAttached = true;
      }
    }

    env->DeleteGlobalRef(_javaByteBufferObj);
    if (isAttached) {
      if (_jvm->DetachCurrentThread() < 0) {
        WEBRTC_TRACE(kTraceWarning,
                     kTraceVideoRenderer,
                     _id,
                     "%s: Could not detach thread from JVM",
                     __FUNCTION__);
      }
    }
  }
}

int32_t AndroidSurfaceViewChannel::Init(
    int32_t /*zOrder*/,
    const float left,
    const float top,
    const float right,
    const float bottom) {

  WEBRTC_TRACE(kTraceDebug,
               kTraceVideoRenderer,
               _id,
               "%s: AndroidSurfaceViewChannel",
               __FUNCTION__);
  if (!_jvm) {
    WEBRTC_TRACE(kTraceError,
                 kTraceVideoRenderer,
                 _id,
                 "%s: Not a valid Java VM pointer",
                 __FUNCTION__);
    return -1;
  }

  if( (top > 1 || top < 0) ||
      (right > 1 || right < 0) ||
      (bottom > 1 || bottom < 0) ||
      (left > 1 || left < 0)) {
    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                 "%s: Wrong coordinates", __FUNCTION__);
    return -1;
  }

  // get the JNI env for this thread
  bool isAttached = false;
  JNIEnv* env = NULL;
  if (_jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
    // try to attach the thread and get the env
    // Attach this thread to JVM
    jint res = _jvm->AttachCurrentThread(&env, NULL);

    // Get the JNI env for this thread
    if ((res < 0) || !env) {
      WEBRTC_TRACE(kTraceError,
                   kTraceVideoRenderer,
                   _id,
                   "%s: Could not attach thread to JVM (%d, %p)",
                   __FUNCTION__,
                   res,
                   env);
      return -1;
    }
    isAttached = true;
  }

  jclass javaRenderClass =
      env->FindClass("org/webrtc/videoengine/ViESurfaceRenderer");
  if (!javaRenderClass) {
    WEBRTC_TRACE(kTraceError,
                 kTraceVideoRenderer,
                 _id,
                 "%s: could not find ViESurfaceRenderer",
                 __FUNCTION__);
    return -1;
  }

  // get the method ID for the CreateIntArray
  _createByteBufferCid =
      env->GetMethodID(javaRenderClass,
                       "CreateByteBuffer",
                       "(II)Ljava/nio/ByteBuffer;");
  if (_createByteBufferCid == NULL) {
    WEBRTC_TRACE(kTraceError,
                 kTraceVideoRenderer,
                 _id,
                 "%s: could not get CreateByteBuffer ID",
                 __FUNCTION__);
    return -1; /* exception thrown */
  }

  // get the method ID for the DrawByteBuffer function
  _drawByteBufferCid = env->GetMethodID(javaRenderClass,
                                        "DrawByteBuffer",
                                        "()V");
  if (_drawByteBufferCid == NULL) {
    WEBRTC_TRACE(kTraceError,
                 kTraceVideoRenderer,
                 _id,
                 "%s: could not get DrawByteBuffer ID",
                 __FUNCTION__);
    return -1; /* exception thrown */
  }

  // get the method ID for the SetCoordinates function
  _setCoordinatesCid = env->GetMethodID(javaRenderClass,
                                        "SetCoordinates",
                                        "(FFFF)V");
  if (_setCoordinatesCid == NULL) {
    WEBRTC_TRACE(kTraceError,
                 kTraceVideoRenderer,
                 _id,
                 "%s: could not get SetCoordinates ID",
                 __FUNCTION__);
    return -1; /* exception thrown */
  }

  env->CallVoidMethod(_javaRenderObj, _setCoordinatesCid,
                      left, top, right, bottom);

  // Detach this thread if it was attached
  if (isAttached) {
    if (_jvm->DetachCurrentThread() < 0) {
      WEBRTC_TRACE(kTraceWarning,
                   kTraceVideoRenderer,
                   _id,
                   "%s: Could not detach thread from JVM",
                   __FUNCTION__);
    }
  }

  WEBRTC_TRACE(kTraceDebug,
               kTraceVideoRenderer,
               _id,
               "%s: AndroidSurfaceViewChannel done",
               __FUNCTION__);
  return 0;
}

int32_t AndroidSurfaceViewChannel::RenderFrame(const uint32_t /*streamId*/,
                                               const VideoFrame& videoFrame) {
  // WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer,_id, "%s:" ,__FUNCTION__);
  _renderCritSect.Enter();
  _bufferToRender = videoFrame;
  _renderCritSect.Leave();
  _renderer.ReDraw();
  return 0;
}


/*Implements AndroidStream
 * Calls the Java object and render the buffer in _bufferToRender
 */
void AndroidSurfaceViewChannel::DeliverFrame(JNIEnv* jniEnv) {
  _renderCritSect.Enter();

  if (_bitmapWidth != _bufferToRender.width() ||
      _bitmapHeight != _bufferToRender.height()) {
    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s: New render size %d "
                 "%d",__FUNCTION__,
                 _bufferToRender.width(), _bufferToRender.height());
    if (_javaByteBufferObj) {
      jniEnv->DeleteGlobalRef(_javaByteBufferObj);
      _javaByteBufferObj = NULL;
      _directBuffer = NULL;
    }

    jobject javaByteBufferObj =
        jniEnv->CallObjectMethod(_javaRenderObj, _createByteBufferCid,
                                 _bufferToRender.width(),
                                 _bufferToRender.height());
    _javaByteBufferObj = jniEnv->NewGlobalRef(javaByteBufferObj);
    if (!_javaByteBufferObj) {
      WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,  "%s: could not "
                   "create Java ByteBuffer object reference", __FUNCTION__);
      _renderCritSect.Leave();
      return;
    } else {
      _directBuffer = static_cast<unsigned char*>
          (jniEnv->GetDirectBufferAddress(_javaByteBufferObj));
      _bitmapWidth = _bufferToRender.width();
      _bitmapHeight = _bufferToRender.height();
    }
  }

  if(_javaByteBufferObj && _bitmapWidth && _bitmapHeight) {
    const int conversionResult =
        ConvertFromI420(_bufferToRender, kRGB565, 0, _directBuffer);

    if (conversionResult < 0)  {
      WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, "%s: Color conversion"
                   " failed.", __FUNCTION__);
      _renderCritSect.Leave();
      return;
    }
  }
  _renderCritSect.Leave();
  // Draw the Surface
  jniEnv->CallVoidMethod(_javaRenderObj, _drawByteBufferCid);
}

}  // namespace webrtc
