/*
 *  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/modules/video_render/mac/cocoa_render_view.h"
#include "webrtc/modules/video_render/mac/video_render_mac_cocoa_impl.h"
#include "webrtc/modules/video_render/mac/video_render_nsopengl.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/trace.h"

namespace webrtc {

VideoRenderMacCocoaImpl::VideoRenderMacCocoaImpl(const int32_t id,
        const VideoRenderType videoRenderType,
        void* window,
        const bool fullscreen) :
_id(id),
_renderMacCocoaCritsect(*CriticalSectionWrapper::CreateCriticalSection()),
_fullScreen(fullscreen),
_ptrWindow(window)
{

    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "Constructor %s:%d", __FUNCTION__, __LINE__);
}

VideoRenderMacCocoaImpl::~VideoRenderMacCocoaImpl()
{
    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "Destructor %s:%d", __FUNCTION__, __LINE__);
    delete &_renderMacCocoaCritsect;
    if (_ptrCocoaRender)
    {
        delete _ptrCocoaRender;
        _ptrCocoaRender = NULL;
    }
}

int32_t
VideoRenderMacCocoaImpl::Init()
{

    CriticalSectionScoped cs(&_renderMacCocoaCritsect);
    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s:%d", __FUNCTION__, __LINE__);

    // cast ptrWindow from void* to CocoaRenderer. Void* was once NSOpenGLView, and CocoaRenderer is NSOpenGLView.
    _ptrCocoaRender = new VideoRenderNSOpenGL((CocoaRenderView*)_ptrWindow, _fullScreen, _id);
    if (!_ptrWindow)
    {
        WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, _id, "Constructor %s:%d", __FUNCTION__, __LINE__);
        return -1;
    }
    int retVal = _ptrCocoaRender->Init();
    if (retVal == -1)
    {
        WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "Failed to init %s:%d", __FUNCTION__, __LINE__);
        return -1;
    }

    return 0;
}

int32_t
VideoRenderMacCocoaImpl::ChangeWindow(void* window)
{

    CriticalSectionScoped cs(&_renderMacCocoaCritsect);
    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s changing ID to ", __FUNCTION__, window);

    if (window == NULL)
    {
        return -1;
    }
    _ptrWindow = window;


    _ptrWindow = window;
    _ptrCocoaRender->ChangeWindow((CocoaRenderView*)_ptrWindow);

    return 0;
}

VideoRenderCallback*
VideoRenderMacCocoaImpl::AddIncomingRenderStream(const uint32_t streamId,
        const uint32_t zOrder,
        const float left,
        const float top,
        const float right,
        const float bottom)
{
    CriticalSectionScoped cs(&_renderMacCocoaCritsect);
    WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "%s", __FUNCTION__);
    VideoChannelNSOpenGL* nsOpenGLChannel = NULL;

    if(!_ptrWindow)
    {
    }

    if(!nsOpenGLChannel)
    {
        nsOpenGLChannel = _ptrCocoaRender->CreateNSGLChannel(streamId, zOrder, left, top, right, bottom);
    }

    return nsOpenGLChannel;

}

int32_t
VideoRenderMacCocoaImpl::DeleteIncomingRenderStream(const uint32_t streamId)
{
    WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "Constructor %s:%d", __FUNCTION__, __LINE__);
    CriticalSectionScoped cs(&_renderMacCocoaCritsect);
    _ptrCocoaRender->DeleteNSGLChannel(streamId);

    return 0;
}

int32_t
VideoRenderMacCocoaImpl::GetIncomingRenderStreamProperties(const uint32_t streamId,
        uint32_t& zOrder,
        float& left,
        float& top,
        float& right,
        float& bottom) const
{
    return _ptrCocoaRender->GetChannelProperties(streamId, zOrder, left, top, right, bottom);
}

int32_t
VideoRenderMacCocoaImpl::StartRender()
{
    return _ptrCocoaRender->StartRender();
}

int32_t
VideoRenderMacCocoaImpl::StopRender()
{
    return _ptrCocoaRender->StopRender();
}

VideoRenderType
VideoRenderMacCocoaImpl::RenderType()
{
    return kRenderCocoa;
}

RawVideoType
VideoRenderMacCocoaImpl::PerferedVideoType()
{
    return kVideoI420;
}

bool
VideoRenderMacCocoaImpl::FullScreen()
{
    return false;
}

int32_t
VideoRenderMacCocoaImpl::GetGraphicsMemory(uint64_t& totalGraphicsMemory,
        uint64_t& availableGraphicsMemory) const
{
    totalGraphicsMemory = 0;
    availableGraphicsMemory = 0;
    return 0;
}

int32_t
VideoRenderMacCocoaImpl::GetScreenResolution(uint32_t& screenWidth,
        uint32_t& screenHeight) const
{
    CriticalSectionScoped cs(&_renderMacCocoaCritsect);
    NSScreen* mainScreen = [NSScreen mainScreen];

    NSRect frame = [mainScreen frame];

    screenWidth = frame.size.width;
    screenHeight = frame.size.height;
    return 0;
}

uint32_t
VideoRenderMacCocoaImpl::RenderFrameRate(const uint32_t streamId)
{
    CriticalSectionScoped cs(&_renderMacCocoaCritsect);
    return 0;
}

int32_t
VideoRenderMacCocoaImpl::SetStreamCropping(const uint32_t streamId,
        const float left,
        const float top,
        const float right,
        const float bottom)
{
    return 0;
}

int32_t VideoRenderMacCocoaImpl::ConfigureRenderer(const uint32_t streamId,
                                                   const unsigned int zOrder,
                                                   const float left,
                                                   const float top,
                                                   const float right,
                                                   const float bottom)
{
    return 0;
}

int32_t
VideoRenderMacCocoaImpl::SetTransparentBackground(const bool enable)
{
    return 0;
}

int32_t VideoRenderMacCocoaImpl::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 _ptrCocoaRender->SetText(textId, text, textLength, textColorRef, backgroundColorRef, left, top, right, bottom);
}

int32_t VideoRenderMacCocoaImpl::SetBitmap(const void* bitMap,
                                           const uint8_t pictureId,
                                           const void* colorKey,
                                           const float left,
                                           const float top,
                                           const float right,
                                           const float bottom)
{
    return 0;
}

int32_t VideoRenderMacCocoaImpl::FullScreenRender(void* window, const bool enable)
{
    return -1;
}

}  // namespace webrtc

#endif // COCOA_RENDERING
