import koffi from 'koffi';

interface GphotoLoadOptions {
    libgphoto2Paths?: string[];
    libcPaths?: string[];
}
declare enum WidgetType {
    Window = 0,
    Section = 1,
    Text = 2,
    Range = 3,
    Toggle = 4,
    Radio = 5,
    Menu = 6,
    Button = 7,
    Date = 8
}
interface CameraInfo {
    name: string;
    port: string;
}
interface CameraFilePath {
    name: string;
    folder: string;
}
declare enum CameraEventType {
    Unknown = 0,
    Timeout = 1,
    FileAdded = 2,
    FolderAdded = 3,
    CaptureComplete = 4,
    FileChanged = 5
}
interface CameraEventUnknown {
    type: CameraEventType.Unknown;
}
interface CameraEventTimeout {
    type: CameraEventType.Timeout;
}
interface CameraEventFileAdded {
    type: CameraEventType.FileAdded;
    path: CameraFilePath;
}
interface CameraEventFolderAdded {
    type: CameraEventType.FolderAdded;
    path: CameraFilePath;
}
interface CameraEventCaptureComplete {
    type: CameraEventType.CaptureComplete;
}
interface CameraEventFileChanged {
    type: CameraEventType.FileChanged;
    path: CameraFilePath;
}
type CameraEvent = CameraEventUnknown | CameraEventTimeout | CameraEventFileAdded | CameraEventFolderAdded | CameraEventCaptureComplete | CameraEventFileChanged;
declare enum LoggingLevel {
    Error = 0,
    Verbose = 1,
    Debug = 2,
    Data = 3
}
interface CameraModule {
    listAsync(): Promise<CameraInfo[]>;
    openAsync(camera: CameraInfo): Promise<void>;
    closeAsync(cameraInfo: CameraInfo): Promise<boolean>;
    summaryAsync(cameraInfo: CameraInfo): Promise<string>;
    triggerCaptureAsync(cameraInfo: CameraInfo): Promise<void>;
    triggerCapturePreviewAsync(cameraInfo: CameraInfo): Promise<{
        data: Uint8Array;
        size: number;
        mimeType: string;
    }>;
    getConfigAsync(cameraInfo: CameraInfo, options?: {
        /**
         * Supply a function to filter which config items will be returned. Return true to include the item, false to exclude it.
         */
        filter?: (name: string, type: WidgetType) => boolean;
        /**
         * Set to true to only include config which which are not read only
         */
        ignoreReadOnly?: boolean;
    }): Promise<{
        [key: string]: string | number | boolean;
    }>;
    getConfigWidgetsAsync(cameraInfo: CameraInfo, options?: {
        /**
         * Supply a function to filter which config items will be returned. Return true to include the item, false to exclude it.
         */
        filter?: (name: string, type: WidgetType) => boolean;
        /**
         * Set to true to only include config which which are not read only
         */
        ignoreReadOnly?: boolean;
    }): Promise<{
        [key: string]: ConfigWidget;
    }>;
    setConfigAsync(cameraInfo: CameraInfo, newConfig: {
        [key: string]: string | number | boolean;
    }, options?: {
        ignoreErrors?: boolean;
    }): Promise<void>;
    waitForEventAsync(cameraInfo: CameraInfo, timeoutMilliseconds: number): Promise<CameraEvent>;
    getFileAsync(cameraInfo: CameraInfo, cameraFilePath: CameraFilePath, targetFilePath: string): Promise<void>;
    addLogFunc(level: LoggingLevel, loggingFn: (level: LoggingLevel, domain: string, message: string) => void): Promise<() => void>;
}
interface TextConfigWidget {
    type: WidgetType.Text;
    label: string;
    value: string;
}
interface RangeConfigWidget {
    type: WidgetType.Range;
    label: string;
    value: number;
    min: number;
    max: number;
    increment: number;
}
interface ToggleConfigWidget {
    type: WidgetType.Toggle;
    label: string;
    value: boolean;
}
interface ChoiceConfigWidget {
    type: WidgetType.Radio | WidgetType.Menu;
    label: string;
    value: string;
    choices: string[];
}
type ConfigWidget = TextConfigWidget | RangeConfigWidget | ToggleConfigWidget | ChoiceConfigWidget;

/**
 * Get the library, setting it up if needed
 */
declare const getFfi: (options: Required<GphotoLoadOptions>) => {
    CameraList: koffi.IKoffiCType;
    Camera: koffi.IKoffiCType;
    CameraAbilitiesList: koffi.IKoffiCType;
    CameraAbilities: koffi.IKoffiCType;
    CameraText: koffi.IKoffiCType;
    GPPortInfoList: koffi.IKoffiCType;
    GPPortInfo: koffi.IKoffiCType;
    CameraEventType: koffi.IKoffiCType;
    CameraFileType: koffi.IKoffiCType;
    CameraFilePath: koffi.IKoffiCType;
    CameraFile: koffi.IKoffiCType;
    CameraWidget: koffi.IKoffiCType;
    CameraWidgetType: koffi.IKoffiCType;
    GPContextIdleFunc: koffi.IKoffiCType;
    GPContextProgressStartFunc: koffi.IKoffiCType;
    GPContextProgressUpdateFunc: koffi.IKoffiCType;
    GPContextProgressStopFunc: koffi.IKoffiCType;
    GPContextErrorFunc: koffi.IKoffiCType;
    GPContextQuestionFunc: koffi.IKoffiCType;
    GPContextCancelFunc: koffi.IKoffiCType;
    GPContextStatusFunc: koffi.IKoffiCType;
    GPContextMessageFunc: koffi.IKoffiCType;
    GPContext: koffi.IKoffiCType;
    GPLogFunc: koffi.IKoffiCType;
} & {
    gp_abilities_list_new: (...args: unknown[]) => Promise<number>;
    gp_abilities_list_load: (...args: unknown[]) => Promise<number>;
    gp_abilities_list_lookup_model: (...args: unknown[]) => Promise<number>;
    gp_abilities_list_get_abilities: (...args: unknown[]) => Promise<number>;
    gp_abilities_list_free: (...args: unknown[]) => Promise<number>;
    gp_port_info_list_new: (...args: unknown[]) => Promise<number>;
    gp_port_info_list_load: (...args: unknown[]) => Promise<number>;
    gp_port_info_list_lookup_path: (...args: unknown[]) => Promise<number>;
    gp_port_info_list_get_info: (...args: unknown[]) => Promise<number>;
    gp_port_info_list_free: (...args: unknown[]) => Promise<number>;
    gp_context_new: (...args: unknown[]) => Promise<unknown>;
    gp_list_new: (...args: unknown[]) => Promise<number>;
    gp_list_unref: (...args: unknown[]) => Promise<number>;
    gp_list_count: (...args: unknown[]) => Promise<number>;
    gp_list_get_name: (...args: unknown[]) => Promise<number>;
    gp_list_get_value: (...args: unknown[]) => Promise<number>;
    gp_camera_autodetect: (...args: unknown[]) => Promise<number>;
    gp_camera_new: (...args: unknown[]) => Promise<number>;
    gp_camera_set_abilities: (...args: unknown[]) => Promise<number>;
    gp_camera_set_port_info: (...args: unknown[]) => Promise<number>;
    gp_camera_init: (...args: unknown[]) => Promise<number>;
    gp_camera_get_summary: (...args: unknown[]) => Promise<number>;
    gp_camera_trigger_capture: (...args: unknown[]) => Promise<number>;
    gp_camera_capture_preview: (...args: unknown[]) => Promise<number>;
    gp_camera_wait_for_event: (...args: unknown[]) => Promise<number>;
    gp_camera_file_get: (...args: unknown[]) => Promise<number>;
    gp_camera_file_delete: (...args: unknown[]) => Promise<number>;
    gp_camera_get_config: (...args: unknown[]) => Promise<number>;
    gp_camera_set_config: (...args: unknown[]) => Promise<number>;
    gp_camera_exit: (...args: unknown[]) => Promise<number>;
    gp_camera_unref: (...args: unknown[]) => Promise<number>;
    gp_widget_count_children: (...args: unknown[]) => Promise<number>;
    gp_widget_get_child: (...args: unknown[]) => Promise<number>;
    gp_widget_get_child_by_name: (...args: unknown[]) => Promise<number>;
    gp_widget_get_child_by_label: (...args: unknown[]) => Promise<number>;
    gp_widget_get_name: (...args: unknown[]) => Promise<number>;
    gp_widget_get_label: (...args: unknown[]) => Promise<number>;
    gp_widget_get_readonly: (...args: unknown[]) => Promise<number>;
    gp_widget_get_type: (...args: unknown[]) => Promise<number>;
    gp_widget_get_range: (...args: unknown[]) => Promise<number>;
    gp_widget_count_choices: (...args: unknown[]) => Promise<number>;
    gp_widget_get_choice: (...args: unknown[]) => Promise<number>;
    gp_widget_get_value_string: (...args: unknown[]) => Promise<number>;
    gp_widget_get_value_float: (...args: unknown[]) => Promise<number>;
    gp_widget_set_value: (...args: unknown[]) => Promise<number>;
    gp_widget_unref: (...args: unknown[]) => Promise<number>;
    gp_file_new: (...args: unknown[]) => Promise<number>;
    gp_file_new_from_fd: (...args: unknown[]) => Promise<number>;
    gp_file_get_data_and_size: (...args: unknown[]) => Promise<number>;
    gp_file_get_mime_type: (...args: unknown[]) => Promise<number>;
    gp_file_free: (...args: unknown[]) => Promise<number>;
    gp_log_add_func: (...args: unknown[]) => Promise<number>;
    gp_log_remove_func: (...args: unknown[]) => Promise<number>;
    open: (...args: unknown[]) => Promise<unknown>;
    fchmod: (...args: unknown[]) => Promise<unknown>;
} & {
    koffi: typeof koffi;
};

declare const DEFAULT_LIBGPHOTO2_PATHS: string[];
declare const DEFAULT_LIBC_PATHS: string[];

/**
 * Do the actual loading of the library
 */
declare const loadInternal: (options: GphotoLoadOptions) => Promise<CameraModule & {
    ffi: ReturnType<typeof getFfi>;
}>;
/**
 * Load the library and return the interface and methods
 */
declare const load: (options?: GphotoLoadOptions) => Promise<CameraModule & {
    ffi: ReturnType<typeof getFfi>;
}>;

export { type CameraEvent, type CameraEventCaptureComplete, type CameraEventFileAdded, type CameraEventFileChanged, type CameraEventFolderAdded, type CameraEventTimeout, CameraEventType, type CameraEventUnknown, type CameraFilePath, type CameraInfo, type CameraModule, type ChoiceConfigWidget, type ConfigWidget, DEFAULT_LIBC_PATHS, DEFAULT_LIBGPHOTO2_PATHS, type GphotoLoadOptions, LoggingLevel, type RangeConfigWidget, type TextConfigWidget, type ToggleConfigWidget, WidgetType, load, loadInternal };
