// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/capture/video/win/video_capture_device_utils_win.h"

#include <cmath>
#include <iostream>

#include "base/win/win_util.h"
#include "base/win/windows_version.h"

namespace media {

namespace {

const int kDegreesToArcSeconds = 3600;
const int kSecondsTo100MicroSeconds = 10000;

// Determines if camera is mounted on a device with naturally portrait display.
bool IsPortraitDevice(DWORD display_height,
                      DWORD display_width,
                      DWORD display_orientation) {
  if (display_orientation == DMDO_DEFAULT || display_orientation == DMDO_180)
    return display_height >= display_width;
  else
    return display_height < display_width;
}

}  // namespace

// Windows platform stores pan and tilt (min, max, step and current) in
// degrees. Spec expects them in arc seconds.
// https://docs.microsoft.com/en-us/windows/win32/api/strmif/ne-strmif-cameracontrolproperty
// spec: https://w3c.github.io/mediacapture-image/#pan
long CaptureAngleToPlatformValue(double arc_seconds) {
  return std::round(arc_seconds / kDegreesToArcSeconds);
}

double PlatformAngleToCaptureValue(long degrees) {
  return 1.0 * degrees * kDegreesToArcSeconds;
}

double PlatformAngleToCaptureStep(long step, double min, double max) {
  return PlatformAngleToCaptureValue(step);
}

// Windows platform stores exposure time (min, max and current) in log base 2
// seconds. If value is n, exposure time is 2^n seconds. Spec expects exposure
// times in 100 micro seconds.
// https://docs.microsoft.com/en-us/windows/win32/api/strmif/ne-strmif-cameracontrolproperty
// spec: https://w3c.github.io/mediacapture-image/#exposure-time
long CaptureExposureTimeToPlatformValue(double hundreds_of_microseconds) {
  return std::log2(hundreds_of_microseconds / kSecondsTo100MicroSeconds);
}

double PlatformExposureTimeToCaptureValue(long log_seconds) {
  return std::exp2(log_seconds) * kSecondsTo100MicroSeconds;
}

double PlatformExposureTimeToCaptureStep(long log_step,
                                         double min,
                                         double max) {
  // The smallest possible value is
  // |exp2(min_log_seconds) * kSecondsTo100MicroSeconds|.
  // That value can be computed by PlatformExposureTimeToCaptureValue and is
  // passed to this function as |min| thus there is not need to recompute it
  // here.
  // The second smallest possible value is
  // |exp2(min_log_seconds + log_step) * kSecondsTo100MicroSeconds| which equals
  // to |exp2(log_step) * min|.
  // While the relative step or ratio between consecutive values is always the
  // same (|std::exp2(log_step)|), the smallest absolute step is between the
  // smallest and the second smallest possible values i.e. between |min| and
  // |exp2(log_step) * min|.
  return (std::exp2(log_step) - 1) * min;
}

// Note: Because we can't find a solid way to detect camera location (front/back
// or external USB camera) with Win32 APIs, assume it's always front camera when
// auto rotation is enabled for now.
int GetCameraRotation(VideoFacingMode facing) {
  int rotation = 0;

  // Before Win10, we can't distinguish if the selected camera is an internal or
  // external one. So we assume it's internal and do the frame rotation if the
  // auto rotation is enabled to cover most user cases.
  if (!IsInternalCamera(facing)) {
    return rotation;
  }

  // When display is only on external monitors, the auto-rotation state still
  // may be ENALBED on the target device. In that case, we shouldn't query the
  // display orientation and the built-in camera will be treated as an external
  // one.
  DISPLAY_DEVICE internal_display_device;
  if (!HasActiveInternalDisplayDevice(&internal_display_device)) {
    return rotation;
  }

  if (facing == VideoFacingMode::MEDIA_VIDEO_FACING_NONE) {
    // We set camera facing using Win10 only DeviceInformation API. So pre-Win10
    // cameras always have a facing of VideoFacingMode::MEDIA_VIDEO_FACING_NONE.
    // Win10 cameras with VideoFacingMode::MEDIA_VIDEO_FACING_NONE should early
    // exit as part of the IsInternalCamera(facing) check above.
    DCHECK(base::win::GetVersion() < base::win::Version::WIN10);
  }

  DEVMODE mode;
  ::ZeroMemory(&mode, sizeof(mode));
  mode.dmSize = sizeof(mode);
  mode.dmDriverExtra = 0;
  if (::EnumDisplaySettings(internal_display_device.DeviceName,
                            ENUM_CURRENT_SETTINGS, &mode)) {
    int camera_offset = 0;  // Measured in degrees, clockwise.
    bool portrait_device = IsPortraitDevice(mode.dmPelsHeight, mode.dmPelsWidth,
                                            mode.dmDisplayOrientation);
    switch (mode.dmDisplayOrientation) {
      case DMDO_DEFAULT:
        if (portrait_device &&
            facing == VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT) {
          camera_offset = 270;  // Adjust portrait device rear camera by 180.
        } else if (portrait_device) {
          camera_offset = 90;  // Portrait device front camera is offset by 90.
        } else {
          camera_offset = 0;
        }
        break;
      case DMDO_90:
        if (portrait_device)
          camera_offset = 180;
        else if (facing == VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT)
          camera_offset = 270;  // Adjust landscape device rear camera by 180.
        else
          camera_offset = 90;
        break;
      case DMDO_180:
        if (portrait_device &&
            facing == VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT) {
          camera_offset = 90;  // Adjust portrait device rear camera by 180.
        } else if (portrait_device) {
          camera_offset = 270;
        } else {
          camera_offset = 180;
        }
        break;
      case DMDO_270:
        if (portrait_device)
          camera_offset = 0;
        else if (facing == VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT)
          camera_offset = 90;  // Adjust landscape device rear camera by 180.
        else
          camera_offset = 270;
        break;
    }
    rotation = (360 - camera_offset) % 360;
  }

  return rotation;
}

bool IsAutoRotationEnabled() {
  typedef BOOL(WINAPI * GetAutoRotationState)(PAR_STATE state);
  static const auto get_rotation_state = reinterpret_cast<GetAutoRotationState>(
      base::win::GetUser32FunctionPointer("GetAutoRotationState"));

  if (get_rotation_state) {
    AR_STATE auto_rotation_state;
    ::ZeroMemory(&auto_rotation_state, sizeof(AR_STATE));

    if (get_rotation_state(&auto_rotation_state)) {
      // AR_ENABLED is defined as '0x0', while AR_STATE enumeration is defined
      // as bitwise. See the example codes in
      // https://msdn.microsoft.com/en-us/library/windows/desktop/dn629263(v=vs.85).aspx.
      if (auto_rotation_state == AR_ENABLED) {
        return true;
      }
    }
  }

  return false;
}

bool IsInternalCamera(VideoFacingMode facing) {
  if (base::win::GetVersion() < base::win::Version::WIN10) {
    return true;
  }

  if (facing == MEDIA_VIDEO_FACING_USER ||
      facing == MEDIA_VIDEO_FACING_ENVIRONMENT) {
    return true;
  }

  return false;
}

bool HasActiveInternalDisplayDevice(DISPLAY_DEVICE* internal_display_device) {
  DISPLAY_DEVICE display_device;
  display_device.cb = sizeof(display_device);

  for (int device_index = 0;; ++device_index) {
    BOOL enum_result =
        ::EnumDisplayDevices(NULL, device_index, &display_device, 0);
    if (!enum_result)
      break;
    if (!(display_device.StateFlags & DISPLAY_DEVICE_ACTIVE))
      continue;

    HRESULT hr = CheckPathInfoForInternal(display_device.DeviceName);
    if (SUCCEEDED(hr)) {
      *internal_display_device = display_device;
      return true;
    }
  }
  return false;
}

HRESULT CheckPathInfoForInternal(const PCWSTR device_name) {
  HRESULT hr = S_OK;
  UINT32 path_info_array_size = 0;
  UINT32 mode_info_array_size = 0;
  DISPLAYCONFIG_PATH_INFO* path_info_array = nullptr;
  DISPLAYCONFIG_MODE_INFO* mode_info_array = nullptr;

  do {
    // In case this isn't the first time through the loop, delete the buffers
    // allocated.
    delete[] path_info_array;
    path_info_array = nullptr;

    delete[] mode_info_array;
    mode_info_array = nullptr;

    hr = HRESULT_FROM_WIN32(::GetDisplayConfigBufferSizes(
        QDC_ONLY_ACTIVE_PATHS, &path_info_array_size, &mode_info_array_size));
    if (FAILED(hr)) {
      break;
    }

    path_info_array =
        new (std::nothrow) DISPLAYCONFIG_PATH_INFO[path_info_array_size];
    if (path_info_array == nullptr) {
      hr = E_OUTOFMEMORY;
      break;
    }

    mode_info_array =
        new (std::nothrow) DISPLAYCONFIG_MODE_INFO[mode_info_array_size];
    if (mode_info_array == nullptr) {
      hr = E_OUTOFMEMORY;
      break;
    }

    hr = HRESULT_FROM_WIN32(::QueryDisplayConfig(
        QDC_ONLY_ACTIVE_PATHS, &path_info_array_size, path_info_array,
        &mode_info_array_size, mode_info_array, nullptr));
  } while (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));

  int desired_path_index = -1;
  if (SUCCEEDED(hr)) {
    // Loop through all sources until the one which matches the |device_name|
    // is found.
    for (UINT32 path_index = 0; path_index < path_info_array_size;
         ++path_index) {
      DISPLAYCONFIG_SOURCE_DEVICE_NAME source_name = {};
      source_name.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
      source_name.header.size = sizeof(source_name);
      source_name.header.adapterId =
          path_info_array[path_index].sourceInfo.adapterId;
      source_name.header.id = path_info_array[path_index].sourceInfo.id;

      hr =
          HRESULT_FROM_WIN32(::DisplayConfigGetDeviceInfo(&source_name.header));
      if (SUCCEEDED(hr)) {
        if (wcscmp(device_name, source_name.viewGdiDeviceName) == 0 &&
            IsInternalVideoOutput(
                path_info_array[path_index].targetInfo.outputTechnology)) {
          desired_path_index = path_index;
          break;
        }
      }
    }
  }

  if (desired_path_index == -1) {
    hr = E_INVALIDARG;
  }

  delete[] path_info_array;
  path_info_array = nullptr;

  delete[] mode_info_array;
  mode_info_array = nullptr;

  return hr;
}

bool IsInternalVideoOutput(
    const DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY video_output_tech_type) {
  switch (video_output_tech_type) {
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL:
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED:
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED:
      return TRUE;

    default:
      return FALSE;
  }
}

}  // namespace media
