import type { Image } from 'react-native-nitro-image';
import type { HybridObject } from 'react-native-nitro-modules';
import type { CameraOrientation } from '../common-types/CameraOrientation';
import type { PhotoContainerFormat } from '../common-types/PhotoContainerFormat';
import type { CameraCalibrationData } from './CameraCalibrationData.nitro';
import type { Depth } from './Depth.nitro';
/**
 * Represents a captured {@linkcode Photo} in-memory.
 *
 * {@linkcode Photo | Photos} can be captured with
 * a {@linkcode CameraPhotoOutput}, and can be saved
 * to a file using {@linkcode Photo.saveToTemporaryFileAsync | saveToTemporaryFileAsync()}.
 *
 * To display the photo to the user, use
 * {@linkcode Photo.toImageAsync | toImageAsync()}, then
 * display that using `react-native-nitro-image`'s
 * `<NitroImage />` component.
 *
 * @note
 * As with all in-memory objects holding large native memory
 * such as Photos, Frames, Images or more, make sure to
 * {@linkcode Photo.dispose | dispose()} the Photo once you
 * are no longer using it, as otherwise the JS Runtime might
 * not immediately delete it, possibly exhausting system resources.
 *
 * @example
 * Display the Photo to the user using `react-native-nitro-image`:
 * ```tsx
 * const photoOutput = ...
 * const [image, setImage] = useState<Image>()
 *
 * const takePhoto = async () => {
 *   const photo = await photoOutput.capturePhoto({}, {})
 *   const img = await photo.toImageAsync()
 *   setImage(img)
 *   photo.dispose()
 * }
 *
 * return <NitroImage style={{ flex: 1 }} image={image} />
 * ```
 * @example
 * Save the photo to a temporary file:
 * ```ts
 * const photoOutput = ...
 *
 * const takePhoto = async () => {
 *   const photo = await photoOutput.capturePhoto({}, {})
 *   const image = await photo.toImageAsync()
 *   photo.dispose()
 * }
 * ```
 * @example
 * Convert the Photo to a Skia Image:
 * ```ts
 * const photoOutput = ...
 * const photo = await photoOutput.capturePhoto({}, {})
 * const encodedData = await photo.getFileDataAsync()
 * const bytes = new Uint8Array(encodedData)
 * const data = Skia.Data.fromBytes(bytes)
 * const skiaImage = Skia.Image.MakeImageFromEncoded(data)
 * photo.dispose()
 * ```
 */
export interface Photo extends HybridObject<{
    ios: 'swift';
    android: 'kotlin';
}> {
    /**
     * Gets whether this {@linkcode Photo} is mirrored alongside the
     * vertical axis.
     */
    readonly isMirrored: boolean;
    /**
     * Gets the {@linkcode CameraOrientation} this {@linkcode Photo} was
     * captured in.
     *
     * {@linkcode CameraOrientation} will be applied lazily via EXIF
     * flags, or when converting the {@linkcode Photo} to an
     * {@linkcode Image}.
     */
    readonly orientation: CameraOrientation;
    /**
     * Represents the timestamp this {@linkcode Photo} was
     * captured at, using the system's host clock, in seconds.
     */
    readonly timestamp: number;
    /**
     * Gets whether this {@linkcode Photo} is a RAW photo (i.e.
     * no processing has been applied), or a processed photo (e.g.
     * JPEG).
     * @see {@linkcode containerFormat}
     */
    readonly isRawPhoto: boolean;
    /**
     * Get the width of this {@linkcode Photo}, in pixels.
     */
    readonly width: number;
    /**
     * Get the height of this {@linkcode Photo}, in pixels.
     */
    readonly height: number;
    /**
     * Get the {@linkcode PhotoContainerFormat} of
     * this {@linkcode Photo}.
     */
    readonly containerFormat: PhotoContainerFormat;
    /**
     * Get whether this {@linkcode Photo} has
     * a native pixel buffer attached to it,
     * which allows reading its pixels from JS.
     * @see {@linkcode getPixelBuffer | getPixelBuffer()}
     */
    readonly hasPixelBuffer: boolean;
    /**
     * Get the {@linkcode Photo}'s native pixel
     * buffer. This allows readonly access
     * to the individual pixels.
     *
     * This does not contain any EXIF data.
     * @throws If {@linkcode hasPixelBuffer} is false.
     */
    getPixelBuffer(): ArrayBuffer;
    /**
     * Get the associated {@linkcode Depth} data
     * for this {@linkcode Photo} if it has one.
     * @see {@linkcode CapturePhotoSettings.enableDepthData}
     */
    readonly depth?: Depth;
    /**
     * Get the associated {@linkcode CameraCalibrationData}
     * for this {@linkcode Photo} if calibration data delivery
     * was enabled.
     *
     * @see {@linkcode CapturePhotoSettings.enableCameraCalibrationDataDelivery}
     * @platform iOS
     */
    readonly calibrationData?: CameraCalibrationData;
    /**
     * Asynchronously saves this {@linkcode Photo} to
     * a file at the given {@linkcode path}, using this
     * {@linkcode containerFormat}.
     *
     * @param path The path to save the Image to.
     * Must contain a full path name including filename
     * and extension. All parent directories must exist,
     * but the file itself must not exist.
     * This must be a filesystem path, not a `file://` URL.
     */
    saveToFileAsync(path: string): Promise<void>;
    /**
     * Asynchronously saves this {@linkcode Photo} to
     * a temporary file using this {@linkcode containerFormat},
     * and returns the path it was saved at.
     *
     * The returned value is a filesystem path, not a `file://` URL.
     */
    saveToTemporaryFileAsync(): Promise<string>;
    /**
     * Gets the raw file data of the {@linkcode Photo} after
     * processing and including EXIF flags.
     */
    getFileData(): ArrayBuffer;
    /**
     * Asynchronously gets the raw file data of
     * the {@linkcode Photo} after processing
     * and including EXIF flags.
     */
    getFileDataAsync(): Promise<ArrayBuffer>;
    /**
     * Converts this {@linkcode Photo} to an {@linkcode Image},
     * possibly applying {@linkcode orientation} and {@linkcode isMirrored}
     * settings.
     * @throws If the {@linkcode Photo} is a raw photo (see {@linkcode isRawPhoto})
     * @throws If the {@linkcode Photo}'s Image data cannot be accessed
     */
    toImage(): Image;
    /**
     * Asynchronously converts this {@linkcode Photo} to an {@linkcode Image},
     * possibly applying {@linkcode orientation} and {@linkcode isMirrored}
     * settings.
     * @throws If the {@linkcode Photo} is a raw photo (see {@linkcode isRawPhoto})
     * @throws If the {@linkcode Photo}'s Image data cannot be accessed
     */
    toImageAsync(): Promise<Image>;
}
