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

// Implementation of CarbonVideoRenderer

#include "webrtc/media/devices/carbonvideorenderer.h"

#include "libyuv/convert_from.h"
#include "webrtc/base/logging.h"
#include "webrtc/media/base/videocommon.h"
#include "webrtc/media/base/videoframe.h"

namespace cricket {

CarbonVideoRenderer::CarbonVideoRenderer(int x, int y)
    : image_width_(0),
      image_height_(0),
      x_(x),
      y_(y),
      window_ref_(NULL) {
}

CarbonVideoRenderer::~CarbonVideoRenderer() {
  if (window_ref_) {
    DisposeWindow(window_ref_);
  }
}

// Called from the main event loop. All renderering needs to happen on
// the main thread.
OSStatus CarbonVideoRenderer::DrawEventHandler(EventHandlerCallRef handler,
                                               EventRef event,
                                               void* data) {
  OSStatus status = noErr;
  CarbonVideoRenderer* renderer = static_cast<CarbonVideoRenderer*>(data);
  if (renderer != NULL) {
    if (!renderer->DrawFrame()) {
      LOG(LS_ERROR) << "Failed to draw frame.";
    }
  }
  return status;
}

bool CarbonVideoRenderer::DrawFrame() {
  // Grab the image lock to make sure it is not changed why we'll draw it.
  rtc::CritScope cs(&image_crit_);

  if (image_.get() == NULL) {
    // Nothing to draw, just return.
    return true;
  }
  int width = image_width_;
  int height = image_height_;
  CGDataProviderRef provider =
      CGDataProviderCreateWithData(NULL, image_.get(), width * height * 4,
                                   NULL);
  CGColorSpaceRef color_space_ref = CGColorSpaceCreateDeviceRGB();
  CGBitmapInfo bitmap_info = kCGBitmapByteOrderDefault;
  CGColorRenderingIntent rendering_intent = kCGRenderingIntentDefault;
  CGImageRef image_ref = CGImageCreate(width, height, 8, 32, width * 4,
                                       color_space_ref, bitmap_info, provider,
                                       NULL, false, rendering_intent);
  CGDataProviderRelease(provider);

  if (image_ref == NULL) {
    return false;
  }
  CGContextRef context;
  SetPortWindowPort(window_ref_);
  if (QDBeginCGContext(GetWindowPort(window_ref_), &context) != noErr) {
    CGImageRelease(image_ref);
    return false;
  }
  Rect window_bounds;
  GetWindowPortBounds(window_ref_, &window_bounds);

  // Anchor the image to the top left corner.
  int x = 0;
  int y = window_bounds.bottom - CGImageGetHeight(image_ref);
  CGRect dst_rect = CGRectMake(x, y, CGImageGetWidth(image_ref),
                               CGImageGetHeight(image_ref));
  CGContextDrawImage(context, dst_rect, image_ref);
  CGContextFlush(context);
  QDEndCGContext(GetWindowPort(window_ref_), &context);
  CGImageRelease(image_ref);
  return true;
}

bool CarbonVideoRenderer::SetSize(int width, int height) {
  if (width != image_width_ || height != image_height_) {
    // Grab the image lock while changing its size.
    rtc::CritScope cs(&image_crit_);
    image_width_ = width;
    image_height_ = height;
    image_.reset(new uint8_t[width * height * 4]);
    memset(image_.get(), 255, width * height * 4);
  }
  return true;
}

void CarbonVideoRenderer::OnFrame(const VideoFrame& video_frame) {
  {
    const cricket::WebRtcVideoFrame frame(
        webrtc::I420Buffer::Rotate(video_frame.video_frame_buffer(),
                                   video_frame.rotation()),
        webrtc::kVideoRotation_0, video_frame.timestamp_us());

    if (!SetSize(frame.width(), frame.height())) {
      return false;
    }

    // Grab the image lock so we are not trashing up the image being drawn.
    rtc::CritScope cs(&image_crit_);
    rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer(
        frame.video_frame_buffer());
    libyuv::I420ToABGR(buffer->DataY(), buffer->StrideY(),
                       buffer->DataU(), buffer->StrideU(),
                       buffer->DataV(), buffer->StrideV(),
                       image_.get(), frame.width() * 4,
                       buffer->width(), buffer->height());
  }

  // Trigger a repaint event for the whole window.
  Rect bounds;
  InvalWindowRect(window_ref_, GetWindowPortBounds(window_ref_, &bounds));
  return true;
}

bool CarbonVideoRenderer::Initialize() {
  OSStatus err;
  WindowAttributes attributes =
      kWindowStandardDocumentAttributes |
      kWindowLiveResizeAttribute |
      kWindowFrameworkScaledAttribute |
      kWindowStandardHandlerAttribute;

  struct Rect bounds;
  bounds.top = y_;
  bounds.bottom = 480;
  bounds.left = x_;
  bounds.right = 640;
  err = CreateNewWindow(kDocumentWindowClass, attributes,
                        &bounds, &window_ref_);
  if (!window_ref_ || err != noErr) {
    LOG(LS_ERROR) << "CreateNewWindow failed, error code: " << err;
    return false;
  }
  static const EventTypeSpec event_spec = {
    kEventClassWindow,
    kEventWindowDrawContent
  };

  err = InstallWindowEventHandler(
      window_ref_,
      NewEventHandlerUPP(CarbonVideoRenderer::DrawEventHandler),
      GetEventTypeCount(event_spec),
      &event_spec,
      this,
      NULL);
  if (err != noErr) {
    LOG(LS_ERROR) << "Failed to install event handler, error code: " << err;
    return false;
  }
  SelectWindow(window_ref_);
  ShowWindow(window_ref_);
  return true;
}

}  // namespace cricket
