/*
 *  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/engine_configurations.h"
#if defined(COCOA_RENDERING)

#include "webrtc/base/platform_thread.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/modules/video_render/mac/video_render_nsopengl.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"
#include "webrtc/system_wrappers/include/trace.h"

namespace webrtc {

VideoChannelNSOpenGL::VideoChannelNSOpenGL(NSOpenGLContext *nsglContext, int iId, VideoRenderNSOpenGL* owner) :
_nsglContext( nsglContext),
_id( iId),
_owner( owner),
_width( 0),
_height( 0),
_startWidth( 0.0f),
_startHeight( 0.0f),
_stopWidth( 0.0f),
_stopHeight( 0.0f),
_stretchedWidth( 0),
_stretchedHeight( 0),
_oldStretchedHeight( 0),
_oldStretchedWidth( 0),
_buffer( 0),
_bufferSize( 0),
_incomingBufferSize( 0),
_bufferIsUpdated( false),
_numberOfStreams( 0),
_pixelFormat( GL_RGBA),
_pixelDataType( GL_UNSIGNED_INT_8_8_8_8),
_texture( 0)
{

}

VideoChannelNSOpenGL::~VideoChannelNSOpenGL()
{
    if (_buffer)
    {
        delete [] _buffer;
        _buffer = NULL;
    }

    if (_texture != 0)
    {
        [_nsglContext makeCurrentContext];
        glDeleteTextures(1, (const GLuint*) &_texture);
        _texture = 0;
    }
}

int VideoChannelNSOpenGL::ChangeContext(NSOpenGLContext *nsglContext)
{
    _owner->LockAGLCntx();

    _nsglContext = nsglContext;
    [_nsglContext makeCurrentContext];

    _owner->UnlockAGLCntx();
    return 0;

}

int32_t VideoChannelNSOpenGL::GetChannelProperties(float& left, float& top,
                                                   float& right, float& bottom)
{

    _owner->LockAGLCntx();

    left = _startWidth;
    top = _startHeight;
    right = _stopWidth;
    bottom = _stopHeight;

    _owner->UnlockAGLCntx();
    return 0;
}

int32_t VideoChannelNSOpenGL::RenderFrame(const uint32_t /*streamId*/,
                                          const VideoFrame& videoFrame) {
  _owner->LockAGLCntx();

  if(_width != videoFrame.width() ||
     _height != videoFrame.height()) {
      if(FrameSizeChange(videoFrame.width(), videoFrame.height(), 1) == -1) {
        _owner->UnlockAGLCntx();
        return -1;
      }
  }
  int ret = DeliverFrame(videoFrame);

  _owner->UnlockAGLCntx();
  return ret;
}

int VideoChannelNSOpenGL::UpdateSize(int width, int height)
{
    _owner->LockAGLCntx();
    _width = width;
    _height = height;
    _owner->UnlockAGLCntx();
    return 0;
}

int VideoChannelNSOpenGL::UpdateStretchSize(int stretchHeight, int stretchWidth)
{

    _owner->LockAGLCntx();
    _stretchedHeight = stretchHeight;
    _stretchedWidth = stretchWidth;
    _owner->UnlockAGLCntx();
    return 0;
}

int VideoChannelNSOpenGL::FrameSizeChange(int width, int height, int numberOfStreams)
{
    //  We got a new frame size from VideoAPI, prepare the buffer

    _owner->LockAGLCntx();

    if (width == _width && _height == height)
    {
        // We already have a correct buffer size
        _numberOfStreams = numberOfStreams;
        _owner->UnlockAGLCntx();
        return 0;
    }

    _width = width;
    _height = height;

    // Delete the old buffer, create a new one with correct size.
    if (_buffer)
    {
        delete [] _buffer;
        _bufferSize = 0;
    }

    _incomingBufferSize = CalcBufferSize(kI420, _width, _height);
    _bufferSize = CalcBufferSize(kARGB, _width, _height);
    _buffer = new unsigned char [_bufferSize];
    memset(_buffer, 0, _bufferSize * sizeof(unsigned char));

    [_nsglContext makeCurrentContext];

    if(glIsTexture(_texture))
    {
        glDeleteTextures(1, (const GLuint*) &_texture);
        _texture = 0;
    }

    // Create a new texture
    glGenTextures(1, (GLuint *) &_texture);

    GLenum glErr = glGetError();

    if (glErr != GL_NO_ERROR)
    {

    }

    glBindTexture(GL_TEXTURE_RECTANGLE_EXT, _texture);

    GLint texSize;
    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);

    if (texSize < _width || texSize < _height)
    {
        _owner->UnlockAGLCntx();
        return -1;
    }

    // Set up th texture type and size
    glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, // target
            0, // level
            GL_RGBA, // internal format
            _width, // width
            _height, // height
            0, // border 0/1 = off/on
            _pixelFormat, // format, GL_RGBA
            _pixelDataType, // data type, GL_UNSIGNED_INT_8_8_8_8
            _buffer); // pixel data

    glErr = glGetError();
    if (glErr != GL_NO_ERROR)
    {
        _owner->UnlockAGLCntx();
        return -1;
    }

    _owner->UnlockAGLCntx();
    return 0;
}

int VideoChannelNSOpenGL::DeliverFrame(const VideoFrame& videoFrame) {
  _owner->LockAGLCntx();

  if (_texture == 0) {
    _owner->UnlockAGLCntx();
    return 0;
  }

  if (CalcBufferSize(kI420, videoFrame.width(), videoFrame.height()) !=
      _incomingBufferSize) {
    _owner->UnlockAGLCntx();
    return -1;
  }

  // Using the VideoFrame for YV12: YV12 is YVU; I420 assumes
  // YUV.
  // TODO(mikhal) : Use appropriate functionality.
  // TODO(wu): See if we are using glTexSubImage2D correctly.
  int rgbRet = ConvertFromYV12(videoFrame, kBGRA, 0, _buffer);
  if (rgbRet < 0) {
    _owner->UnlockAGLCntx();
    return -1;
  }

  [_nsglContext makeCurrentContext];

  // Make sure this texture is the active one
  glBindTexture(GL_TEXTURE_RECTANGLE_EXT, _texture);
  GLenum glErr = glGetError();
  if (glErr != GL_NO_ERROR) {
    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    "ERROR %d while calling glBindTexture", glErr);
    _owner->UnlockAGLCntx();
    return -1;
  }

  glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT,
                  0, // Level, not use
                  0, // start point x, (low left of pic)
                  0, // start point y,
                  _width, // width
                  _height, // height
                  _pixelFormat, // pictue format for _buffer
                  _pixelDataType, // data type of _buffer
                  (const GLvoid*) _buffer); // the pixel data

  glErr = glGetError();
  if (glErr != GL_NO_ERROR) {
    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
    "ERROR %d while calling glTexSubImage2d", glErr);
    _owner->UnlockAGLCntx();
    return -1;
  }

  _bufferIsUpdated = true;

  _owner->UnlockAGLCntx();
  return 0;
}

int VideoChannelNSOpenGL::RenderOffScreenBuffer()
{

    _owner->LockAGLCntx();

    if (_texture == 0)
    {
        _owner->UnlockAGLCntx();
        return 0;
    }

    //	if(_fullscreen)
    //	{
    // NSRect mainDisplayRect = [[NSScreen mainScreen] frame];
    //		_width = mainDisplayRect.size.width;
    //		_height = mainDisplayRect.size.height;
    //		glViewport(0, 0, mainDisplayRect.size.width, mainDisplayRect.size.height);
    //		float newX = mainDisplayRect.size.width/_width;
    //		float newY = mainDisplayRect.size.height/_height;

    // convert from 0.0 <= size <= 1.0 to
    // open gl world -1.0 < size < 1.0
    GLfloat xStart = 2.0f * _startWidth - 1.0f;
    GLfloat xStop = 2.0f * _stopWidth - 1.0f;
    GLfloat yStart = 1.0f - 2.0f * _stopHeight;
    GLfloat yStop = 1.0f - 2.0f * _startHeight;

    [_nsglContext makeCurrentContext];

    glBindTexture(GL_TEXTURE_RECTANGLE_EXT, _texture);
    _oldStretchedHeight = _stretchedHeight;
    _oldStretchedWidth = _stretchedWidth;

    glLoadIdentity();
    glEnable(GL_TEXTURE_RECTANGLE_EXT);
    glBegin(GL_POLYGON);
    {
        glTexCoord2f(0.0, 0.0); glVertex2f(xStart, yStop);
        glTexCoord2f(_width, 0.0); glVertex2f(xStop, yStop);
        glTexCoord2f(_width, _height); glVertex2f(xStop, yStart);
        glTexCoord2f(0.0, _height); glVertex2f(xStart, yStart);
    }
    glEnd();

    glDisable(GL_TEXTURE_RECTANGLE_EXT);

    _bufferIsUpdated = false;

    _owner->UnlockAGLCntx();
    return 0;
}

int VideoChannelNSOpenGL::IsUpdated(bool& isUpdated)
{
    _owner->LockAGLCntx();

    isUpdated = _bufferIsUpdated;

    _owner->UnlockAGLCntx();
    return 0;
}

int VideoChannelNSOpenGL::SetStreamSettings(int /*streamId*/, float startWidth, float startHeight, float stopWidth, float stopHeight)
{
    _owner->LockAGLCntx();

    _startWidth = startWidth;
    _stopWidth = stopWidth;
    _startHeight = startHeight;
    _stopHeight = stopHeight;

    int oldWidth = _width;
    int oldHeight = _height;
    int oldNumberOfStreams = _numberOfStreams;

    _width = 0;
    _height = 0;

    int retVal = FrameSizeChange(oldWidth, oldHeight, oldNumberOfStreams);

    _owner->UnlockAGLCntx();
    return retVal;
}

int VideoChannelNSOpenGL::SetStreamCropSettings(int /*streamId*/, float /*startWidth*/, float /*startHeight*/, float /*stopWidth*/, float /*stopHeight*/)
{
    return -1;
}

/*
 *
 *    VideoRenderNSOpenGL
 *
 */

VideoRenderNSOpenGL::VideoRenderNSOpenGL(CocoaRenderView *windowRef, bool fullScreen, int iId) :
_windowRef( (CocoaRenderView*)windowRef),
_fullScreen( fullScreen),
_id( iId),
_nsglContextCritSec( *CriticalSectionWrapper::CreateCriticalSection()),
_screenUpdateEvent(EventTimerWrapper::Create()),
_nsglContext( 0),
_nsglFullScreenContext( 0),
_fullScreenWindow( nil),
_windowRect( ),
_windowWidth( 0),
_windowHeight( 0),
_nsglChannels( ),
_zOrderToChannel( ),
_renderingIsPaused (FALSE),
_windowRefSuperView(NULL),
_windowRefSuperViewFrame(NSMakeRect(0,0,0,0))
{
  _screenUpdateThread = PlatformThread::CreateThread(
      ScreenUpdateThreadProc, this, "ScreenUpdateNSOpenGL");
}

int VideoRenderNSOpenGL::ChangeWindow(CocoaRenderView* newWindowRef)
{

    LockAGLCntx();

    _windowRef = newWindowRef;

    if(CreateMixingContext() == -1)
    {
        UnlockAGLCntx();
        return -1;
    }

    int error = 0;
    std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.begin();
    while (it!= _nsglChannels.end())
    {
        error |= (it->second)->ChangeContext(_nsglContext);
        it++;
    }
    if(error != 0)
    {
        UnlockAGLCntx();
        return -1;
    }

    UnlockAGLCntx();
    return 0;
}

/* Check if the thread and event already exist.
 * If so then they will simply be restarted
 * If not then create them and continue
 */
int32_t VideoRenderNSOpenGL::StartRender()
{

    LockAGLCntx();

    const unsigned int MONITOR_FREQ = 60;
    if(TRUE == _renderingIsPaused)
    {
        WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "Restarting screenUpdateThread");

        // we already have the thread. Most likely StopRender() was called and they were paused
        if(FALSE == _screenUpdateThread->Start() ||
                FALSE == _screenUpdateEvent->StartTimer(true, 1000/MONITOR_FREQ))
        {
            WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, "Failed to restart screenUpdateThread or screenUpdateEvent");
            UnlockAGLCntx();
            return -1;
        }

        _screenUpdateThread->SetPriority(kRealtimePriority);

        UnlockAGLCntx();
        return 0;
    }


    if (!_screenUpdateThread)
    {
        WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "failed start screenUpdateThread");
        UnlockAGLCntx();
        return -1;
    }


    UnlockAGLCntx();
    return 0;
}
int32_t VideoRenderNSOpenGL::StopRender()
{

    LockAGLCntx();

    /* The code below is functional
     * but it pauses for several seconds
     */

    // pause the update thread and the event timer
    if(!_screenUpdateThread || !_screenUpdateEvent)
    {
        _renderingIsPaused = TRUE;

        UnlockAGLCntx();
        return 0;
    }

    if(FALSE == _screenUpdateThread->Stop() || FALSE == _screenUpdateEvent->StopTimer())
    {
        _renderingIsPaused = FALSE;

        UnlockAGLCntx();
        return -1;
    }

    _renderingIsPaused = TRUE;

    UnlockAGLCntx();
    return 0;
}

int VideoRenderNSOpenGL::configureNSOpenGLView()
{
    return 0;

}

int VideoRenderNSOpenGL::configureNSOpenGLEngine()
{

    LockAGLCntx();

    // Disable not needed functionality to increase performance
    glDisable(GL_DITHER);
    glDisable(GL_ALPHA_TEST);
    glDisable(GL_STENCIL_TEST);
    glDisable(GL_FOG);
    glDisable(GL_TEXTURE_2D);
    glPixelZoom(1.0, 1.0);
    glDisable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
    glDepthMask(GL_FALSE);
    glDisable(GL_CULL_FACE);

    // Set texture parameters
    glTexParameterf(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_PRIORITY, 1.0);
    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE);

    if (GetWindowRect(_windowRect) == -1)
    {
        UnlockAGLCntx();
        return true;
    }

    if (_windowWidth != (_windowRect.right - _windowRect.left)
            || _windowHeight != (_windowRect.bottom - _windowRect.top))
    {
        _windowWidth = _windowRect.right - _windowRect.left;
        _windowHeight = _windowRect.bottom - _windowRect.top;
    }
    glViewport(0, 0, _windowWidth, _windowHeight);

    // Synchronize buffer swaps with vertical refresh rate
    GLint swapInt = 1;
    [_nsglContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];

    UnlockAGLCntx();
    return 0;
}

int VideoRenderNSOpenGL::setRenderTargetWindow()
{
    LockAGLCntx();


    GLuint attribs[] =
    {
        NSOpenGLPFAColorSize, 24,
        NSOpenGLPFAAlphaSize, 8,
        NSOpenGLPFADepthSize, 16,
        NSOpenGLPFAAccelerated,
        0
    };

    NSOpenGLPixelFormat* fmt = [[[NSOpenGLPixelFormat alloc] initWithAttributes:
                          (NSOpenGLPixelFormatAttribute*) attribs] autorelease];

    if(_windowRef)
    {
        [_windowRef initCocoaRenderView:fmt];
    }
    else
    {
        UnlockAGLCntx();
        return -1;
    }

    _nsglContext = [_windowRef nsOpenGLContext];
    [_nsglContext makeCurrentContext];

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);


    DisplayBuffers();

    UnlockAGLCntx();
    return 0;
}

int VideoRenderNSOpenGL::setRenderTargetFullScreen()
{
    LockAGLCntx();


    GLuint attribs[] =
    {
        NSOpenGLPFAColorSize, 24,
        NSOpenGLPFAAlphaSize, 8,
        NSOpenGLPFADepthSize, 16,
        NSOpenGLPFAAccelerated,
        0
    };

    NSOpenGLPixelFormat* fmt = [[[NSOpenGLPixelFormat alloc] initWithAttributes:
                          (NSOpenGLPixelFormatAttribute*) attribs] autorelease];

    // Store original superview and frame for use when exiting full screens
    _windowRefSuperViewFrame = [_windowRef frame];
    _windowRefSuperView = [_windowRef superview];


    // create new fullscreen window
    NSRect screenRect = [[NSScreen mainScreen]frame];
    [_windowRef setFrame:screenRect];
    [_windowRef setBounds:screenRect];


    _fullScreenWindow = [[CocoaFullScreenWindow alloc]init];
    [_fullScreenWindow grabFullScreen];
    [[[_fullScreenWindow window] contentView] addSubview:_windowRef];

    if(_windowRef)
    {
        [_windowRef initCocoaRenderViewFullScreen:fmt];
    }
    else
    {
        UnlockAGLCntx();
        return -1;
    }

    _nsglContext = [_windowRef nsOpenGLContext];
    [_nsglContext makeCurrentContext];

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    DisplayBuffers();

    UnlockAGLCntx();
    return 0;
}

VideoRenderNSOpenGL::~VideoRenderNSOpenGL()
{

    if(_fullScreen)
    {
        if(_fullScreenWindow)
        {
            // Detach CocoaRenderView from full screen view back to
            // it's original parent.
            [_windowRef removeFromSuperview];
            if(_windowRefSuperView)
            {
              [_windowRefSuperView addSubview:_windowRef];
              [_windowRef setFrame:_windowRefSuperViewFrame];
            }

            WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, 0, "%s:%d Attempting to release fullscreen window", __FUNCTION__, __LINE__);
            [_fullScreenWindow releaseFullScreen];

        }
    }

    // Signal event to exit thread, then delete it
    PlatformThread* tmpPtr = _screenUpdateThread.release();

    if (tmpPtr)
    {
        _screenUpdateEvent->Set();
        _screenUpdateEvent->StopTimer();

        if (tmpPtr->Stop())
        {
            delete tmpPtr;
        }
        delete _screenUpdateEvent;
        _screenUpdateEvent = NULL;
    }

    if (_nsglContext != 0)
    {
        [_nsglContext makeCurrentContext];
        _nsglContext = nil;
    }

    // Delete all channels
    std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.begin();
    while (it!= _nsglChannels.end())
    {
        delete it->second;
        _nsglChannels.erase(it);
        it = _nsglChannels.begin();
    }
    _nsglChannels.clear();

    // Clean the zOrder map
    std::multimap<int, int>::iterator zIt = _zOrderToChannel.begin();
    while(zIt != _zOrderToChannel.end())
    {
        _zOrderToChannel.erase(zIt);
        zIt = _zOrderToChannel.begin();
    }
    _zOrderToChannel.clear();

}

/* static */
int VideoRenderNSOpenGL::GetOpenGLVersion(int& /*nsglMajor*/, int& /*nsglMinor*/)
{
    return -1;
}

int VideoRenderNSOpenGL::Init()
{

    LockAGLCntx();
    if (!_screenUpdateThread)
    {
        UnlockAGLCntx();
        return -1;
    }

    _screenUpdateThread->Start();
    _screenUpdateThread->SetPriority(kRealtimePriority);

    // Start the event triggering the render process
    unsigned int monitorFreq = 60;
    _screenUpdateEvent->StartTimer(true, 1000/monitorFreq);

    if (CreateMixingContext() == -1)
    {
        UnlockAGLCntx();
        return -1;
    }

    UnlockAGLCntx();
    return 0;
}

VideoChannelNSOpenGL* VideoRenderNSOpenGL::CreateNSGLChannel(int channel, int zOrder, float startWidth, float startHeight, float stopWidth, float stopHeight)
{
    CriticalSectionScoped cs(&_nsglContextCritSec);

    if (HasChannel(channel))
    {
        return NULL;
    }

    if (_zOrderToChannel.find(zOrder) != _zOrderToChannel.end())
    {

    }

    VideoChannelNSOpenGL* newAGLChannel = new VideoChannelNSOpenGL(_nsglContext, _id, this);
    if (newAGLChannel->SetStreamSettings(0, startWidth, startHeight, stopWidth, stopHeight) == -1)
    {
        if (newAGLChannel)
        {
            delete newAGLChannel;
            newAGLChannel = NULL;
        }

        return NULL;
    }

    _nsglChannels[channel] = newAGLChannel;
    _zOrderToChannel.insert(std::pair<int, int>(zOrder, channel));

    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s successfully created NSGL channel number %d", __FUNCTION__, channel);

    return newAGLChannel;
}

int VideoRenderNSOpenGL::DeleteAllNSGLChannels()
{

    CriticalSectionScoped cs(&_nsglContextCritSec);

    std::map<int, VideoChannelNSOpenGL*>::iterator it;
    it = _nsglChannels.begin();

    while (it != _nsglChannels.end())
    {
        VideoChannelNSOpenGL* channel = it->second;
        WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s Deleting channel %d", __FUNCTION__, channel);
        delete channel;
        it++;
    }
    _nsglChannels.clear();
    return 0;
}

int32_t VideoRenderNSOpenGL::DeleteNSGLChannel(const uint32_t channel)
{

    CriticalSectionScoped cs(&_nsglContextCritSec);

    std::map<int, VideoChannelNSOpenGL*>::iterator it;
    it = _nsglChannels.find(channel);
    if (it != _nsglChannels.end())
    {
        delete it->second;
        _nsglChannels.erase(it);
    }
    else
    {
        return -1;
    }

    std::multimap<int, int>::iterator zIt = _zOrderToChannel.begin();
    while( zIt != _zOrderToChannel.end())
    {
        if (zIt->second == (int)channel)
        {
            _zOrderToChannel.erase(zIt);
            break;
        }
        zIt++;
    }

    return 0;
}

int32_t VideoRenderNSOpenGL::GetChannelProperties(const uint16_t streamId,
                                                  uint32_t& zOrder,
                                                  float& left,
                                                  float& top,
                                                  float& right,
                                                  float& bottom)
{

    CriticalSectionScoped cs(&_nsglContextCritSec);

    bool channelFound = false;

    // Loop through all channels until we find a match.
    // From that, get zorder.
    // From that, get T, L, R, B
    for (std::multimap<int, int>::reverse_iterator rIt = _zOrderToChannel.rbegin();
            rIt != _zOrderToChannel.rend();
            rIt++)
    {
        if(streamId == rIt->second)
        {
            channelFound = true;

            zOrder = rIt->second;

            std::map<int, VideoChannelNSOpenGL*>::iterator rIt = _nsglChannels.find(streamId);
            VideoChannelNSOpenGL* tempChannel = rIt->second;

            if(-1 == tempChannel->GetChannelProperties(left, top, right, bottom) )
            {
                return -1;
            }
            break;
        }
    }

    if(false == channelFound)
    {

        return -1;
    }

    return 0;
}

int VideoRenderNSOpenGL::StopThread()
{

    PlatformThread* tmpPtr = _screenUpdateThread.release();
    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id,
                 "%s Stopping thread ", __FUNCTION__, tmpPtr);

    if (tmpPtr)
    {
        _screenUpdateEvent->Set();
        if (tmpPtr->Stop())
        {
            delete tmpPtr;
        }
    }

    delete _screenUpdateEvent;
    _screenUpdateEvent = NULL;

    return 0;
}

bool VideoRenderNSOpenGL::IsFullScreen()
{

    CriticalSectionScoped cs(&_nsglContextCritSec);
    return _fullScreen;
}

bool VideoRenderNSOpenGL::HasChannels()
{
    CriticalSectionScoped cs(&_nsglContextCritSec);

    if (_nsglChannels.begin() != _nsglChannels.end())
    {
        return true;
    }
    return false;
}

bool VideoRenderNSOpenGL::HasChannel(int channel)
{

    CriticalSectionScoped cs(&_nsglContextCritSec);

    std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.find(channel);

    if (it != _nsglChannels.end())
    {
        return true;
    }
    return false;
}

int VideoRenderNSOpenGL::GetChannels(std::list<int>& channelList)
{

    CriticalSectionScoped cs(&_nsglContextCritSec);

    std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.begin();

    while (it != _nsglChannels.end())
    {
        channelList.push_back(it->first);
        it++;
    }

    return 0;
}

VideoChannelNSOpenGL* VideoRenderNSOpenGL::ConfigureNSGLChannel(int channel, int zOrder, float startWidth, float startHeight, float stopWidth, float stopHeight)
{

    CriticalSectionScoped cs(&_nsglContextCritSec);

    std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.find(channel);

    if (it != _nsglChannels.end())
    {
        VideoChannelNSOpenGL* aglChannel = it->second;
        if (aglChannel->SetStreamSettings(0, startWidth, startHeight, stopWidth, stopHeight) == -1)
        {
            WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, "%s failed to set stream settings: channel %d. channel=%d zOrder=%d startWidth=%d startHeight=%d stopWidth=%d stopHeight=%d",
                    __FUNCTION__, channel, zOrder, startWidth, startHeight, stopWidth, stopHeight);
            return NULL;
        }
        WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s Configuring channel %d. channel=%d zOrder=%d startWidth=%d startHeight=%d stopWidth=%d stopHeight=%d",
                __FUNCTION__, channel, zOrder, startWidth, startHeight, stopWidth, stopHeight);

        std::multimap<int, int>::iterator it = _zOrderToChannel.begin();
        while(it != _zOrderToChannel.end())
        {
            if (it->second == channel)
            {
                if (it->first != zOrder)
                {
                    _zOrderToChannel.erase(it);
                    _zOrderToChannel.insert(std::pair<int, int>(zOrder, channel));
                }
                break;
            }
            it++;
        }
        return aglChannel;
    }

    return NULL;
}

/*
 *
 *    Rendering process
 *
 */

bool VideoRenderNSOpenGL::ScreenUpdateThreadProc(void* obj)
{
    return static_cast<VideoRenderNSOpenGL*>(obj)->ScreenUpdateProcess();
}

bool VideoRenderNSOpenGL::ScreenUpdateProcess()
{

    _screenUpdateEvent->Wait(10);
    LockAGLCntx();

    if (!_screenUpdateThread)
    {
        WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, _id, "%s no screen update thread", __FUNCTION__);
        UnlockAGLCntx();
        return false;
    }

    [_nsglContext makeCurrentContext];

    if (GetWindowRect(_windowRect) == -1)
    {
        UnlockAGLCntx();
        return true;
    }

    if (_windowWidth != (_windowRect.right - _windowRect.left)
            || _windowHeight != (_windowRect.bottom - _windowRect.top))
    {
        _windowWidth = _windowRect.right - _windowRect.left;
        _windowHeight = _windowRect.bottom - _windowRect.top;
        glViewport(0, 0, _windowWidth, _windowHeight);
    }

    // Check if there are any updated buffers
    bool updated = false;
    std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.begin();
    while (it != _nsglChannels.end())
    {

        VideoChannelNSOpenGL* aglChannel = it->second;
        aglChannel->UpdateStretchSize(_windowHeight, _windowWidth);
        aglChannel->IsUpdated(updated);
        if (updated)
        {
            break;
        }
        it++;
    }

    if (updated)
    {

        // At least on buffers is updated, we need to repaint the texture
        if (RenderOffScreenBuffers() != -1)
        {
            UnlockAGLCntx();
            return true;
        }
    }
    //    }
    UnlockAGLCntx();
    return true;
}

/*
 *
 *    Functions for creating mixing buffers and screen settings
 *
 */

int VideoRenderNSOpenGL::CreateMixingContext()
{

    CriticalSectionScoped cs(&_nsglContextCritSec);

    if(_fullScreen)
    {
        if(-1 == setRenderTargetFullScreen())
        {
            return -1;
        }
    }
    else
    {

        if(-1 == setRenderTargetWindow())
        {
            return -1;
        }
    }

    configureNSOpenGLEngine();

    DisplayBuffers();

    GLenum glErr = glGetError();
    if (glErr)
    {
    }

    return 0;
}

/*
 *
 *    Rendering functions
 *
 */

int VideoRenderNSOpenGL::RenderOffScreenBuffers()
{
    LockAGLCntx();

    // Get the current window size, it might have changed since last render.
    if (GetWindowRect(_windowRect) == -1)
    {
        UnlockAGLCntx();
        return -1;
    }

    [_nsglContext makeCurrentContext];
    glClear(GL_COLOR_BUFFER_BIT);

    // Loop through all channels starting highest zOrder ending with lowest.
    for (std::multimap<int, int>::reverse_iterator rIt = _zOrderToChannel.rbegin();
            rIt != _zOrderToChannel.rend();
            rIt++)
    {
        int channelId = rIt->second;
        std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.find(channelId);

        VideoChannelNSOpenGL* aglChannel = it->second;

        aglChannel->RenderOffScreenBuffer();
    }

    DisplayBuffers();

    UnlockAGLCntx();
    return 0;
}

/*
 *
 * Help functions
 *
 * All help functions assumes external protections
 *
 */

int VideoRenderNSOpenGL::DisplayBuffers()
{

    LockAGLCntx();

    glFinish();
    [_nsglContext flushBuffer];

    WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "%s glFinish and [_nsglContext flushBuffer]", __FUNCTION__);

    UnlockAGLCntx();
    return 0;
}

int VideoRenderNSOpenGL::GetWindowRect(Rect& rect)
{

    CriticalSectionScoped cs(&_nsglContextCritSec);

    if (_windowRef)
    {
        if(_fullScreen)
        {
            NSRect mainDisplayRect = [[NSScreen mainScreen] frame];
            rect.bottom = 0;
            rect.left = 0;
            rect.right = mainDisplayRect.size.width;
            rect.top = mainDisplayRect.size.height;
        }
        else
        {
            rect.top = [_windowRef frame].origin.y;
            rect.left = [_windowRef frame].origin.x;
            rect.bottom = [_windowRef frame].origin.y + [_windowRef frame].size.height;
            rect.right = [_windowRef frame].origin.x + [_windowRef frame].size.width;
        }

        return 0;
    }
    else
    {
        return -1;
    }
}

int32_t VideoRenderNSOpenGL::SetText(const uint8_t /*textId*/,
                                     const uint8_t* /*text*/,
                                     const int32_t /*textLength*/,
                                     const uint32_t /*textColorRef*/,
                                     const uint32_t /*backgroundColorRef*/,
                                     const float /*left*/,
                                     const float /*top*/,
                                     const float /*right*/,
                                     const float /*bottom*/)
{

    return 0;

}

void VideoRenderNSOpenGL::LockAGLCntx()
{
    _nsglContextCritSec.Enter();
}
void VideoRenderNSOpenGL::UnlockAGLCntx()
{
    _nsglContextCritSec.Leave();
}

/*

 bool VideoRenderNSOpenGL::SetFullScreen(bool fullscreen)
 {
 NSRect mainDisplayRect, viewRect;

 // Create a screen-sized window on the display you want to take over
 // Note, mainDisplayRect has a non-zero origin if the key window is on a secondary display
 mainDisplayRect = [[NSScreen mainScreen] frame];
 fullScreenWindow = [[NSWindow alloc] initWithContentRect:mainDisplayRect styleMask:NSBorderlessWindowMask
 backing:NSBackingStoreBuffered defer:YES];

 // Set the window level to be above the menu bar
 [fullScreenWindow setLevel:NSMainMenuWindowLevel+1];

 // Perform any other window configuration you desire
 [fullScreenWindow setOpaque:YES];
 [fullScreenWindow setHidesOnDeactivate:YES];

 // Create a view with a double-buffered OpenGL context and attach it to the window
 // By specifying the non-fullscreen context as the shareContext, we automatically inherit the OpenGL objects (textures, etc) it has defined
 viewRect = NSMakeRect(0.0, 0.0, mainDisplayRect.size.width, mainDisplayRect.size.height);
 fullScreenView = [[MyOpenGLView alloc] initWithFrame:viewRect shareContext:[openGLView openGLContext]];
 [fullScreenWindow setContentView:fullScreenView];

 // Show the window
 [fullScreenWindow makeKeyAndOrderFront:self];

 // Set the scene with the full-screen viewport and viewing transformation
 [scene setViewportRect:viewRect];

 // Assign the view's MainController to self
 [fullScreenView setMainController:self];

 if (!isAnimating) {
 // Mark the view as needing drawing to initalize its contents
 [fullScreenView setNeedsDisplay:YES];
 }
 else {
 // Start playing the animation
 [fullScreenView startAnimation];
 }

 }



 */


}  // namespace webrtc

#endif // COCOA_RENDERING
