/*
 *  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 <initguid.h>  // Must come before the help_functions_ds.h include so
                       // that DEFINE_GUID() entries will be defined in this
                       // object file.

#include "modules/video_capture/windows/help_functions_ds.h"

#include "rtc_base/logging.h"

#include <cguid.h>

namespace webrtc {
namespace videocapturemodule {
// This returns minimum :), which will give max frame rate...
LONGLONG GetMaxOfFrameArray(LONGLONG* maxFps, long size) {
  LONGLONG maxFPS = maxFps[0];
  for (int i = 0; i < size; i++) {
    if (maxFPS > maxFps[i])
      maxFPS = maxFps[i];
  }
  return maxFPS;
}

IPin* GetInputPin(IBaseFilter* filter) {
  HRESULT hr;
  IPin* pin = NULL;
  IEnumPins* pPinEnum = NULL;
  filter->EnumPins(&pPinEnum);
  if (pPinEnum == NULL) {
    return NULL;
  }

  // get first unconnected pin
  hr = pPinEnum->Reset();  // set to first pin

  while (S_OK == pPinEnum->Next(1, &pin, NULL)) {
    PIN_DIRECTION pPinDir;
    pin->QueryDirection(&pPinDir);
    if (PINDIR_INPUT == pPinDir)  // This is an input pin
    {
      IPin* tempPin = NULL;
      if (S_OK != pin->ConnectedTo(&tempPin))  // The pint is not connected
      {
        pPinEnum->Release();
        return pin;
      }
    }
    pin->Release();
  }
  pPinEnum->Release();
  return NULL;
}

IPin* GetOutputPin(IBaseFilter* filter, REFGUID Category) {
  HRESULT hr;
  IPin* pin = NULL;
  IEnumPins* pPinEnum = NULL;
  filter->EnumPins(&pPinEnum);
  if (pPinEnum == NULL) {
    return NULL;
  }
  // get first unconnected pin
  hr = pPinEnum->Reset();  // set to first pin
  while (S_OK == pPinEnum->Next(1, &pin, NULL)) {
    PIN_DIRECTION pPinDir;
    pin->QueryDirection(&pPinDir);
    if (PINDIR_OUTPUT == pPinDir)  // This is an output pin
    {
      if (Category == GUID_NULL || PinMatchesCategory(pin, Category)) {
        pPinEnum->Release();
        return pin;
      }
    }
    pin->Release();
    pin = NULL;
  }
  pPinEnum->Release();
  return NULL;
}

BOOL PinMatchesCategory(IPin* pPin, REFGUID Category) {
  BOOL bFound = FALSE;
  IKsPropertySet* pKs = NULL;
  HRESULT hr = pPin->QueryInterface(IID_PPV_ARGS(&pKs));
  if (SUCCEEDED(hr)) {
    GUID PinCategory;
    DWORD cbReturned;
    hr = pKs->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0,
                  &PinCategory, sizeof(GUID), &cbReturned);
    if (SUCCEEDED(hr) && (cbReturned == sizeof(GUID))) {
      bFound = (PinCategory == Category);
    }
    pKs->Release();
  }
  return bFound;
}

void ResetMediaType(AM_MEDIA_TYPE* media_type) {
  if (!media_type)
    return;
  if (media_type->cbFormat != 0) {
    CoTaskMemFree(media_type->pbFormat);
    media_type->cbFormat = 0;
    media_type->pbFormat = nullptr;
  }
  if (media_type->pUnk) {
    media_type->pUnk->Release();
    media_type->pUnk = nullptr;
  }
}

void FreeMediaType(AM_MEDIA_TYPE* media_type) {
  if (!media_type)
    return;
  ResetMediaType(media_type);
  CoTaskMemFree(media_type);
}

HRESULT CopyMediaType(AM_MEDIA_TYPE* target, const AM_MEDIA_TYPE* source) {
  RTC_DCHECK_NE(source, target);
  *target = *source;
  if (source->cbFormat != 0) {
    RTC_DCHECK(source->pbFormat);
    target->pbFormat =
        reinterpret_cast<BYTE*>(CoTaskMemAlloc(source->cbFormat));
    if (target->pbFormat == nullptr) {
      target->cbFormat = 0;
      return E_OUTOFMEMORY;
    } else {
      CopyMemory(target->pbFormat, source->pbFormat, target->cbFormat);
    }
  }

  if (target->pUnk != nullptr)
    target->pUnk->AddRef();

  return S_OK;
}

wchar_t* DuplicateWideString(const wchar_t* str) {
  size_t len = lstrlenW(str);
  wchar_t* ret =
      reinterpret_cast<LPWSTR>(CoTaskMemAlloc((len + 1) * sizeof(wchar_t)));
  lstrcpyW(ret, str);
  return ret;
}

}  // namespace videocapturemodule
}  // namespace webrtc
