/*
 *  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 <assert.h>

#include "webrtc/common_video/interface/incoming_video_stream.h"
#include "webrtc/engine_configurations.h"
#include "webrtc/modules/video_render/external/video_render_external_impl.h"
#include "webrtc/modules/video_render/i_video_render.h"
#include "webrtc/modules/video_render/include/video_render_defines.h"
#include "webrtc/modules/video_render/video_render_impl.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/trace.h"

namespace webrtc {

VideoRender*
VideoRender::CreateVideoRender(const int32_t id,
                               void* window,
                               const bool fullscreen,
                               const VideoRenderType videoRenderType/*=kRenderDefault*/)
{
    VideoRenderType resultVideoRenderType = videoRenderType;
    if (videoRenderType == kRenderDefault)
    {
        resultVideoRenderType = kRenderExternal;
    }
    return new ModuleVideoRenderImpl(id, resultVideoRenderType, window,
                                     fullscreen);
}

void VideoRender::DestroyVideoRender(
                                                         VideoRender* module)
{
    if (module)
    {
        delete module;
    }
}

ModuleVideoRenderImpl::ModuleVideoRenderImpl(
                                             const int32_t id,
                                             const VideoRenderType videoRenderType,
                                             void* window,
                                             const bool fullscreen) :
    _id(id), _moduleCrit(*CriticalSectionWrapper::CreateCriticalSection()),
    _ptrWindow(window), _fullScreen(fullscreen), _ptrRenderer(NULL)
{

    // Create platform specific renderer
    switch (videoRenderType)
    {
        case kRenderExternal:
        {
            VideoRenderExternalImpl* ptrRenderer(NULL);
            ptrRenderer = new VideoRenderExternalImpl(_id, videoRenderType,
                                                      window, _fullScreen);
            if (ptrRenderer)
            {
                _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
            }
        }
            break;
        default:
            // Error...
            break;
    }
    if (_ptrRenderer)
    {
        if (_ptrRenderer->Init() == -1)
        {
        }
    }
}

ModuleVideoRenderImpl::~ModuleVideoRenderImpl()
{
    delete &_moduleCrit;

    for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin();
         it != _streamRenderMap.end();
         ++it) {
      delete it->second;
    }

    // Delete platform specific renderer
    if (_ptrRenderer)
    {
        VideoRenderType videoRenderType = _ptrRenderer->RenderType();

        switch (videoRenderType)
        {
            case kRenderExternal:
            {
                VideoRenderExternalImpl
                        * ptrRenderer =
                                reinterpret_cast<VideoRenderExternalImpl*> (_ptrRenderer);
                _ptrRenderer = NULL;
                delete ptrRenderer;
            }
            break;

            default:
                // Error...
                break;
        }
    }
}

int64_t ModuleVideoRenderImpl::TimeUntilNextProcess()
{
    // Not used
    return 50;
}
int32_t ModuleVideoRenderImpl::Process()
{
    // Not used
    return 0;
}

void*
ModuleVideoRenderImpl::Window()
{
    CriticalSectionScoped cs(&_moduleCrit);
    return _ptrWindow;
}

int32_t ModuleVideoRenderImpl::ChangeWindow(void* window)
{
    return -1;
}

int32_t ModuleVideoRenderImpl::Id()
{
    CriticalSectionScoped cs(&_moduleCrit);
    return _id;
}

uint32_t ModuleVideoRenderImpl::GetIncomingFrameRate(const uint32_t streamId) {
  CriticalSectionScoped cs(&_moduleCrit);

  IncomingVideoStreamMap::iterator it = _streamRenderMap.find(streamId);

  if (it == _streamRenderMap.end()) {
    // This stream doesn't exist
    WEBRTC_TRACE(kTraceError,
                 kTraceVideoRenderer,
                 _id,
                 "%s: stream doesn't exist",
                 __FUNCTION__);
    return 0;
  }
  assert(it->second != NULL);
  return it->second->IncomingRate();
}

VideoRenderCallback*
ModuleVideoRenderImpl::AddIncomingRenderStream(const uint32_t streamId,
                                               const uint32_t zOrder,
                                               const float left,
                                               const float top,
                                               const float right,
                                               const float bottom)
{
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return NULL;
    }

    if (_streamRenderMap.find(streamId) != _streamRenderMap.end()) {
        // The stream already exists...
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: stream already exists", __FUNCTION__);
        return NULL;
    }

    VideoRenderCallback* ptrRenderCallback =
            _ptrRenderer->AddIncomingRenderStream(streamId, zOrder, left, top,
                                                  right, bottom);
    if (ptrRenderCallback == NULL)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: Can't create incoming stream in renderer",
                     __FUNCTION__);
        return NULL;
    }

    // Create platform independant code
    IncomingVideoStream* ptrIncomingStream = new IncomingVideoStream(streamId);
    ptrIncomingStream->SetRenderCallback(ptrRenderCallback);
    VideoRenderCallback* moduleCallback = ptrIncomingStream->ModuleCallback();

    // Store the stream
    _streamRenderMap[streamId] = ptrIncomingStream;

    return moduleCallback;
}

int32_t ModuleVideoRenderImpl::DeleteIncomingRenderStream(
                                                                const uint32_t streamId)
{
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return -1;
    }

    IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);
    if (item == _streamRenderMap.end())
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: stream doesn't exist", __FUNCTION__);
        return -1;
    }

    delete item->second;

    _ptrRenderer->DeleteIncomingRenderStream(streamId);

    _streamRenderMap.erase(item);

    return 0;
}

int32_t ModuleVideoRenderImpl::AddExternalRenderCallback(
    const uint32_t streamId,
    VideoRenderCallback* renderObject) {
    CriticalSectionScoped cs(&_moduleCrit);

    IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);

    if (item == _streamRenderMap.end())
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: stream doesn't exist", __FUNCTION__);
        return -1;
    }

    if (item->second == NULL) {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: could not get stream", __FUNCTION__);
        return -1;
    }
    item->second->SetExternalCallback(renderObject);
    return 0;
}

int32_t ModuleVideoRenderImpl::GetIncomingRenderStreamProperties(
    const uint32_t streamId,
    uint32_t& zOrder,
    float& left,
    float& top,
    float& right,
    float& bottom) const {
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return -1;
    }

    return _ptrRenderer->GetIncomingRenderStreamProperties(streamId, zOrder,
                                                           left, top, right,
                                                           bottom);
}

uint32_t ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const
{
    CriticalSectionScoped cs(&_moduleCrit);

    return static_cast<uint32_t>(_streamRenderMap.size());
}

bool ModuleVideoRenderImpl::HasIncomingRenderStream(
    const uint32_t streamId) const {
  CriticalSectionScoped cs(&_moduleCrit);

  return _streamRenderMap.find(streamId) != _streamRenderMap.end();
}

int32_t ModuleVideoRenderImpl::RegisterRawFrameCallback(
    const uint32_t streamId,
    VideoRenderCallback* callbackObj) {
  return -1;
}

int32_t ModuleVideoRenderImpl::StartRender(const uint32_t streamId)
{
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return -1;
    }

    // Start the stream
    IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);

    if (item == _streamRenderMap.end())
    {
        return -1;
    }

    if (item->second->Start() == -1)
    {
        return -1;
    }

    // Start the HW renderer
    if (_ptrRenderer->StartRender() == -1)
    {
        return -1;
    }
    return 0;
}

int32_t ModuleVideoRenderImpl::StopRender(const uint32_t streamId)
{
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s(%d): No renderer", __FUNCTION__, streamId);
        return -1;
    }

    // Stop the incoming stream
    IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);

    if (item == _streamRenderMap.end())
    {
        return -1;
    }

    if (item->second->Stop() == -1)
    {
        return -1;
    }

    return 0;
}

int32_t ModuleVideoRenderImpl::ResetRender()
{
    CriticalSectionScoped cs(&_moduleCrit);

    int32_t ret = 0;
    // Loop through all incoming streams and reset them
    for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin();
         it != _streamRenderMap.end();
         ++it) {
      if (it->second->Reset() == -1)
        ret = -1;
    }
    return ret;
}

RawVideoType ModuleVideoRenderImpl::PreferredVideoType() const
{
    CriticalSectionScoped cs(&_moduleCrit);

    if (_ptrRenderer == NULL)
    {
        return kVideoI420;
    }

    return _ptrRenderer->PerferedVideoType();
}

bool ModuleVideoRenderImpl::IsFullScreen()
{
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return false;
    }
    return _ptrRenderer->FullScreen();
}

int32_t ModuleVideoRenderImpl::GetScreenResolution(
                                                         uint32_t& screenWidth,
                                                         uint32_t& screenHeight) const
{
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return false;
    }
    return _ptrRenderer->GetScreenResolution(screenWidth, screenHeight);
}

uint32_t ModuleVideoRenderImpl::RenderFrameRate(
                                                      const uint32_t streamId)
{
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return false;
    }
    return _ptrRenderer->RenderFrameRate(streamId);
}

int32_t ModuleVideoRenderImpl::SetStreamCropping(
                                                       const uint32_t streamId,
                                                       const float left,
                                                       const float top,
                                                       const float right,
                                                       const float bottom)
{
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return false;
    }
    return _ptrRenderer->SetStreamCropping(streamId, left, top, right, bottom);
}

int32_t ModuleVideoRenderImpl::SetTransparentBackground(const bool enable)
{
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return false;
    }
    return _ptrRenderer->SetTransparentBackground(enable);
}

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

int32_t ModuleVideoRenderImpl::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)
{
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return -1;
    }
    return _ptrRenderer->SetText(textId, text, textLength, textColorRef,
                                 backgroundColorRef, left, top, right, bottom);
}

int32_t ModuleVideoRenderImpl::SetBitmap(const void* bitMap,
                                         const uint8_t pictureId,
                                         const void* colorKey,
                                         const float left,
                                         const float top,
                                         const float right,
                                         const float bottom)
{
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return -1;
    }
    return _ptrRenderer->SetBitmap(bitMap, pictureId, colorKey, left, top,
                                   right, bottom);
}

int32_t ModuleVideoRenderImpl::SetExpectedRenderDelay(
    uint32_t stream_id, int32_t delay_ms) {
  CriticalSectionScoped cs(&_moduleCrit);

  if (!_ptrRenderer) {
    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                 "%s: No renderer", __FUNCTION__);
    return false;
  }

  IncomingVideoStreamMap::const_iterator item =
      _streamRenderMap.find(stream_id);
  if (item == _streamRenderMap.end()) {
    // This stream doesn't exist
    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                 "%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id,
                 delay_ms);
    return -1;
  }

  assert(item->second != NULL);
  return item->second->SetExpectedRenderDelay(delay_ms);
}

int32_t ModuleVideoRenderImpl::ConfigureRenderer(
                                                       const uint32_t streamId,
                                                       const unsigned int zOrder,
                                                       const float left,
                                                       const float top,
                                                       const float right,
                                                       const float bottom)
{
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return false;
    }
    return _ptrRenderer->ConfigureRenderer(streamId, zOrder, left, top, right,
                                           bottom);
}

int32_t ModuleVideoRenderImpl::SetStartImage(const uint32_t streamId,
                                             const VideoFrame& videoFrame) {
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return -1;
    }

    IncomingVideoStreamMap::const_iterator item =
        _streamRenderMap.find(streamId);
    if (item == _streamRenderMap.end())
    {
        // This stream doesn't exist
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: stream doesn't exist", __FUNCTION__);
        return -1;
    }
    assert (item->second != NULL);
    return item->second->SetStartImage(videoFrame);

}

int32_t ModuleVideoRenderImpl::SetTimeoutImage(const uint32_t streamId,
                                               const VideoFrame& videoFrame,
                                               const uint32_t timeout) {
    CriticalSectionScoped cs(&_moduleCrit);

    if (!_ptrRenderer)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: No renderer", __FUNCTION__);
        return -1;
    }

    IncomingVideoStreamMap::const_iterator item =
        _streamRenderMap.find(streamId);
    if (item == _streamRenderMap.end())
    {
        // This stream doesn't exist
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
                     "%s: stream doesn't exist", __FUNCTION__);
        return -1;
    }
    assert(item->second != NULL);
    return item->second->SetTimeoutImage(videoFrame, timeout);
}

}  // namespace webrtc
