import type { HybridObject } from 'react-native-nitro-modules';
import type { CameraPosition } from '../common-types/CameraPosition';
import type { DeviceType } from '../common-types/DeviceType';
import type { DynamicRange } from '../common-types/DynamicRange';
import type { MediaType } from '../common-types/MediaType';
import type { OutputStreamType } from '../common-types/OutputStreamType';
import type { PixelFormat } from '../common-types/PixelFormat';
import type { Range } from '../common-types/Range';
import type { Size } from '../common-types/Size';
import type { TargetStabilizationMode } from '../common-types/StabilizationMode';
import type { CameraOutput } from '../outputs/CameraOutput.nitro';
import type { CameraSessionConfig } from '../session/CameraSessionConfig.nitro';
/**
 * The {@linkcode CameraDevice} represents a physical- or
 * virtual Camera Device.
 *
 * Examples:
 * - Physical: The 0.5x ultra-wide-angle Camera
 * - Virtual: The Triple-Camera consisting of the 0.5x, the 1x, and the 3x Camera
 * - TrueDepth Face ID: A virtual Camera consisting of a color, and a depth Camera
 */
export interface CameraDevice extends HybridObject<{
    ios: 'swift';
    android: 'kotlin';
}> {
    /**
     * A unique identifier for this camera device.
     */
    readonly id: string;
    /**
     * The model identifier for this camera device.
     */
    readonly modelID: string;
    /**
     * A user friendly camera name shown by the system.
     */
    readonly localizedName: string;
    /**
     * The hardware manufacturer name for this device.
     */
    readonly manufacturer: string;
    /**
     * The camera hardware type, for example
     * {@linkcode DeviceType | 'wide-angle'}.
     */
    readonly type: DeviceType;
    /**
     * The position of this camera on the device.
     */
    readonly position: CameraPosition;
    /**
     * If this {@linkcode CameraDevice} is a virtual
     * device (see {@linkcode isVirtualDevice}), this
     * property contains a list of all constituent
     * physical devices this virtual device is made of.
     *
     * For physical devices, this returns an empty array.
     */
    readonly physicalDevices: CameraDevice[];
    /**
     * Gets whether this {@linkcode CameraDevice}
     * is a virtual device, which consists of two or
     * more physical {@linkcode CameraDevice}s.
     *
     * Devices like the "Triple-Camera" (0.5x + 1x + 3x)
     * or the "FaceID Camera" (color + depth) are virtual
     * devices.
     *
     * To access the individual physical devices
     * a virtual device consists of, use {@linkcode physicalDevices}.
     */
    readonly isVirtualDevice: boolean;
    /**
     * Get a list of all supported {@linkcode PixelFormat}s this
     * {@linkcode CameraDevice} can stream in.
     */
    readonly supportedPixelFormats: PixelFormat[];
    /**
     * Get a list of all supported resolutions this {@linkcode CameraDevice}
     * can produce for outputs of the given {@linkcode OutputStreamType}.
     *
     * If a given {@linkcode OutputStreamType} can not be streamed to at
     * all, an empty array (`[]`) will be returned.
     *
     * @discussion
     * While a {@linkcode CameraDevice} may be able to stream in the
     * given output resolutions individually, it is not guaranteed that
     * all resolutions are available when streaming to multiple
     * {@linkcode CameraOutput} with multiple {@linkcode Constraint}s
     * enabled.
     *
     * The {@linkcode CameraSession} internally negotiates available
     * output resolutions based on {@linkcode Constraint}s, and potentially
     * downgrades (or upgrades) target resolutions if needed.
     *
     * @see {@linkcode VideoOutputOptions.targetResolution}
     * @see {@linkcode PhotoOutputOptions.targetResolution}
     * @see {@linkcode FrameOutputOptions.targetResolution}
     * @see {@linkcode DepthFrameOutputOptions.targetResolution}
     * @see {@linkcode ResolutionBiasConstraint}
     *
     * @example
     * Get all resolutions for Photo capture:
     * ```ts
     * const device = ...
     * const resolutions = device.getSupportedResolutions('photo')
     * ```
     */
    getSupportedResolutions(outputStreamType: OutputStreamType): Size[];
    /**
     * Returns whether this {@linkcode CameraDevice}
     * supports streaming to the given {@linkcode output}.
     *
     * @discussion
     * Usually, a {@linkcode CameraDevice} can stream to all
     * {@linkcode CameraOutput}s, with very rare exceptions.
     *
     * For example, Depth Frame Outputs ({@linkcode CameraDepthFrameOutput})
     * may not be supported on all {@linkcode CameraDevice}s - see
     * {@linkcode mediaTypes}.
     */
    supportsOutput(output: CameraOutput): boolean;
    /**
     * Gets whether this {@linkcode CameraDevice}
     * supports capturing Photos in High Dynamic Range (HDR).
     *
     * @discussion
     * Photo HDR captures multiple images in various
     * exposure settings (often one under-exposed, one
     * over-exposed and one perfectly exposed), and fuses
     * the images together into a single image with a wider
     * range of colors, which results in darker blacks and
     * brighter whites.
     *
     * @discussion
     * While a device may support Photo HDR individually,
     * it is not guaranteed to be supported with all
     * possible feature and output combinations.
     *
     * The {@linkcode Constraint} API (specifically {@linkcode PhotoHDRConstraint})
     * internally negotiates the target Photo HDR preference with
     * other enabled features (such as {@linkcode ResolutionBiasConstraint})
     * and all connected {@linkcode CameraOutput}s to find a best-matching
     * supported combination on this device.
     *
     * Alternatively, to find out if a specific combination is supported upfront,
     * use the {@linkcode isSessionConfigSupported | isSessionConfigSupported(...)}
     * method with your desired outputs and constraints applied.
     *
     * @see {@linkcode PhotoHDRConstraint.photoHDR}
     * @see {@linkcode CameraPhotoOutput}
     */
    readonly supportsPhotoHDR: boolean;
    /**
     * Get a list of all {@linkcode DynamicRange}s this
     * {@linkcode CameraDevice} supports streaming at,
     * often affecting both Video recordings and Preview.
     *
     * @discussion
     * Unlike Photo HDR, Video Dynamic Ranges are not
     * only extra processing, but often entirely different
     * sensor readouts.
     * While Photo HDR might capture multiple bracketed Photos
     * to fuse them together to expose more colors, Video
     * Dynamic Ranges sometimes stream in an entirely different
     * Pixel Format (e.g. 10-bit instead of 8-bit), and use
     * a different YUV Transfer Matrix to compose pixels from
     * sensor data.
     *
     * @discussion
     * While a device may support a given {@linkcode DynamicRange}
     * individually, it is not guaranteed to be supported with all
     * possible feature and output combinations.
     *
     * The {@linkcode Constraint} API (specifically {@linkcode VideoDynamicRangeConstraint})
     * internally negotiates the target Dynamic Range with
     * other enabled features (such as {@linkcode ResolutionBiasConstraint} or
     * {@linkcode FPSConstraint}) and all connected {@linkcode CameraOutput}s
     * to find a best-matching supported combination on this device.
     *
     * Alternatively, to find out if a specific combination is supported upfront,
     * use the {@linkcode isSessionConfigSupported | isSessionConfigSupported(...)}
     * method with your desired outputs and constraints applied.
     *
     * @see {@linkcode VideoDynamicRangeConstraint.videoDynamicRange}
     * @see {@linkcode CameraVideoOutput}
     */
    readonly supportedVideoDynamicRanges: DynamicRange[];
    /**
     * Gets all available Frame Rate Ranges this
     * {@linkcode CameraDevice} supports individually.
     *
     * Frame Rates are expressed in FPS (Frames per Second),
     * for example `60` refers to 60 FPS (= 16.666ms per Frame).
     *
     * @discussion
     * Use {@linkcode supportsFPS | supportsFPS(...)} as a convenience
     * method to find out if a given fixed frame rate is supported
     * individually.
     *
     * @discussion
     * While a device may support a given FPS {@linkcode Range}
     * individually, it is not guaranteed to be supported with all
     * possible feature and output combinations.
     *
     * The {@linkcode Constraint} API (specifically {@linkcode FPSConstraint})
     * internally negotiates the target {@linkcode FPSConstraint.fps | fps}
     * with other enabled features (such as {@linkcode VideoStabilizationModeConstraint})
     * and all connected {@linkcode CameraOutput}s to find a best-matching
     * supported combination on this device.
     *
     * Alternatively, to find out if a specific combination is supported upfront,
     * use the {@linkcode isSessionConfigSupported | isSessionConfigSupported(...)}
     * method with your desired outputs and constraints applied.
     */
    readonly supportedFPSRanges: Range[];
    /**
     * Gets whether the given {@linkcode fps} is individually supported
     * by any of the {@linkcode supportedFPSRanges} on this {@linkcode CameraDevice}.
     *
     * @discussion
     * While a device may support a given FPS {@linkcode Range}
     * individually, it is not guaranteed to be supported with all
     * possible feature and output combinations.
     *
     * The {@linkcode Constraint} API (specifically {@linkcode FPSConstraint})
     * internally negotiates the target {@linkcode FPSConstraint.fps | fps}
     * with other enabled features (such as {@linkcode VideoStabilizationModeConstraint})
     * and all connected {@linkcode CameraOutput}s to find a best-matching
     * supported combination on this device.
     *
     * Alternatively, to find out if a specific combination is supported upfront,
     * use the {@linkcode isSessionConfigSupported | isSessionConfigSupported(...)}
     * method with your desired outputs and constraints applied.
     *
     * @see {@linkcode supportedFPSRanges}
     */
    supportsFPS(fps: number): boolean;
    /**
     * Returns whether this {@linkcode CameraDevice} supports
     * the given {@linkcode StabilizationMode} for video streams
     * (e.g. {@linkcode CameraVideoOutput}).
     *
     * @discussion
     * While a device may support a given {@linkcode StabilizationMode}
     * individually, it is not guaranteed to be supported with all
     * possible feature and output combinations.
     *
     * The {@linkcode Constraint} API (specifically
     * {@linkcode VideoStabilizationModeConstraint}) internally
     * negotiates the target {@linkcode VideoStabilizationModeConstraint.videoStabilizationMode | videoStabilizationMode}
     * with other enabled features (such as {@linkcode FPSConstraint}) and
     * all connected {@linkcode CameraOutput}s to find a best-matching
     * supported combination on this device.
     *
     * Alternatively, to find out if a specific combination is supported upfront,
     * use the {@linkcode isSessionConfigSupported | isSessionConfigSupported(...)}
     * method with your desired outputs and constraints applied.
     */
    supportsVideoStabilizationMode(videoStabilizationMode: TargetStabilizationMode): boolean;
    /**
     * Returns whether this {@linkcode CameraDevice} supports
     * the given {@linkcode StabilizationMode} for preview streams
     * (e.g. {@linkcode CameraPreviewOutput}).
     *
     * @discussion
     * While a device may support a given {@linkcode StabilizationMode}
     * individually, it is not guaranteed to be supported with all
     * possible feature and output combinations.
     *
     * The {@linkcode Constraint} API (specifically
     * {@linkcode PreviewStabilizationModeConstraint}) internally
     * negotiates the target {@linkcode PreviewStabilizationModeConstraint.previewStabilizationMode | previewStabilizationMode}
     * with other enabled features (such as {@linkcode FPSConstraint}) and
     * all connected {@linkcode CameraOutput}s to find a best-matching
     * supported combination on this device.
     *
     * Alternatively, to find out if a specific combination is supported upfront,
     * use the {@linkcode isSessionConfigSupported | isSessionConfigSupported(...)}
     * method with your desired outputs and constraints applied.
     */
    supportsPreviewStabilizationMode(previewStabilizationMode: TargetStabilizationMode): boolean;
    /**
     * Returns `true` if this {@linkcode CameraDevice} supports
     * delivering preview {@linkcode Image} instances before
     * the actual {@linkcode Photo} is available.
     *
     * On iOS, this is always `true`.
     *
     * @see {@linkcode PhotoOutputOptions.previewImageTargetSize}
     * @see {@linkcode CapturePhotoCallbacks.onPreviewImageAvailable}
     */
    readonly supportsPreviewImage: boolean;
    /**
     * Returns `true` if this {@linkcode CameraDevice} supports
     * capturing photos with the {@linkcode QualityPrioritization | 'speed'}
     * {@linkcode QualityPrioritization}.
     *
     * @see {@linkcode PhotoOutputOptions.qualityPrioritization}
     */
    readonly supportsSpeedQualityPrioritization: boolean;
    /**
     * Returns the Camera Device's nominal focal length in 35mm film format.
     */
    readonly focalLength?: number;
    /**
     * The size (ƒ number) of the lens diaphragm.
     */
    readonly lensAperture: number;
    /**
     * Returns `true` if this camera is a Continuity Camera.
     * On non iOS platforms this is always `false`.
     *
     * @platform iOS
     */
    readonly isContinuityCamera: boolean;
    /**
     * The matching Desk View camera for this Continuity Camera, if available.
     *
     * @platform iOS
     */
    readonly companionDeskViewCamera?: CameraDevice;
    /**
     * Represents all {@linkcode MediaType}s this
     * {@linkcode CameraDevice} can capture.
     *
     * Most Cameras return {@linkcode MediaType | ['video']}.
     * Virtual Cameras that also support Depth Capture return {@linkcode MediaType | ['video', 'depth']}.
     */
    readonly mediaTypes: MediaType[];
    /**
     * Gets whether this {@linkcode CameraDevice}
     * supports metering auto-focus ({@linkcode MeteringMode | 'AF'})
     * via {@linkcode CameraController.focusTo | focusTo(...)}.
     */
    readonly supportsFocusMetering: boolean;
    /**
     * Gets whether this {@linkcode CameraDevice}
     * supports manual focus via
     * {@linkcode CameraController.setFocusLocked | setFocusLocked(...)}.
     */
    readonly supportsFocusLocking: boolean;
    /**
     * Gets whether this {@linkcode CameraDevice}
     * supports smoothly adjusting focus via
     * {@linkcode CameraControllerConfiguration.enableSmoothAutoFocus}.
     *
     * @example
     * ```ts
     * await controller.configure({
     *   enableSmoothAutoFocus: device.supportsSmoothAutoFocus
     * })
     * ```
     */
    readonly supportsSmoothAutoFocus: boolean;
    /**
     * Gets whether this {@linkcode CameraDevice}
     * supports metering auto-exposure ({@linkcode MeteringMode | 'AE'})
     * via {@linkcode CameraController.focusTo | focusTo(...)}.
     */
    readonly supportsExposureMetering: boolean;
    /**
     * Gets whether this {@linkcode CameraDevice}
     * supports manual exposure via
     * {@linkcode CameraController.setExposureLocked | setExposureLocked(...)}.
     */
    readonly supportsExposureLocking: boolean;
    /**
     * Gets whether this {@linkcode CameraDevice}
     * supports biasing auto-exposure via
     * {@linkcode CameraController.setExposureBias | setExposureBias(...)}.
     */
    readonly supportsExposureBias: boolean;
    /**
     * Gets the minimum supported value for
     * the exposure bias (in EV units), or `0`
     * if {@linkcode supportsExposureBias} is false.
     */
    readonly minExposureBias: number;
    /**
     * Gets the maximum supported value for
     * the exposure bias (in EV units), or `0`
     * if {@linkcode supportsExposureBias} is false.
     */
    readonly maxExposureBias: number;
    /**
     * Gets whether this {@linkcode CameraDevice}
     * supports metering auto-white-balance ({@linkcode MeteringMode | 'AWB'})
     * via {@linkcode CameraController.focusTo | focusTo(...)}.
     */
    readonly supportsWhiteBalanceMetering: boolean;
    /**
     * The maximum value a single color-channel can be
     * set to in {@linkcode WhiteBalanceGains}, or `0`
     * if {@linkcode supportsWhiteBalanceLocking} is `false`.
     */
    readonly maxWhiteBalanceGain: number;
    /**
     * Gets whether this {@linkcode CameraDevice}
     * supports manual white-balance via
     * {@linkcode CameraController.setWhiteBalanceLocked | setWhiteBalanceLocked(...)}.
     *
     * @see {@linkcode maxWhiteBalanceGain}
     */
    readonly supportsWhiteBalanceLocking: boolean;
    /**
     * Whether this {@linkcode CameraDevice} has a
     * physical flash unit, or not.
     *
     * For {@linkcode CameraPosition | front}-facing
     * devices, {@linkcode hasFlash} may be `false`,
     * but you might still be able to use a screen-
     * flash for photo capture.
     *
     * @see {@linkcode CapturePhotoSettings.flashMode}
     */
    readonly hasFlash: boolean;
    /**
     * Whether this {@linkcode CameraDevice} supports
     * using its flash ({@linkcode hasFlash}) as a
     * continuous light (_"torch"_) while the session is running.
     *
     * In almost all cases, {@linkcode hasTorch} is the
     * same as {@linkcode hasFlash}.
     *
     * Use {@linkcode supportsTorchStrength} to find out whether
     * the torch additionally accepts a custom brightness level
     * via {@linkcode CameraController.enableTorchWithStrength | enableTorchWithStrength(...)}.
     *
     * @see {@linkcode CameraController.setTorchMode | setTorchMode(...)}
     * @see {@linkcode supportsTorchStrength}
     */
    readonly hasTorch: boolean;
    /**
     * Whether this {@linkcode CameraDevice} supports configuring
     * a custom torch brightness level via
     * {@linkcode CameraController.enableTorchWithStrength | enableTorchWithStrength(...)}.
     *
     * @discussion
     * Many devices with a {@linkcode hasTorch | torch} can only
     * toggle the torch on or off and do not expose a brightness
     * level - calling
     * {@linkcode CameraController.enableTorchWithStrength | enableTorchWithStrength(...)}
     * on such a device will fail. Use
     * {@linkcode CameraController.setTorchMode | setTorchMode('on')}
     * instead to turn the torch on at the system default level.
     *
     * @see {@linkcode hasTorch}
     * @see {@linkcode CameraController.enableTorchWithStrength | enableTorchWithStrength(...)}
     */
    readonly supportsTorchStrength: boolean;
    /**
     * Gets the minimum supported torch strength for this device,
     * or `0` if {@linkcode supportsTorchStrength} is false.
     *
     * Use {@linkcode CameraController.enableTorchWithStrength | enableTorchWithStrength(...)}
     * to set the torch strength.
     *
     * @see {@linkcode supportsTorchStrength}
     * @see {@linkcode maxTorchStrength}
     */
    readonly minTorchStrength: number;
    /**
     * Gets the maximum supported torch strength for this device,
     * or `0` if {@linkcode supportsTorchStrength} is false.
     *
     * Use {@linkcode CameraController.enableTorchWithStrength | enableTorchWithStrength(...)}
     * to set the torch strength.
     *
     * @see {@linkcode supportsTorchStrength}
     * @see {@linkcode minTorchStrength}
     */
    readonly maxTorchStrength: number;
    /**
     * Whether this {@linkcode CameraDevice} supports
     * enabling low-light boost to improve exposure in
     * dark scenes via {@linkcode CameraControllerConfiguration.enableLowLightBoost}.
     *
     * @example
     * ```ts
     * await controller.configure({
     *   enableLowLightBoost: device.supportsLowLightBoost
     * })
     * ```
     */
    readonly supportsLowLightBoost: boolean;
    /**
     * The minimum individually supported zoom value of this device.
     *
     * @note Depending on the {@linkcode Constraint}s and
     * {@linkcode CameraOutput}s configured on the
     * {@linkcode CameraSession}, the actual minimum zoom
     * value may change.
     * Inspect the returned {@linkcode CameraController}'s
     * {@linkcode CameraController.minZoom | minZoom} property
     * for a true current minimum.
     */
    readonly minZoom: number;
    /**
     * The maximum individually supported zoom value of this device.
     *
     * @note Depending on the {@linkcode Constraint}s and
     * {@linkcode CameraOutput}s configured on the
     * {@linkcode CameraSession}, the actual maximum zoom
     * value may change.
     * Inspect the returned {@linkcode CameraController}'s
     * {@linkcode CameraController.maxZoom | maxZoom} property
     * for a true current maximum.
     */
    readonly maxZoom: number;
    /**
     * If this {@linkcode CameraDevice} is a virtual device,
     * this returns a list of zoom factors at which the virtual
     * device may switch to another physical camera.
     *
     * For physical devices, this returns an empty array.
     *
     * @example
     * ```ts
     * const camera = ...           // Triple-Camera (0.5x, 1x, 3x)
     * camera.zoomLensSwitchFactors // [1, 3]
     * ```
     */
    readonly zoomLensSwitchFactors: number[];
    /**
     * Whether the {@linkcode CameraDevice} supports
     * distortion correction to correct stretched edges
     * in wide-angle Cameras during Photo capture.
     * @see {@linkcode CapturePhotoSettings.enableDistortionCorrection}
     */
    readonly supportsDistortionCorrection: boolean;
    /**
     * Returns whether the given {@linkcode CameraSessionConfig}
     * is supported by this {@linkcode CameraDevice}, or not.
     *
     * If this method returns `false`, configuring a
     * {@linkcode CameraSession} with this {@linkcode CameraSessionConfig}
     * will fail.
     */
    isSessionConfigSupported(config: CameraSessionConfig): boolean;
}
