/*
 *  Copyright (c) 2011 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 "video_render_android_surface_view.h"
#include "critical_section_wrapper.h"
#include "common_video/libyuv/include/libyuv.h"
#include "tick_util.h"
#ifdef ANDROID_NDK_8_OR_ABOVE
    #include <android/bitmap.h>
#endif


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

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

namespace webrtc {

AndroidSurfaceViewRenderer::AndroidSurfaceViewRenderer(const WebRtc_Word32 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__);
            }
        }
    }
}


WebRtc_Word32 
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(WebRtc_Word32 streamId,
                WebRtc_Word32 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(WebRtc_UWord32 streamId,JavaVM* jvm,VideoRenderAndroid& renderer,jobject javaRenderObj)
:
_id(streamId),
_renderCritSect(*CriticalSectionWrapper::CreateCriticalSection()),
_renderer(renderer),
_jvm(jvm),
_javaRenderObj(javaRenderObj),
_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;
            }
        }

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

WebRtc_Word32
AndroidSurfaceViewChannel::Init(WebRtc_Word32 /*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;
    }
#ifdef ANDROID_NDK_8_OR_ABOVE
    // get the method ID for the CreateBitmap
    _createBitmapCid = env->GetMethodID(_javaRenderClass, "CreateBitmap", "(II)Landroid/graphics/Bitmap;");
    if (_createBitmapCid == NULL)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,  "%s: could not get CreateBitmap ID", __FUNCTION__);
        return -1; /* exception thrown */
    }
    // get the method ID for the DrawBitmap function
    _drawBitmapCid = env->GetMethodID(_javaRenderClass, "DrawBitmap", "()V");
    if (_drawBitmapCid == NULL)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,  "%s: could not get DrawBitmap ID", __FUNCTION__);
        return -1; /* exception thrown */
    }
#else
    // 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 */
    }
#endif

    // 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;
}


WebRtc_Word32 AndroidSurfaceViewChannel::RenderFrame(const WebRtc_UWord32 /*streamId*/, VideoFrame& videoFrame)
{
 //   WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer,_id, "%s:" ,__FUNCTION__);
    _renderCritSect.Enter();
    _bufferToRender.SwapFrame(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();

#ifdef ANDROID_NDK_8_OR_ABOVE
  if (_bitmapWidth != _bufferToRender.Width() ||
    _bitmapHeight != _bufferToRender.Height()) {
    // Create the bitmap to write to
    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s: Creating bitmap %u "
                 "%u", __FUNCTION__, _bufferToRender.Width(),
                 _bufferToRender.Height());
    if (_javaBitmapObj) {
      jniEnv->DeleteGlobalRef(_javaBitmapObj);
     _javaBitmapObj = NULL;
    }
    jobject javaBitmap = jniEnv->CallObjectMethod(_javaRenderObj,
                                                  _createBitmapCid,
                                                  videoFrame.Width(),
                                                  videoFrame.Height());
    _javaBitmapObj = jniEnv->NewGlobalRef(javaBitmap);
     if (!_javaBitmapObj) {
       WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, "%s: could not "
                    "create Java Bitmap object reference", __FUNCTION__);
       _renderCritSect.Leave();
       return;
    } else {
      _bitmapWidth=_bufferToRender.Width();
      _bitmapHeight=_bufferToRender.Height();
    }
  }
  void* pixels;
  if (_javaBitmapObj &&
      AndroidBitmap_lockPixels(jniEnv, _javaBitmapObj, &pixels) >= 0) {
    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s: Locked bitmap",
                 __FUNCTION__);
    // Convert I420 straight into the Java bitmap.
    int ret = ConvertI420ToRGB565((unsigned char* )_bufferToRender.Buffer(),
                                  (unsigned char* ) pixels,
                                  _bitmapWidth, _bitmapHeight);
    if (ret < 0) {
      WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, "%s: Color conversion "
                   "failed.", __FUNCTION__);
    }

    AndroidBitmap_unlockPixels(jniEnv, _javaBitmapObj);
    // Draw the Surface.
    jniEnv->CallVoidMethod(_javaRenderObj,_drawCid);

  } else {
    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, "%s: Could not lock "
                 "bitmap", __FUNCTION__);
  }
  _renderCritSect.Leave();

#else
  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) {
    // Android requires a vertically flipped image compared to std convert.
    // This is done by giving a negative height input.
    const int conversionResult =
      ConvertI420ToRGB565((unsigned char* )_bufferToRender.Buffer(),
                          _directBuffer, _bitmapWidth, -_bitmapHeight);
    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);
#endif
}

}  // namespace webrtc

