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

#define DEFAULT_CAPTURE_DEVICE_INDEX    1
#define DEFAULT_FRAME_RATE              30
#define DEFAULT_FRAME_WIDTH             352
#define DEFAULT_FRAME_HEIGHT            288
#define ROTATE_CAPTURED_FRAME           1
#define LOW_QUALITY                     1

#import "webrtc/modules/video_capture/mac/qtkit/video_capture_qtkit_objc.h"

#include "webrtc/system_wrappers/interface/trace.h"

using namespace webrtc;
using namespace videocapturemodule;

@implementation VideoCaptureMacQTKitObjC

-(id)init {
  self = [super init];
  if (self) {
    [self initializeVariables];
  }
  return self;
}

- (void)dealloc {
  if (_captureSession)
    [_captureSession stopRunning];

  if (_captureVideoDeviceInput) {
    if ([[_captureVideoDeviceInput device] isOpen])
      [[_captureVideoDeviceInput device] close];

    [_captureVideoDeviceInput release];
  }

  [_captureDecompressedVideoOutput release];
  [_captureSession release];
  [_captureDevices release];
  [_lock release];

  [super dealloc];
}

#pragma mark Public methods

- (void)registerOwner:(VideoCaptureMacQTKit*)owner {
  [_lock lock];
  _owner = owner;
  [_lock unlock];
}

- (BOOL)setCaptureDeviceById:(char*)uniqueId {
  if (uniqueId == nil || !strcmp("", uniqueId)) {
    WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0,
                 "Incorrect capture id argument");
    return NO;
  }

  if (!strcmp(uniqueId, _captureDeviceNameUniqueID))
    return YES;

  QTCaptureDevice* captureDevice;
  for(int index = 0; index < _captureDeviceCount; index++) {
    captureDevice = (QTCaptureDevice*)[_captureDevices objectAtIndex:index];
    char captureDeviceId[1024] = "";
    [[captureDevice uniqueID] getCString:captureDeviceId
                               maxLength:1024
                                encoding:NSUTF8StringEncoding];
    if (strcmp(uniqueId, captureDeviceId) == 0) {
      WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0,
                   "%s:%d Found capture device id %s as index %d",
                   __FUNCTION__, __LINE__, captureDeviceId, index);
      [[captureDevice localizedDisplayName] getCString:_captureDeviceNameUTF8
                                             maxLength:1024
                                              encoding:NSUTF8StringEncoding];
      [[captureDevice uniqueID] getCString:_captureDeviceNameUniqueID
                                 maxLength:1024
                                  encoding:NSUTF8StringEncoding];
      break;
    }
    captureDevice = nil;
  }

  if (!captureDevice)
    return NO;

  NSError* error;
  if (![captureDevice open:&error]) {
    WEBRTC_TRACE(kTraceError, kTraceVideoCapture, 0,
                 "Failed to open capture device: %s", _captureDeviceNameUTF8);
    return NO;
  }

  if (_captureVideoDeviceInput) {
    [_captureVideoDeviceInput release];
  }
  _captureVideoDeviceInput =
      [[QTCaptureDeviceInput alloc] initWithDevice:captureDevice];

  if (![_captureSession addInput:_captureVideoDeviceInput error:&error]) {
    WEBRTC_TRACE(kTraceError, kTraceVideoCapture, 0,
                 "Failed to add input from %s to the capture session",
                 _captureDeviceNameUTF8);
    return NO;
  }

  WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0,
               "%s:%d successfully added capture device: %s", __FUNCTION__,
               __LINE__, _captureDeviceNameUTF8);
  return YES;
}

- (void)setCaptureHeight:(int)height width:(int)width frameRate:(int)frameRate {
  _frameWidth = width;
  _frameHeight = height;
  _frameRate = frameRate;

  NSDictionary* captureDictionary =
      [NSDictionary dictionaryWithObjectsAndKeys:
          [NSNumber numberWithDouble:_frameWidth],
          (id)kCVPixelBufferWidthKey,
          [NSNumber numberWithDouble:_frameHeight],
          (id)kCVPixelBufferHeightKey,
          [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB],
          (id)kCVPixelBufferPixelFormatTypeKey,
          nil];
  [_captureDecompressedVideoOutput
      performSelectorOnMainThread:@selector(setPixelBufferAttributes:)
                       withObject:captureDictionary
                    waitUntilDone:YES];
}

- (void)startCapture {
  if (_capturing)
    return;

  [_captureSession startRunning];
  _capturing = YES;
}

- (void)stopCapture {
  if (!_capturing)
    return;

  [_captureSession stopRunning];
  _capturing = NO;
}

#pragma mark Private methods

- (BOOL)initializeVariables {
  if (NSClassFromString(@"QTCaptureSession") == nil)
    return NO;

  memset(_captureDeviceNameUTF8, 0, 1024);
  _framesDelivered = 0;
  _framesRendered = 0;
  _captureDeviceCount = 0;
  _capturing = NO;
  _captureInitialized = NO;
  _frameRate = DEFAULT_FRAME_RATE;
  _frameWidth = DEFAULT_FRAME_WIDTH;
  _frameHeight = DEFAULT_FRAME_HEIGHT;
  _lock = [[NSLock alloc] init];
  _captureSession = [[QTCaptureSession alloc] init];
  _captureDecompressedVideoOutput =
      [[QTCaptureDecompressedVideoOutput alloc] init];
  [_captureDecompressedVideoOutput setDelegate:self];

  [self getCaptureDevices];
  if (![self initializeVideoCapture])
    return NO;

  return NO;
}

- (void)getCaptureDevices {
  if (_captureDevices)
    [_captureDevices release];

  _captureDevices = [[NSArray alloc] initWithArray:
      [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo]];

  _captureDeviceCount = _captureDevices.count;
}

- (BOOL)initializeVideoCapture{
  NSDictionary *captureDictionary =
      [NSDictionary dictionaryWithObjectsAndKeys:
          [NSNumber numberWithDouble:_frameWidth],
          (id)kCVPixelBufferWidthKey,
          [NSNumber numberWithDouble:_frameHeight],
          (id)kCVPixelBufferHeightKey,
          [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB],
          (id)kCVPixelBufferPixelFormatTypeKey,
          nil];

  [_captureDecompressedVideoOutput setPixelBufferAttributes:captureDictionary];
  [_captureDecompressedVideoOutput setAutomaticallyDropsLateVideoFrames:YES];
  [_captureDecompressedVideoOutput
      setMinimumVideoFrameInterval:(NSTimeInterval)1/(float)_frameRate];

  NSError *error;
  if (![_captureSession addOutput:_captureDecompressedVideoOutput error:&error])
    return NO;

  return YES;
}

- (void)captureOutput:(QTCaptureOutput *)captureOutput
    didDropVideoFrameWithSampleBuffer:(QTSampleBuffer *)sampleBuffer
                       fromConnection:(QTCaptureConnection *)connection {
  // TODO(mflodman) Experiment more when this happens.
}

- (void)captureOutput:(QTCaptureOutput *)captureOutput
  didOutputVideoFrame:(CVImageBufferRef)videoFrame
     withSampleBuffer:(QTSampleBuffer *)sampleBuffer
       fromConnection:(QTCaptureConnection *)connection {

  [_lock lock];
  if (!_owner) {
    [_lock unlock];
    return;
  }

  const int kFlags = 0;
  if (CVPixelBufferLockBaseAddress(videoFrame, kFlags) == kCVReturnSuccess) {
    void *baseAddress = CVPixelBufferGetBaseAddress(videoFrame);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(videoFrame);
    size_t frameHeight = CVPixelBufferGetHeight(videoFrame);
    size_t frameSize = bytesPerRow * frameHeight;

    VideoCaptureCapability tempCaptureCapability;
    tempCaptureCapability.width = _frameWidth;
    tempCaptureCapability.height = _frameHeight;
    tempCaptureCapability.maxFPS = _frameRate;
    // TODO(wu) : Update actual type and not hard-coded value.
    tempCaptureCapability.rawType = kVideoBGRA;

    _owner->IncomingFrame((unsigned char*)baseAddress, frameSize,
                          tempCaptureCapability, 0);
    CVPixelBufferUnlockBaseAddress(videoFrame, kFlags);
  }
  [_lock unlock];
  _framesDelivered++;
  _framesRendered++;
}

@end
