/*
 *  Copyright (c) 2013 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.
 */

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

#include "webrtc/modules/video_render/ios/video_render_ios_gles20.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"

using namespace webrtc;

VideoRenderIosGles20::VideoRenderIosGles20(VideoRenderIosView* view,
                                           bool full_screen,
                                           int render_id)
    : gles_crit_sec_(CriticalSectionWrapper::CreateCriticalSection()),
      screen_update_event_(0),
      view_(view),
      window_rect_(),
      window_width_(0),
      window_height_(0),
      is_full_screen_(full_screen),
      agl_channels_(),
      z_order_to_channel_(),
      gles_context_([view context]),
      is_rendering_(true) {
  screen_update_thread_ = ThreadWrapper::CreateThread(
      ScreenUpdateThreadProc, this, "ScreenUpdateGles20");
  screen_update_event_ = EventTimerWrapper::Create();
  GetWindowRect(window_rect_);
}

VideoRenderIosGles20::~VideoRenderIosGles20() {
  // Signal event to exit thread, then delete it
  ThreadWrapper* thread_wrapper = screen_update_thread_.release();

  if (thread_wrapper) {
    screen_update_event_->Set();
    screen_update_event_->StopTimer();

    thread_wrapper->Stop();
    delete thread_wrapper;
    delete screen_update_event_;
    screen_update_event_ = NULL;
    is_rendering_ = FALSE;
  }

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

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

int VideoRenderIosGles20::Init() {
  CriticalSectionScoped cs(gles_crit_sec_.get());

  if (!view_) {
    view_ = [[VideoRenderIosView alloc] init];
  }

  if (![view_ createContext]) {
    return -1;
  }

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

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

  window_width_ = window_rect_.right - window_rect_.left;
  window_height_ = window_rect_.bottom - window_rect_.top;

  return 0;
}

VideoRenderIosChannel* VideoRenderIosGles20::CreateEaglChannel(int channel,
                                                               int z_order,
                                                               float left,
                                                               float top,
                                                               float right,
                                                               float bottom) {
  CriticalSectionScoped cs(gles_crit_sec_.get());

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

  VideoRenderIosChannel* new_eagl_channel = new VideoRenderIosChannel(view_);

  if (new_eagl_channel->SetStreamSettings(z_order, left, top, right, bottom) ==
      -1) {
    return NULL;
  }

  agl_channels_[channel] = new_eagl_channel;
  z_order_to_channel_.insert(std::pair<int, int>(z_order, channel));

  return new_eagl_channel;
}

int VideoRenderIosGles20::DeleteEaglChannel(int channel) {
  CriticalSectionScoped cs(gles_crit_sec_.get());

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

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

  return 0;
}

bool VideoRenderIosGles20::HasChannel(int channel) {
  CriticalSectionScoped cs(gles_crit_sec_.get());

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

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

  return false;
}

// Rendering process
bool VideoRenderIosGles20::ScreenUpdateThreadProc(void* obj) {
  return static_cast<VideoRenderIosGles20*>(obj)->ScreenUpdateProcess();
}

bool VideoRenderIosGles20::ScreenUpdateProcess() {
  screen_update_event_->Wait(100);

  CriticalSectionScoped cs(gles_crit_sec_.get());

  if (!is_rendering_) {
    return false;
  }

  if (!screen_update_thread_) {
    return false;
  }

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

  if (window_width_ != (window_rect_.right - window_rect_.left) ||
      window_height_ != (window_rect_.bottom - window_rect_.top)) {
    window_width_ = window_rect_.right - window_rect_.left;
    window_height_ = window_rect_.bottom - window_rect_.top;
  }

  // Check if there are any updated buffers
  bool updated = false;

  std::map<int, VideoRenderIosChannel*>::iterator it = agl_channels_.begin();
  while (it != agl_channels_.end()) {
    VideoRenderIosChannel* agl_channel = it->second;

    updated = agl_channel->IsUpdated();
    if (updated) {
      break;
    }
    it++;
  }

  if (updated) {
    // At least one buffer has been updated, we need to repaint the texture
    // Loop through all channels starting highest zOrder ending with lowest.
    for (std::multimap<int, int>::reverse_iterator r_it =
             z_order_to_channel_.rbegin();
         r_it != z_order_to_channel_.rend();
         r_it++) {
      int channel_id = r_it->second;
      std::map<int, VideoRenderIosChannel*>::iterator it =
          agl_channels_.find(channel_id);

      VideoRenderIosChannel* agl_channel = it->second;

      agl_channel->RenderOffScreenBuffer();
    }

    [view_ presentFramebuffer];
  }

  return true;
}

int VideoRenderIosGles20::GetWindowRect(Rect& rect) {
  CriticalSectionScoped cs(gles_crit_sec_.get());

  if (!view_) {
    return -1;
  }

  CGRect bounds = [view_ bounds];
  rect.top = bounds.origin.y;
  rect.left = bounds.origin.x;
  rect.bottom = bounds.size.height + bounds.origin.y;
  rect.right = bounds.size.width + bounds.origin.x;

  return 0;
}

int VideoRenderIosGles20::ChangeWindow(void* new_window) {
  CriticalSectionScoped cs(gles_crit_sec_.get());

  view_ = (__bridge VideoRenderIosView*)new_window;

  return 0;
}

int VideoRenderIosGles20::StartRender() {
  is_rendering_ = true;
  return 0;
}

int VideoRenderIosGles20::StopRender() {
  is_rendering_ = false;
  return 0;
}

int VideoRenderIosGles20::GetScreenResolution(uint& screen_width,
                                              uint& screen_height) {
  screen_width = [view_ bounds].size.width;
  screen_height = [view_ bounds].size.height;
  return 0;
}

int VideoRenderIosGles20::SetStreamCropping(const uint stream_id,
                                            const float left,
                                            const float top,
                                            const float right,
                                            const float bottom) {
  // Check if there are any updated buffers
  // bool updated = false;
  uint counter = 0;

  std::map<int, VideoRenderIosChannel*>::iterator it = agl_channels_.begin();
  while (it != agl_channels_.end()) {
    if (counter == stream_id) {
      VideoRenderIosChannel* agl_channel = it->second;
      agl_channel->SetStreamSettings(0, left, top, right, bottom);
    }
    counter++;
    it++;
  }

  return 0;
}
