const c = @import("c.zig").c;

pub const Atoms = struct {
    wm_protocols: c.Atom,
    wm_delete_window: c.Atom,
    wm_take_focus: c.Atom,
    wm_state: c.Atom,
    wm_change_state: c.Atom,
    net_supported: c.Atom,
    net_supporting_wm_check: c.Atom,
    net_wm_name: c.Atom,
    net_wm_state: c.Atom,
    net_wm_state_fullscreen: c.Atom,
    net_wm_state_hidden: c.Atom,
    net_wm_state_demands_attention: c.Atom,
    net_wm_state_above: c.Atom,
    net_wm_window_type: c.Atom,
    net_wm_window_type_normal: c.Atom,
    net_wm_window_type_dialog: c.Atom,
    net_wm_window_type_utility: c.Atom,
    net_wm_window_type_toolbar: c.Atom,
    net_wm_window_type_splash: c.Atom,
    net_wm_window_type_menu: c.Atom,
    net_wm_window_type_dock: c.Atom,
    net_active_window: c.Atom,
    net_close_window: c.Atom,
    net_client_list: c.Atom,
    net_client_list_stacking: c.Atom,
    net_frame_extents: c.Atom,
    net_wm_pid: c.Atom,

    pub fn init(display: ?*c.Display) Atoms {
        const names = [_][*:0]const u8{
            "WM_PROTOCOLS",
            "WM_DELETE_WINDOW",
            "WM_TAKE_FOCUS",
            "WM_STATE",
            "WM_CHANGE_STATE",
            "_NET_SUPPORTED",
            "_NET_SUPPORTING_WM_CHECK",
            "_NET_WM_NAME",
            "_NET_WM_STATE",
            "_NET_WM_STATE_FULLSCREEN",
            "_NET_WM_STATE_HIDDEN",
            "_NET_WM_STATE_DEMANDS_ATTENTION",
            "_NET_WM_STATE_ABOVE",
            "_NET_WM_WINDOW_TYPE",
            "_NET_WM_WINDOW_TYPE_NORMAL",
            "_NET_WM_WINDOW_TYPE_DIALOG",
            "_NET_WM_WINDOW_TYPE_UTILITY",
            "_NET_WM_WINDOW_TYPE_TOOLBAR",
            "_NET_WM_WINDOW_TYPE_SPLASH",
            "_NET_WM_WINDOW_TYPE_MENU",
            "_NET_WM_WINDOW_TYPE_DOCK",
            "_NET_ACTIVE_WINDOW",
            "_NET_CLOSE_WINDOW",
            "_NET_CLIENT_LIST",
            "_NET_CLIENT_LIST_STACKING",
            "_NET_FRAME_EXTENTS",
            "_NET_WM_PID",
        };
        var atoms: [names.len]c.Atom = undefined;
        _ = c.XInternAtoms(display, @ptrCast(@constCast(&names)), @intCast(names.len), 0, &atoms);
        return .{
            .wm_protocols = atoms[0],
            .wm_delete_window = atoms[1],
            .wm_take_focus = atoms[2],
            .wm_state = atoms[3],
            .wm_change_state = atoms[4],
            .net_supported = atoms[5],
            .net_supporting_wm_check = atoms[6],
            .net_wm_name = atoms[7],
            .net_wm_state = atoms[8],
            .net_wm_state_fullscreen = atoms[9],
            .net_wm_state_hidden = atoms[10],
            .net_wm_state_demands_attention = atoms[11],
            .net_wm_state_above = atoms[12],
            .net_wm_window_type = atoms[13],
            .net_wm_window_type_normal = atoms[14],
            .net_wm_window_type_dialog = atoms[15],
            .net_wm_window_type_utility = atoms[16],
            .net_wm_window_type_toolbar = atoms[17],
            .net_wm_window_type_splash = atoms[18],
            .net_wm_window_type_menu = atoms[19],
            .net_wm_window_type_dock = atoms[20],
            .net_active_window = atoms[21],
            .net_close_window = atoms[22],
            .net_client_list = atoms[23],
            .net_client_list_stacking = atoms[24],
            .net_frame_extents = atoms[25],
            .net_wm_pid = atoms[26],
        };
    }

    pub fn supportedList(self: *const Atoms) []const c.Atom {
        return &.{
            self.net_supported,
            self.net_supporting_wm_check,
            self.net_wm_name,
            self.net_wm_state,
            self.net_wm_state_fullscreen,
            self.net_wm_state_hidden,
            self.net_wm_state_demands_attention,
            self.net_wm_state_above,
            self.net_wm_window_type,
            self.net_wm_window_type_normal,
            self.net_wm_window_type_dialog,
            self.net_wm_window_type_utility,
            self.net_wm_window_type_toolbar,
            self.net_wm_window_type_splash,
            self.net_wm_window_type_menu,
            self.net_wm_window_type_dock,
            self.net_active_window,
            self.net_close_window,
            self.net_client_list,
            self.net_client_list_stacking,
            self.net_frame_extents,
            self.net_wm_pid,
        };
    }
};
