import typing

from PIL import Image

"""
This type stub file was generated by pyright.
"""

class Icon:
    """A representation of a system tray icon.

    The icon is initially hidden. Set :attr:`visible` to ``True`` to show it.

    :param str name: The name of the icon. This is used by the system to
        identify the icon.

    :param icon: The icon to use. If this is specified, it must be a
        :class:`PIL.Image.Image` instance.

    :param str title: A short title for the icon.

    :param menu: A menu to use as popup menu. This can be either an instance of
        :class:`Menu` or an iterable, which will be interpreted as arguments to
        the :class:`Menu` constructor, or ``None``, which disables the menu.

        The behaviour of the menu depends on the platform. Only one action is
        guaranteed to be invocable: the first menu item whose
        :attr:`~pystray.MenuItem.default` attribute is set.

        Some platforms allow both menu interaction and a special way of
        activating the default action, some platform allow only either an
        invisible menu with a default entry as special action or a full menu
        with no special way to activate the default item, and some platforms do
        not support a menu at all.

    :param kwargs: Any non-standard platform dependent options. These should be
        prefixed with the platform name thus: ``appindicator_``, ``darwin_``,
        ``gtk_``, ``win32_`` or ``xorg_``.

        Supported values are:

        ``darwin_nsapplication``
            An ``NSApplication`` instance used to run the event loop. If this
            is not specified, the shared application will be used.
    """

    HAS_DEFAULT_ACTION: bool = ...
    HAS_MENU: bool = ...
    HAS_MENU_RADIO: bool = ...
    HAS_NOTIFICATION: bool = ...
    SETUP_THREAD_TIMEOUT: float = ...
    def __init__(
        self,
        name: str,
        icon: "Image.Image" = ...,
        title: str = ...,
        menu: Menu | None = ...,
        **kwargs: typing.Any,
    ) -> None: ...
    def __del__(self) -> None: ...
    def __call__(self) -> None: ...
    @property
    def name(self) -> str:
        """The name passed to the constructor."""
        ...

    @property
    def icon(self) -> Image.Image | None:
        """The current icon.

        Setting this to a falsy value will hide the icon. Setting this to an
        image while the icon is hidden has no effect until the icon is shown.
        """
        ...

    @icon.setter
    def icon(self, value: Image.Image | None) -> None: ...
    @property
    def title(self) -> str:
        """The current icon title."""
        ...

    @title.setter
    def title(self, value: str) -> None: ...
    @property
    def menu(self) -> Menu | None:
        """The menu.

        Setting this to a falsy value will disable the menu.
        """
        ...

    @menu.setter
    def menu(self, value: Menu | None) -> None: ...
    @property
    def visible(self) -> bool:
        """Whether the icon is currently visible.

        :raises ValueError: if set to ``True`` and no icon image has been set
        """
        ...

    @visible.setter
    def visible(self, value: bool) -> None: ...
    def run(self, setup: typing.Any = ...) -> None:
        """Enters the loop handling events for the icon.

        This method is blocking until :meth:`stop` is called. It *must* be
        called from the main thread.

        :param callable setup: An optional callback to execute in a separate
            thread once the loop has started. It is passed the icon as its sole
            argument.

            Please note that this function is started in a thread, and when the
            icon is stopped, an attempt to join this thread is made, so
            stopping the icon may be blocking for up to
            ``SETUP_THREAD_TIMEOUT`` seconds if the function is not
            well-behaved.

            If not specified, a simple setup function setting :attr:`visible`
            to ``True`` is used. If you specify a custom setup function, you
            must explicitly set this attribute.
        """
        ...

    def run_detached(self, setup: typing.Any = ...) -> None:
        """Prepares for running the loop handling events detached.

        This allows integrating *pystray* with other libraries requiring a
        mainloop. Call this method before entering the mainloop of the other
        library.

        Depending on the backend used, calling this method may require special
        preparations:

        macOS
            Pass an instance of ``NSApplication`` retrieved from the library
            with which you are integrating as the argument
            ``darwin_nsapplication``. This will allow this library to integrate
            with the main loop.

        :param callable setup: An optional callback to execute in a separate
            thread once the loop has started. It is passed the icon as its sole
            argument.

            If not specified, a simple setup function setting :attr:`visible`
            to ``True`` is used. If you specify a custom setup function, you
            must explicitly set this attribute.

        :raises NotImplementedError: if this is not implemented for the
            preparations taken
        """
        ...

    def stop(self) -> None:
        """Stops the loop handling events for the icon.

        If the icon is not running, calling this method has no effect.
        """
        ...

    def update_menu(self) -> None:
        """Updates the menu.

        If the properties of the menu descriptor are dynamic, that is, any are
        defined by callables and not constants, and the return values of these
        callables change by actions other than the menu item activation
        callbacks, calling this function is required to keep the menu in sync.

        This is required since not all supported platforms allow the menu to be
        generated when shown.

        For simple use cases where menu changes are triggered by interaction
        with the menu, this method is not necessary.
        """
        ...

    def notify(self, message: str, title: str | None = ...) -> None:
        """Displays a notification.

        The notification will generally be visible until
        :meth:`remove_notification` is called.

        The class field :attr:`HAS_NOTIFICATION` indicates whether this feature
        is supported on the current platform.

        :param str message: The message of the notification.

        :param str title: The title of the notification. This will be replaced
            with :attr:`title` if ``None``.
        """
        ...

    def remove_notification(self) -> None:
        """Remove a notification."""
        ...

class MenuItem:
    """A single menu item.

    A menu item is immutable.

    It has a text and an action. The action is either a callable of a menu. It
    is callable; when called, the activation callback is called.

    The :attr:`visible` attribute is provided to make menu creation easier; all
    menu items with this value set to ``False`` will be discarded when a
    :class:`Menu` is constructed.
    """

    def __init__(
        self,
        text: str,
        action: typing.Any,
        checked: typing.Any = ...,
        radio: bool = ...,
        default: bool = ...,
        visible: bool = ...,
        enabled: bool = ...,
    ) -> None: ...
    def __call__(self, icon: Icon) -> typing.Any | None: ...
    def __str__(self) -> str: ...
    @property
    def text(self) -> str:
        """The menu item text."""
        ...

    @property
    def checked(self) -> bool | None:
        """Whether this item is checked.

        This can be either ``True``, which implies that the item is checkable
        and checked, ``False``, which implies that the item is checkable but
        not checked, and ``None`` for uncheckable items.

        Depending on platform, uncheckable items may be rendered differently
        from unchecked items.
        """
        ...

    @property
    def radio(self) -> bool | typing.Literal[False]:
        """Whether this item is a radio button.

        This is only used for checkable items. It is always set to ``False``
        for uncheckable items.
        """
        ...

    @property
    def default(self) -> bool:
        """Whether this is the default menu item."""
        ...

    @property
    def visible(self) -> bool:
        """Whether this menu item is visible.

        If the action for this menu item is a menu, that also has to be visible
        for this property to be ``True``.
        """
        ...

    @property
    def enabled(self) -> bool:
        """Whether this menu item is enabled."""
        ...

    @property
    def submenu(self) -> Menu | None:
        """The submenu used by this menu item, or ``None``."""
        ...

class Menu:
    """A description of a menu.

    A menu description is immutable.

    It is created with a sequence of :class:`Menu.Item` instances, or a single
    callable which must return a generator for the menu items.

    First, non-visible menu items are removed from the list, then any instances
    of :attr:`SEPARATOR` occurring at the head or tail of the item list are
    removed, and any consecutive separators are reduced to one.
    """

    SEPARATOR: MenuItem = ...

    def __init__(self, *items: typing.Any) -> None: ...
    @property
    def items(self) -> tuple[MenuItem, ...] | tuple[typing.Any]:
        """All menu items."""
        ...

    @property
    def visible(self) -> bool:
        """Whether this menu is visible."""
        ...

    def __call__(self, icon: Icon) -> None: ...
    def __iter__(self) -> typing.Iterator[typing.Any]: ...
    def __bool__(self) -> bool: ...
    __nonzero__: typing.Any = ...

    def __str__(self) -> str: ...
