import typing

import datetime
from fractions import Fraction

from gi.repository import Gio
from gi.repository import GLib
from gi.repository import GObject

T = typing.TypeVar("T")

MAJOR_VERSION: int = 0
MICRO_VERSION: int = 3
MINOR_VERSION: int = 14
_introspection_module = ...  # FIXME Constant
_lock = ...  # FIXME Constant
_namespace: str = "GExiv2"
_overrides_module = ...  # FIXME Constant
_version: str = "0.10"

def get_version() -> int: ...
def initialize() -> bool: ...
def log_get_level() -> LogLevel: ...
def log_set_level(level: LogLevel) -> None: ...
def log_use_glib_logging() -> None: ...

class Metadata(GObject.Object):
    """
    :Constructors:

    ::

        Metadata(**properties)
        new() -> GExiv2.Metadata

    Object GExiv2Metadata

    Signals from GObject:
      notify (GParam)
    """

    parent_instance: GObject.Object = ...
    priv: MetadataPrivate = ...
    # override
    def __init__(self, path: typing.Optional[str] = None): ...
    def clear(self) -> None: ...
    def clear_comment(self) -> None: ...
    def clear_exif(self) -> None: ...
    def clear_iptc(self) -> None: ...
    def clear_tag(self, tag: str) -> bool: ...
    def clear_xmp(self) -> None: ...
    def delete_gps_info(self) -> None: ...
    def erase_exif_thumbnail(self) -> None: ...
    def free(self) -> None: ...
    def from_app1_segment(self, data: typing.Sequence[int]) -> bool: ...
    def from_stream(self, stream: Gio.InputStream) -> bool: ...
    def generate_xmp_packet(
        self, xmp_format_flags: XmpFormatFlags, padding: int
    ) -> typing.Optional[str]: ...
    # override
    def get(self, key, default=None) -> typing.Optional[str]: ...
    def get_comment(self) -> typing.Optional[str]: ...
    # override
    def get_date_time(self) -> datetime.datetime: ...
    def get_exif_data(self, byte_order: ByteOrder) -> typing.Optional[GLib.Bytes]: ...
    # override
    def get_exif_tag_rational(self, key) -> typing.Optional[Fraction]: ...
    def get_exif_tags(self) -> list[str]: ...
    def get_exif_thumbnail(self) -> typing.Tuple[bool, bytes]: ...
    # override
    def get_exposure_time(self) -> typing.Optional[Fraction]: ...
    def get_fnumber(self) -> float: ...
    def get_focal_length(self) -> float: ...
    def get_gps_altitude(self) -> typing.Tuple[bool, float]: ...
    def get_gps_info(self) -> typing.Tuple[bool, float, float, float]: ...
    def get_gps_latitude(self) -> typing.Tuple[bool, float]: ...
    def get_gps_longitude(self) -> typing.Tuple[bool, float]: ...
    def get_iptc_tags(self) -> list[str]: ...
    def get_iso_speed(self) -> int: ...
    def get_metadata_pixel_height(self) -> int: ...
    def get_metadata_pixel_width(self) -> int: ...
    def get_mime_type(self) -> str: ...
    def get_orientation(self) -> Orientation: ...
    def get_pixel_height(self) -> int: ...
    def get_pixel_width(self) -> int: ...
    def get_preview_image(self, props: PreviewProperties) -> PreviewImage: ...
    def get_preview_properties(self) -> typing.Optional[list[PreviewProperties]]: ...
    # override
    def get_raw(self, key) -> bytes: ...
    def get_supports_exif(self) -> bool: ...
    def get_supports_iptc(self) -> bool: ...
    def get_supports_xmp(self) -> bool: ...
    @staticmethod
    def get_tag_description(tag: str) -> typing.Optional[str]: ...
    def get_tag_interpreted_string(self, tag: str) -> typing.Optional[str]: ...
    @staticmethod
    def get_tag_label(tag: str) -> typing.Optional[str]: ...
    def get_tag_long(self, tag: str) -> int: ...
    def get_tag_multiple(self, tag: str) -> typing.Optional[list[str]]: ...
    def get_tag_raw(self, tag: str) -> typing.Optional[GLib.Bytes]: ...
    def get_tag_string(self, tag: str) -> typing.Optional[str]: ...
    @staticmethod
    def get_tag_type(tag: str) -> typing.Optional[str]: ...
    # override
    def get_tags(self) -> list[str]: ...
    @staticmethod
    def get_xmp_namespace_for_tag(tag: str) -> str: ...
    def get_xmp_packet(self) -> typing.Optional[str]: ...
    def get_xmp_tags(self) -> list[str]: ...
    def has_exif(self) -> bool: ...
    def has_iptc(self) -> bool: ...
    def has_tag(self, tag: str) -> bool: ...
    def has_xmp(self) -> bool: ...
    @staticmethod
    def is_exif_tag(tag: str) -> bool: ...
    @staticmethod
    def is_iptc_tag(tag: str) -> bool: ...
    @staticmethod
    def is_xmp_tag(tag: str) -> bool: ...
    @classmethod
    def new(cls) -> Metadata: ...
    def open_buf(self, data: typing.Sequence[int]) -> bool: ...
    # override
    def open_path(self, path: typing.Optional[str]): ...
    @staticmethod
    def register_xmp_namespace(name: str, prefix: str) -> bool: ...
    def save_external(self, path: str) -> bool: ...
    # override
    def save_file(self, path: typing.Optional[str] = None): ...
    def set_comment(self, comment: str) -> None: ...
    # override
    def set_date_time(self, value: str): ...
    # override
    def set_exif_tag_rational(self, key, fraction: Fraction): ...
    def set_exif_thumbnail_from_buffer(self, buffer: typing.Sequence[int]) -> None: ...
    def set_exif_thumbnail_from_file(self, path: str) -> bool: ...
    def set_gps_info(
        self, longitude: float, latitude: float, altitude: float
    ) -> bool: ...
    def set_metadata_pixel_height(self, height: int) -> None: ...
    def set_metadata_pixel_width(self, width: int) -> None: ...
    def set_orientation(self, orientation: Orientation) -> None: ...
    def set_tag_long(self, tag: str, value: int) -> bool: ...
    def set_tag_multiple(self, tag: str, values: typing.Sequence[str]) -> bool: ...
    def set_tag_string(self, tag: str, value: str) -> bool: ...
    def set_xmp_tag_struct(self, tag: str, type: StructureType) -> bool: ...
    def try_clear_tag(self, tag: str) -> bool: ...
    def try_delete_gps_info(self) -> None: ...
    def try_erase_exif_thumbnail(self) -> None: ...
    def try_generate_xmp_packet(
        self, xmp_format_flags: XmpFormatFlags, padding: int
    ) -> typing.Optional[str]: ...
    def try_get_comment(self) -> typing.Optional[str]: ...
    def try_get_exif_tag_rational(self, tag: str) -> typing.Tuple[bool, int, int]: ...
    def try_get_exposure_time(self) -> typing.Tuple[bool, int, int]: ...
    def try_get_fnumber(self) -> float: ...
    def try_get_focal_length(self) -> float: ...
    def try_get_gps_altitude(self) -> typing.Tuple[bool, float]: ...
    def try_get_gps_info(self) -> typing.Tuple[bool, float, float, float]: ...
    def try_get_gps_latitude(self) -> typing.Tuple[bool, float]: ...
    def try_get_gps_longitude(self) -> typing.Tuple[bool, float]: ...
    def try_get_iso_speed(self) -> int: ...
    def try_get_metadata_pixel_height(self) -> int: ...
    def try_get_metadata_pixel_width(self) -> int: ...
    def try_get_orientation(self) -> Orientation: ...
    def try_get_preview_image(self, props: PreviewProperties) -> PreviewImage: ...
    @staticmethod
    def try_get_tag_description(tag: str) -> typing.Optional[str]: ...
    def try_get_tag_interpreted_string(self, tag: str) -> typing.Optional[str]: ...
    @staticmethod
    def try_get_tag_label(tag: str) -> typing.Optional[str]: ...
    def try_get_tag_long(self, tag: str) -> int: ...
    def try_get_tag_multiple(self, tag: str) -> typing.Optional[list[str]]: ...
    def try_get_tag_raw(self, tag: str) -> typing.Optional[GLib.Bytes]: ...
    def try_get_tag_string(self, tag: str) -> typing.Optional[str]: ...
    @staticmethod
    def try_get_tag_type(tag: str) -> typing.Optional[str]: ...
    @staticmethod
    def try_get_xmp_namespace_for_tag(tag: str) -> str: ...
    def try_get_xmp_packet(self) -> typing.Optional[str]: ...
    def try_has_tag(self, tag: str) -> bool: ...
    @staticmethod
    def try_register_xmp_namespace(name: str, prefix: str) -> bool: ...
    def try_set_comment(self, comment: str) -> None: ...
    def try_set_exif_tag_rational(self, tag: str, nom: int, den: int) -> bool: ...
    def try_set_exif_thumbnail_from_buffer(
        self, buffer: typing.Sequence[int]
    ) -> None: ...
    def try_set_gps_info(
        self, longitude: float, latitude: float, altitude: float
    ) -> bool: ...
    def try_set_metadata_pixel_height(self, height: int) -> None: ...
    def try_set_metadata_pixel_width(self, width: int) -> None: ...
    def try_set_orientation(self, orientation: Orientation) -> None: ...
    def try_set_tag_long(self, tag: str, value: int) -> bool: ...
    def try_set_tag_multiple(self, tag: str, values: typing.Sequence[str]) -> bool: ...
    def try_set_tag_string(self, tag: str, value: str) -> bool: ...
    def try_set_xmp_tag_struct(self, tag: str, type: StructureType) -> bool: ...
    def try_tag_supports_multiple_values(self, tag: str) -> bool: ...
    @staticmethod
    def try_unregister_all_xmp_namespaces() -> None: ...
    @staticmethod
    def try_unregister_xmp_namespace(name: str) -> bool: ...
    def try_update_gps_info(
        self, longitude: float, latitude: float, altitude: float
    ) -> bool: ...
    @staticmethod
    def unregister_all_xmp_namespaces() -> None: ...
    @staticmethod
    def unregister_xmp_namespace(name: str) -> bool: ...
    def update_gps_info(
        self, longitude: float, latitude: float, altitude: float
    ) -> bool: ...

class MetadataClass(GObject.GPointer):
    """
    :Constructors:

    ::

        MetadataClass()
    """

    parent_class: GObject.ObjectClass = ...

class MetadataPrivate(GObject.GPointer): ...

class PreviewImage(GObject.Object):
    """
    :Constructors:

    ::

        PreviewImage(**properties)

    Object GExiv2PreviewImage

    Signals from GObject:
      notify (GParam)
    """

    parent_instance: GObject.Object = ...
    priv: PreviewImagePrivate = ...
    def free(self) -> None: ...
    def get_data(self) -> bytes: ...
    def get_extension(self) -> str: ...
    def get_height(self) -> int: ...
    def get_mime_type(self) -> str: ...
    def get_width(self) -> int: ...
    def try_write_file(self, path: str) -> int: ...
    def write_file(self, path: str) -> int: ...

class PreviewImageClass(GObject.GPointer):
    """
    :Constructors:

    ::

        PreviewImageClass()
    """

    parent_class: GObject.ObjectClass = ...

class PreviewImagePrivate(GObject.GPointer): ...

class PreviewProperties(GObject.Object):
    """
    :Constructors:

    ::

        PreviewProperties(**properties)

    Object GExiv2PreviewProperties

    Signals from GObject:
      notify (GParam)
    """

    parent_instance: GObject.Object = ...
    priv: PreviewPropertiesPrivate = ...
    def get_extension(self) -> str: ...
    def get_height(self) -> int: ...
    def get_mime_type(self) -> str: ...
    def get_size(self) -> int: ...
    def get_width(self) -> int: ...

class PreviewPropertiesClass(GObject.GPointer):
    """
    :Constructors:

    ::

        PreviewPropertiesClass()
    """

    parent_class: GObject.ObjectClass = ...

class PreviewPropertiesPrivate(GObject.GPointer): ...

class XmpFormatFlags(GObject.GFlags):
    EXACT_PACKET_LENGTH = 512
    INCLUDE_THUMBNAIL_PAD = 256
    OMIT_ALL_FORMATTING = 2048
    OMIT_PACKET_WRAPPER = 16
    READ_ONLY_PACKET = 32
    USE_COMPACT_FORMAT = 64
    WRITE_ALIAS_COMMENTS = 1024

class ByteOrder(GObject.GEnum):
    BIG = 1
    LITTLE = 0

class LogLevel(GObject.GEnum):
    DEBUG = 0
    ERROR = 3
    INFO = 1
    MUTE = 4
    WARN = 2

class Orientation(GObject.GEnum):
    HFLIP = 2
    NORMAL = 1
    ROT_180 = 3
    ROT_270 = 8
    ROT_90 = 6
    ROT_90_HFLIP = 5
    ROT_90_VFLIP = 7
    UNSPECIFIED = 0
    VFLIP = 4

class StructureType(GObject.GEnum):
    ALT = 20
    BAG = 21
    LANG = 23
    NONE = 0
    SEQ = 22
