pub const ext = @import("ext.zig");
const notify = @This();

const std = @import("std");
const compat = @import("compat");
const gdkpixbuf = @import("gdkpixbuf2");
const gio = @import("gio2");
const gobject = @import("gobject2");
const glib = @import("glib2");
const gmodule = @import("gmodule2");
/// A passive pop-up notification.
///
/// `notify.Notification` represents a passive pop-up notification. It can
/// contain summary text, body text, and an icon, as well as hints specifying
/// how the notification should be presented. The notification is rendered
/// by a notification daemon, and may present the notification in any number
/// of ways. As such, there is a clear separation of content and presentation,
/// and this API enforces that.
pub const Notification = extern struct {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = notify.NotificationClass;
    f_parent_instance: gobject.Object,

    pub const virtual_methods = struct {
        pub const closed = struct {
            pub fn call(p_class: anytype, p_notification: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(Notification.Class, p_class).f_closed.?(gobject.ext.as(Notification, p_notification));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_notification: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(Notification.Class, p_class).f_closed = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// The icon of the application for the notification.
        pub const app_icon = struct {
            pub const name = "app-icon";

            pub const Type = ?[*:0]u8;
        };

        /// The name of the application for the notification.
        pub const app_name = struct {
            pub const name = "app-name";

            pub const Type = ?[*:0]u8;
        };

        /// The body of the notification.
        pub const body = struct {
            pub const name = "body";

            pub const Type = ?[*:0]u8;
        };

        /// The closed reason of the notification.
        ///
        /// See `Notification.signals.closed`.
        pub const closed_reason = struct {
            pub const name = "closed-reason";

            pub const Type = c_int;
        };

        /// The icon-name of the icon to be displayed on the notification.
        pub const icon_name = struct {
            pub const name = "icon-name";

            pub const Type = ?[*:0]u8;
        };

        /// The Id of the notification.
        pub const id = struct {
            pub const name = "id";

            pub const Type = c_int;
        };

        /// The summary of the notification.
        pub const summary = struct {
            pub const name = "summary";

            pub const Type = ?[*:0]u8;
        };
    };

    pub const signals = struct {
        /// Emitted when the notification is closed.
        ///
        /// Note that when a `notify.Notification` is used in a sandboxed
        /// environment where XDG Desktop Notification Portal is implicitly used,
        /// the signal `notify.Notification.signals.closed` is only emitted when
        /// the notification is closed in response to an user action response.
        ///
        /// NO signal will be emitted if the user or the daemon dismissed the
        /// notification for any other reason.
        pub const closed = struct {
            pub const name = "closed";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Notification, p_instance))),
                    gobject.signalLookup("closed", Notification.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Creates a new `notify.Notification`.
    ///
    /// The summary text is required, but all other parameters are optional.
    extern fn notify_notification_new(p_summary: [*:0]const u8, p_body: ?[*:0]const u8, p_icon: ?[*:0]const u8) *notify.Notification;
    pub const new = notify_notification_new;

    /// Adds an action to a notification.
    ///
    /// When the action is invoked, the specified callback function will be called,
    /// along with the value passed to `user_data`.
    extern fn notify_notification_add_action(p_notification: *Notification, p_action: [*:0]const u8, p_label: [*:0]const u8, p_callback: notify.ActionCallback, p_user_data: ?*anyopaque, p_free_func: ?glib.DestroyNotify) void;
    pub const addAction = notify_notification_add_action;

    /// Clears all actions from the notification.
    extern fn notify_notification_clear_actions(p_notification: *Notification) void;
    pub const clearActions = notify_notification_clear_actions;

    /// Clears all hints from the notification.
    extern fn notify_notification_clear_hints(p_notification: *Notification) void;
    pub const clearHints = notify_notification_clear_hints;

    /// Synchronously tells the notification server to hide the notification on the screen.
    extern fn notify_notification_close(p_notification: *Notification, p_error: ?*?*glib.Error) c_int;
    pub const close = notify_notification_close;

    /// Gets an application launch context for the notification action
    /// activation.
    ///
    /// If an an action is currently being activated, gets a
    /// a `gio.AppLaunchContext` that can be used to launch applications using
    /// the current activation token (see `Notification.getActivationToken`).
    ///
    /// This function is intended to be used in a `ActionCallback` to get
    /// the launch context for the activated action, if the notification daemon
    /// supports it.
    extern fn notify_notification_get_activation_app_launch_context(p_notification: *Notification) ?*gio.AppLaunchContext;
    pub const getActivationAppLaunchContext = notify_notification_get_activation_app_launch_context;

    /// Gets the activation token of the notification.
    ///
    /// If an an action is currently being activated, return the activation token.
    /// This function is intended to be used in a `ActionCallback` to get
    /// the activation token for the activated action, if the notification daemon
    /// supports it.
    extern fn notify_notification_get_activation_token(p_notification: *Notification) ?[*:0]const u8;
    pub const getActivationToken = notify_notification_get_activation_token;

    /// Returns the closed reason code for the notification.
    ///
    /// This is valid only after the `Notification.signals.closed` signal is emitted.
    ///
    /// Since version 0.8.0 the returned value is of type `ClosedReason`.
    extern fn notify_notification_get_closed_reason(p_notification: *const Notification) c_int;
    pub const getClosedReason = notify_notification_get_closed_reason;

    /// Sets the application icon for the notification.
    ///
    /// If this function is not called or if `app_icon` is `NULL`, the application icon
    /// will be set from the value set via `setAppIcon`.
    extern fn notify_notification_set_app_icon(p_notification: *Notification, p_app_icon: ?[*:0]const u8) void;
    pub const setAppIcon = notify_notification_set_app_icon;

    /// Sets the application name for the notification.
    ///
    /// If this function is not called or if `app_name` is `NULL`, the application name
    /// will be set from the value used in `init` or overridden with
    /// `setAppName`.
    extern fn notify_notification_set_app_name(p_notification: *Notification, p_app_name: ?[*:0]const u8) void;
    pub const setAppName = notify_notification_set_app_name;

    /// Sets the category of this notification.
    ///
    /// This can be used by the notification server to filter or display the data in
    /// a certain way.
    extern fn notify_notification_set_category(p_notification: *Notification, p_category: [*:0]const u8) void;
    pub const setCategory = notify_notification_set_category;

    /// Sets a hint for `key` with value `value`.
    ///
    /// If `value` is `NULL`, a previously set hint for `key` is unset.
    ///
    /// If `value` is floating, it is consumed.
    extern fn notify_notification_set_hint(p_notification: *Notification, p_key: [*:0]const u8, p_value: ?*glib.Variant) void;
    pub const setHint = notify_notification_set_hint;

    /// Sets a hint with a byte value.
    extern fn notify_notification_set_hint_byte(p_notification: *Notification, p_key: [*:0]const u8, p_value: u8) void;
    pub const setHintByte = notify_notification_set_hint_byte;

    /// Sets a hint with a byte array value.
    ///
    /// The length of `value` must be passed as `len`.
    extern fn notify_notification_set_hint_byte_array(p_notification: *Notification, p_key: [*:0]const u8, p_value: [*]const u8, p_len: usize) void;
    pub const setHintByteArray = notify_notification_set_hint_byte_array;

    /// Sets a hint with a double value.
    extern fn notify_notification_set_hint_double(p_notification: *Notification, p_key: [*:0]const u8, p_value: f64) void;
    pub const setHintDouble = notify_notification_set_hint_double;

    /// Sets a hint with a 32-bit integer value.
    extern fn notify_notification_set_hint_int32(p_notification: *Notification, p_key: [*:0]const u8, p_value: c_int) void;
    pub const setHintInt32 = notify_notification_set_hint_int32;

    /// Sets a hint with a string value.
    extern fn notify_notification_set_hint_string(p_notification: *Notification, p_key: [*:0]const u8, p_value: [*:0]const u8) void;
    pub const setHintString = notify_notification_set_hint_string;

    /// Sets a hint with an unsigned 32-bit integer value.
    extern fn notify_notification_set_hint_uint32(p_notification: *Notification, p_key: [*:0]const u8, p_value: c_uint) void;
    pub const setHintUint32 = notify_notification_set_hint_uint32;

    /// Sets the icon in the notification from a `gdkpixbuf.Pixbuf`.
    extern fn notify_notification_set_icon_from_pixbuf(p_notification: *Notification, p_icon: *gdkpixbuf.Pixbuf) void;
    pub const setIconFromPixbuf = notify_notification_set_icon_from_pixbuf;

    /// Sets the image in the notification from a `gdkpixbuf.Pixbuf`.
    extern fn notify_notification_set_image_from_pixbuf(p_notification: *Notification, p_pixbuf: *gdkpixbuf.Pixbuf) void;
    pub const setImageFromPixbuf = notify_notification_set_image_from_pixbuf;

    /// Sets the timeout of the notification.
    ///
    /// To set the default time, pass `NOTIFY_EXPIRES_DEFAULT` as `timeout`. To set the
    /// notification to never expire, pass `NOTIFY_EXPIRES_NEVER`.
    ///
    /// Note that the timeout may be ignored by the server.
    extern fn notify_notification_set_timeout(p_notification: *Notification, p_timeout: c_int) void;
    pub const setTimeout = notify_notification_set_timeout;

    /// Sets the urgency level of this notification.
    extern fn notify_notification_set_urgency(p_notification: *Notification, p_urgency: notify.Urgency) void;
    pub const setUrgency = notify_notification_set_urgency;

    /// Tells the notification server to display the notification on the screen.
    extern fn notify_notification_show(p_notification: *Notification, p_error: ?*?*glib.Error) c_int;
    pub const show = notify_notification_show;

    /// Updates the notification text and icon.
    ///
    /// This won't send the update out and display it on the screen. For that, you
    /// will need to call `Notification.show`.
    extern fn notify_notification_update(p_notification: *Notification, p_summary: [*:0]const u8, p_body: ?[*:0]const u8, p_icon: ?[*:0]const u8) c_int;
    pub const update = notify_notification_update;

    extern fn notify_notification_get_type() usize;
    pub const getGObjectType = notify_notification_get_type;

    extern fn g_object_ref(p_self: *notify.Notification) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *notify.Notification) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Notification, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const NotificationClass = extern struct {
    pub const Instance = notify.Notification;

    f_parent_class: gobject.ObjectClass,
    f_closed: ?*const fn (p_notification: *notify.Notification) callconv(.c) void,

    pub fn as(p_instance: *NotificationClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ClosedReason = enum(c_int) {
    unset = -1,
    expired = 1,
    dismissed = 2,
    api_request = 3,
    undefined = 4,
    _,

    pub const undefiend = ClosedReason.undefined;
    extern fn notify_closed_reason_get_type() usize;
    pub const getGObjectType = notify_closed_reason_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The urgency level of the notification.
pub const Urgency = enum(c_int) {
    low = 0,
    normal = 1,
    critical = 2,
    _,

    extern fn notify_urgency_get_type() usize;
    pub const getGObjectType = notify_urgency_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Gets the application icon registered.
extern fn notify_get_app_icon() [*:0]const u8;
pub const getAppIcon = notify_get_app_icon;

/// Gets the application name registered.
extern fn notify_get_app_name() [*:0]const u8;
pub const getAppName = notify_get_app_name;

/// Queries the server capabilities.
///
/// Synchronously queries the server for its capabilities and returns them in a
/// list.
extern fn notify_get_server_caps() *glib.List;
pub const getServerCaps = notify_get_server_caps;

/// Queries the server for information.
///
/// Synchronously queries the server for its information, specifically, the name,
/// vendor, server version, and the version of the notifications specification
/// that it is compliant with.
extern fn notify_get_server_info(p_ret_name: ?*[*:0]u8, p_ret_vendor: ?*[*:0]u8, p_ret_version: ?*[*:0]u8, p_ret_spec_version: ?*[*:0]u8) c_int;
pub const getServerInfo = notify_get_server_info;

/// Initialized libnotify. This must be called before any other functions.
///
/// Starting from 0.8, if the provided `app_name` is `NULL`, libnotify will
/// try to figure it out from the running application.
/// Before it was not allowed, and was causing libnotify not to be initialized.
extern fn notify_init(p_app_name: ?[*:0]const u8) c_int;
pub const init = notify_init;

/// Gets whether or not libnotify is initialized.
extern fn notify_is_initted() c_int;
pub const isInitted = notify_is_initted;

/// Sets the application icon.
extern fn notify_set_app_icon(p_app_icon: ?[*:0]const u8) void;
pub const setAppIcon = notify_set_app_icon;

/// Sets the application name.
extern fn notify_set_app_name(p_app_name: [*:0]const u8) void;
pub const setAppName = notify_set_app_name;

/// Uninitializes libnotify.
///
/// This should be called when the program no longer needs libnotify for
/// the rest of its lifecycle, typically just before exitting.
extern fn notify_uninit() void;
pub const uninit = notify_uninit;

/// An action callback function.
pub const ActionCallback = *const fn (p_notification: *notify.Notification, p_action: [*:0]u8, p_user_data: ?*anyopaque) callconv(.c) void;

/// The default expiration time on a notification.
pub const EXPIRES_DEFAULT = -1;
/// The notification never expires.
///
/// It stays open until closed by the calling API or the user.
pub const EXPIRES_NEVER = 0;
/// When set, a server that has the "action-icons" capability will attempt to
/// interpret any action identifier as a named icon. The localized display name
/// will be used to annotate the icon for accessibility purposes. The icon name
/// should be compliant with the Freedesktop.org Icon Naming Specification.
///
/// Requires server supporting specification version >= 1.2.
///
/// Hint `glib.VariantType`: `glib.VARIANT_TYPE_BOOLEAN` (`b`).
pub const NOTIFICATION_HINT_ACTION_ICONS = "action-icons";
/// The type of notification this is.
///
/// Hint `glib.VariantType`: `glib.VARIANT_TYPE_STRING` (`s`).
pub const NOTIFICATION_HINT_CATEGORY = "category";
/// This specifies the name of the desktop filename representing the calling
/// program. This should be the same as the prefix used for the application's
/// .desktop file. An example would be "rhythmbox" from "rhythmbox.desktop". This
/// can be used by the daemon to retrieve the correct icon for the application,
/// for logging purposes, etc.
///
/// Hint `glib.VariantType`: `glib.VARIANT_TYPE_STRING` (`s`).
pub const NOTIFICATION_HINT_DESKTOP_ENTRY = "desktop-entry";
/// This is a raw data image format which describes the width,
/// height, rowstride, has alpha, bits per sample, channels and image data
/// respectively.
///
/// Requires server supporting specification version >= 1.2
///
/// `glib.VariantType`: `(iiibiiay)`
pub const NOTIFICATION_HINT_IMAGE_DATA = "image-data";
/// This is a raw data image format which describes the width,
/// height, rowstride, has alpha, bits per sample, channels and image data
/// respectively.
///
/// Requires server supporting specification version >= 1.1
///
/// `glib.VariantType`: `(iiibiiay)`
pub const NOTIFICATION_HINT_IMAGE_DATA_LEGACY = "image_data";
/// Alternative way to define the notification image.
///
/// Requires server supporting specification version >= 1.2.
///
/// Hint `glib.VariantType`: `glib.VARIANT_TYPE_STRING` (`s`).
pub const NOTIFICATION_HINT_IMAGE_PATH = "image-path";
/// Alternative way to define the notification image.
///
/// Requires server supporting specification version >= 1.1.
///
/// Hint `glib.VariantType`: `glib.VARIANT_TYPE_STRING` (`s`).
pub const NOTIFICATION_HINT_IMAGE_PATH_LEGACY = "image_path";
/// When set the server will not automatically remove the notification when an
/// action has been invoked. The notification will remain resident in the server
/// until it is explicitly removed by the user or by the sender. This hint is
/// likely only useful when the server has the "persistence" capability.
///
/// Requires server supporting specification version >= 1.2.
///
/// Hint `glib.VariantType`: `glib.VARIANT_TYPE_BOOLEAN` (`b`).
pub const NOTIFICATION_HINT_RESIDENT = "resident";
/// The path to a sound file to play when the notification pops up.
///
/// Hint `glib.VariantType`: `glib.VARIANT_TYPE_STRING` (`s`).
pub const NOTIFICATION_HINT_SOUND_FILE = "sound-file";
/// A themeable named sound from the freedesktop.org sound naming specification
/// to play when the notification pops up. Similar to icon-name, only for sounds.
/// An example would be "message-new-instant".
///
/// Hint `glib.VariantType`: `glib.VARIANT_TYPE_STRING` (`s`).
pub const NOTIFICATION_HINT_SOUND_NAME = "sound-name";
/// Causes the server to suppress playing any sounds, if it has that ability.
/// This is usually set when the client itself is going to play its own sound.
///
/// Hint `glib.VariantType`: `glib.VARIANT_TYPE_BOOLEAN` (`b`).
pub const NOTIFICATION_HINT_SUPPRESS_SOUND = "suppress-sound";
/// When set the server will treat the notification as transient and by-pass the
/// server's persistence capability, if it should exist.
///
/// Requires server supporting specification version >= 1.2.
///
/// Hint `glib.VariantType`: `glib.VARIANT_TYPE_BOOLEAN` (`b`).
pub const NOTIFICATION_HINT_TRANSIENT = "transient";
/// The urgency level.
///
/// Hint `glib.VariantType`: `glib.VARIANT_TYPE_BYTE` (`y`).
pub const NOTIFICATION_HINT_URGENCY = "urgency";
/// Specifies the X location on the screen that the notification should point to.
/// The "y" hint must also be specified.
///
/// Hint `glib.VariantType`: `glib.VARIANT_TYPE_INT32` (`i`).
pub const NOTIFICATION_HINT_X = "x";
/// Specifies the Y location on the screen that the notification should point to.
/// The "x" hint must also be specified.
///
/// Hint `glib.VariantType`: `glib.VARIANT_TYPE_INT32` (`i`).
pub const NOTIFICATION_HINT_Y = "y";
/// Notify major version component (e.g. 1 if the version is 1.2.3).
pub const VERSION_MAJOR = 0;
/// Notify micro version component (e.g. 3 if the version is 1.2.3).
pub const VERSION_MICRO = 8;
/// Notify minor version component (e.g. 2 if the version is 1.2.3).
pub const VERSION_MINOR = 8;

test {
    @setEvalBranchQuota(100_000);
    std.testing.refAllDecls(@This());
    std.testing.refAllDecls(ext);
}
