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

#include "test/mac/video_renderer_mac.h"

#import <Cocoa/Cocoa.h>

// Creates a Cocoa Window with an OpenGL context, used together with an OpenGL
// renderer.
@interface CocoaWindow : NSObject {
 @private
  NSWindow *window_;
  NSOpenGLContext *context_;
  NSString *title_;
  int width_;
  int height_;
}

- (id)initWithTitle:(NSString *)title width:(int)width height:(int)height;
// 'createWindow' must be called on the main thread.
- (void)createWindow:(NSObject *)ignored;
- (void)makeCurrentContext;

@end

@implementation CocoaWindow
static NSInteger nextXOrigin_;
static NSInteger nextYOrigin_;

- (id)initWithTitle:(NSString *)title width:(int)width height:(int)height {
  self = [super init];
  if (self) {
    title_ = title;
    width_ = width;
    height_ = height;
  }
  return self;
}

- (void)createWindow:(NSObject *)ignored {
  NSInteger xOrigin = nextXOrigin_;
  NSRect screenFrame = [[NSScreen mainScreen] frame];
  if (nextXOrigin_ + width_ < screenFrame.size.width) {
    nextXOrigin_ += width_;
  } else {
    xOrigin = 0;
    nextXOrigin_ = 0;
    nextYOrigin_ += height_;
  }
  if (nextYOrigin_ + height_ > screenFrame.size.height) {
    xOrigin = 0;
    nextXOrigin_ = 0;
    nextYOrigin_ = 0;
  }
  NSInteger yOrigin = nextYOrigin_;
  NSRect windowFrame = NSMakeRect(xOrigin, yOrigin, width_, height_);
  window_ = [[NSWindow alloc] initWithContentRect:windowFrame
                                        styleMask:NSWindowStyleMaskTitled
                                          backing:NSBackingStoreBuffered
                                            defer:NO];

  NSRect viewFrame = NSMakeRect(0, 0, width_, height_);
  NSOpenGLView *view = [[NSOpenGLView alloc] initWithFrame:viewFrame
                                               pixelFormat:nil];
  context_ = [view openGLContext];

  [[window_ contentView] addSubview:view];
  [window_ setTitle:title_];
  [window_ makeKeyAndOrderFront:NSApp];
}

- (void)makeCurrentContext {
  [context_ makeCurrentContext];
}

@end

namespace webrtc {
namespace test {

VideoRenderer *VideoRenderer::CreatePlatformRenderer(const char *window_title,
                                                     size_t width,
                                                     size_t height) {
  MacRenderer *renderer = new MacRenderer();
  if (!renderer->Init(window_title, width, height)) {
    delete renderer;
    return NULL;
  }
  return renderer;
}

MacRenderer::MacRenderer() : window_(NULL) {}

MacRenderer::~MacRenderer() {
  GlRenderer::Destroy();
}

bool MacRenderer::Init(const char *window_title, int width, int height) {
  window_ = [[CocoaWindow alloc]
      initWithTitle:[NSString stringWithUTF8String:window_title]
              width:width
             height:height];
  if (!window_) return false;
  [window_ performSelectorOnMainThread:@selector(createWindow:)
                            withObject:nil
                         waitUntilDone:YES];

  [window_ makeCurrentContext];
  GlRenderer::Init();
  GlRenderer::ResizeViewport(width, height);
  return true;
}

void MacRenderer::OnFrame(const VideoFrame &frame) {
  [window_ makeCurrentContext];
  GlRenderer::OnFrame(frame);
}

}  // namespace test
}  // namespace webrtc
