#!/usr/bin/env bash

# Keybindings
# https://mylinuxforwork.github.io/dotfiles/usage/keybindings

# Debian dependencies handled in separated script. Current calls hyprland_deps.sh
# which has the corresponding depends in debian that reflects the ml4w deps found
# here: https://mylinuxforwork.github.io/dotfiles/getting-started/dependencies

# On debian it's best to avoid their userspace python packages
# Thet appear to have hijacked pip for their own usw and
# none of the automated packaging tools remaom om sync for
# installing from pypi.

pipx install qtile
pipx inject qtile qtile-extras psutil dbus-fast iwlib

# Pywal is a tool that generates a color palette from the dominant colors in an image.
# It then applies the colors system-wide and on-the-fly in all of your favourite programs.
pipx install pywal pywalfox

pipx install waypaper # fontend to X and wayland wallpaper backends.

DEST=${1:-/etc/skel}
CONFIG_HOME=${DEST}/.config
ROFI_HOME=${CONFIG_HOME}/rofi
QTILE_HOME=${CONFIG_HOME}/qtile
QTILE_SCRIPTS=${QTILE_HOME}/scripts
QTILE_SETTINGS_HOME=${CONFIG_HOME}/ml4w
QTILE_SETTINGS=${QTILE_SETTINGS_HOME}/settings
QTILE_THEME_CACHE=${QTILE_SETTINGS_HOME}/cache
mkdir -p "${ROFI_HOME}"
mkdir -p "${QTILE_HOME}"
mkdir -p "${QTILE_SCRIPTS}"
mkdir -p "${QTILE_SETTINGS}"
mkdir -p "${QTILE_THEME_CACHE}"

# x11-utils
DEBIAN_XPROP_PATH="/usr/bin/xprop"
xprop=${DEBIAN_XPROP_PATH}

# Put ml4w config files in place
# These are the conf files replicated in these heredocs
# git clone --depth 1 https://github.com/mylinuxforwork/qtile /var/tmp/ml4w_qtile/

# Other settings
git clone --depth 1 https://github.com/mylinuxforwork/dotfiles /var/tmp/ml4w_dotfiles/
cp -a /var/tmp/ml4w_dotfiles/.config/ml4w/ "${QTILE_SETTINGS_HOME}"

# Add the rofi configuration
# https://davatorium.github.io/rofi/CONFIG/
cp -a /var/tmp/ml4w_dotfiles/.config/rofi/* "${ROFI_HOME}"

# Create the wallpaper directory and copy in the ml4w wallpapers
# The ensure-wal sscript below will copy in just the default background if the
# wallpaper directory is empty so you can comment this out.
mkdir -p "${DEST}/wallpaper"
cp -a /var/tmp/ml4w_dotfiles/dotfiles/.config/ml4w/wallpapers/* "${DEST}/wallpaper"

# START: nested displays for configuration testing in X and Wayland
# Test qtile in a xephyr nested server.
if [ -d "/usr/bin/Xephyr" ]; then
  sudo apt install -y xserver-xephyr
fi

# https://raw.githubusercontent.com/qtile/qtile/refs/heads/master/scripts/wephyr
conf_print_xephyr() {
  cat <<-'EOF'
#!/usr/bin/env python
#
# The Wayland backend's equivalent to the xephyr script
#
# The QTILE_XEPHYR environmental variable is set to 2 in this script, which can
# be used by configs to detect when they are run via this script.
#

import os
import signal
import subprocess
import sys
import time
from pathlib import Path

BASE_DIR = Path(__file__).parent.parent.resolve()
sys.path.insert(0, BASE_DIR)

from libqtile.utils import get_cache_dir, guess_terminal  # noqa: E402

CACHE_DIR = Path(get_cache_dir())
QTILE = BASE_DIR / "libqtile" / "scripts" / "main.py"


# This script can be configured with environmental variables and arguments:
outputs = os.environ.get("OUTPUTS", 1)
app = os.environ.get("APP", guess_terminal())
log_level = os.environ.get("LOG_LEVEL", "INFO")

cmd = [sys.executable, QTILE.as_posix(), "start", "-b", "wayland", "-l", log_level]
cmd.extend(sys.argv[1:])


# Find the display that the app needs
display = os.environ.get("WAYLAND_DISPLAY", "")
if display:
    display = display[:-1] + str(int(display[-1]) + 1)
else:
    display = "wayland-0"

os.environ["QTILE_XEPHYR"] = "2"
os.environ["WLR_X11_OUTPUTS"] = str(outputs)
os.environ["WLR_WL_OUTPUTS"] = str(outputs)

proc = subprocess.Popen(cmd)

time.sleep(1)
os.environ["WAYLAND_DISPLAY"] = display
app_proc = subprocess.Popen(app)


# Suppress KeyboardInterrupt messages
def noop(signal, frame):
    pass


signal.signal(signal.SIGINT, noop)

proc.wait()
EOF
}
conf_print_xephyr | tee "${HOME}/.local/bin/qtile-start_wnested.sh"
chmod +x "${HOME}/.local/bin/qtile-start_wnested.sh"

# https://raw.githubusercontent.com/qtile/qtile/refs/heads/master/scripts/xephyr
conf_print_xephyr_official() {
  cat <<-'EOF'
#!/usr/bin/env bash

HERE=$(dirname $(readlink -f $0))
SCREEN_SIZE=${SCREEN_SIZE:-800x600}
XDISPLAY=${XDISPLAY:-:1}
LOG_LEVEL=${LOG_LEVEL:-INFO}
APP=${APP:-$(python -c "from libqtile.utils import guess_terminal; print(guess_terminal())")}
if [[ -z $PYTHON ]]; then
    PYTHON=python3
fi

Xephyr +extension RANDR -screen ${SCREEN_SIZE} ${XDISPLAY} -ac &
XEPHYR_PID=$!
(
  sleep 1
  # env DISPLAY=${XDISPLAY} QTILE_XEPHYR=1 ${PYTHON} "${HERE}"/../libqtile/scripts/main.py start -l ${LOG_LEVEL} $@ &
  env DISPLAY=${XDISPLAY} QTILE_XEPHYR=1 qtile start -l ${LOG_LEVEL} $@ &   
  QTILE_PID=$!
  env DISPLAY=${XDISPLAY} ${APP} &
  wait $QTILE_PID
  kill $XEPHYR_PID
)
EOF
}
conf_print_xephyr_official | sudo tee "${HOME}/.local/bin/qtile-start_xnested_official.sh"

# Working - two screens
conf_print_xephyr() {
  cat <<-'EOF'
Xephyr +extension RANDR -screen 1280x720 -screen 1280x720+1280+0 :1 -ac & 
export DISPLAY=:1
qtile start
EOF
}
conf_print_xephyr | tee "${HOME}/.local/bin/qtile-start_xnested.sh"
chmod +x "${HOME}/.local/bin/qtile-start_xnested.sh"

# Add XDG path
if [ -d "$HOME/.local/bin" ]; then
  PATH="$HOME/.local/bin:$PATH"
fi
# END: nested displays for configuration testing in X and Wayland

# START:Debian files (will be overridden by qtile debian package)
conf_print_start() {
  cat <<-'EOF'
#!/bin/bash
# /usr/bin/qtile start
/home/default/.local/bin/qtile start
EOF
}
conf_print_start | sudo tee /usr/bin/qtile-start

conf_print_desktop() {
  cat <<-EOF
[Desktop Entry]
Name=Qtile
Comment=Qtile Session
Exec=dbus-run-session -- ${DEST}/.local/bin/qtile start
Type=Application
Keywords=wm;tiling
EOF
}
# conf_print_desktop | sudo tee /usr/share/xsessions/qtile.desktop

# This is to set a default session in the $HOME directory rather than
# using /usr/share to run $HOME/.local/bin programs. Also this session
# will not be available to other users.
conf_print_xsession() {
  cat <<-EOF
#!/bin/sh
exec dbus-run-session -- ${DEST}/.local/bin/qtile start
EOF
}
conf_print_xsession | tee "${DEST}/.xsession"
chmod +x "${DEST}/.xsession"

# The default session for lightdm: named system sessions
# xfce, qtile, or default etc from /usr/share/xsessions and
# /usr/share/wayland-sessions
# default points to $HOME/.xsession
conf_print_dmrc() {
  cat <<-'EOF'
[Desktop]
Language=en_GB.UTF-8
Session=default
EOF
}
conf_print_dmrc | tee "${DEST}/.dmrc"
chmod 644 ~/.dmrc

conf_print_wayland_desktop() {
  cat <<-EOF
[Desktop Entry]
Name=Qtile
Comment=Qtile Session
Exec=dbus-run-session -- ${DEST}/.local/bin/qtile -b start
Type=Application
Keywords=wm;tiling
EOF
}
# conf_print_wayland_desktop | sudo tee /usr/share/wayland-sessions/qtile-wayland.desktop

# https://raw.githubusercontent.com/qtile/qtile/refs/heads/master/resources/qtile.desktop
# conf_print_desktop() {
#   cat <<-'EOF'
# [Desktop Entry]
# Name=Qtile
# Comment=Qtile Session
# Exec=qtile start
# Type=Application
# Keywords=wm;tiling
# EOF
# }
# conf_print_desktop | sudo tee /usr/share/xsessions/qtile.desktop

# https://raw.githubusercontent.com/qtile/qtile/refs/heads/master/resources/qtile-wayland.desktop
# conf_print_wayland_desktop() {
#   cat <<-'EOF'
# [Desktop Entry]
# Name=Qtile (Wayland)
# Comment=Qtile Session
# Exec=qtile start -b wayland
# Type=Application
# Keywords=wm;tiling
# EOF
# }
# conf_print_wayland_desktop | sudo tee /usr/share/xsessions/qtile-wayland.desktop

# https://github.com/qtile/qtile/raw/refs/heads/master/resources/99-qtile.rules
conf_print_rules() {
  cat <<-'EOF'
# for controlling LCD backlight
ACTION=="add", SUBSYSTEM=="backlight", RUN+="/usr/bin/chmod o+w /sys/class/backlight/%k/brightness" OPTIONS="log_level=debug"

# keyboard backlight
ACTION=="add", SUBSYSTEM=="leds",      RUN+="/usr/bin/chmod o+w /sys/class/leds/%k/brightness"

# fancy battery charge control, needs to be per ACPI implementation, so we need
# to periodically check the kernel for more of these:
#
#     $ ~/packages/linux/drivers/platform/x86 master git grep -l charge_control_end_threshold
#     asus-wmi.c
#     dell/dell-laptop.c
#     fujitsu-laptop.c
#     huawei-wmi.c
#     lg-laptop.c
#     msi-ec.c
#     samsung-galaxybook.c
#     system76_acpi.c
#     thinkpad_acpi.c
#     toshiba_acpi.c
#
# Last checked as of 6.16.
#
# This is a bit annoying: if we use stuff like BAT0 matching we get:
#   BAT0: Process '/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold' failed with exit code 1
# because charge_control_start_threshold is created by the driver loading, not
# the battery being identified. but then we don't have a device name when the
# driver loads, so we hardcode BAT0... if you have more than one battery, you
# can just copypasta a BAT1 rule too (obviously only for your hardware, though
# :).
ACTION=="add" KERNEL=="asus-wmi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold"
ACTION=="add" KERNEL=="asus-wmi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold"
ACTION=="add" KERNEL=="dell-laptop" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold"
ACTION=="add" KERNEL=="dell-laptop" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold"
ACTION=="add" KERNEL=="huawei-wmi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold"
ACTION=="add" KERNEL=="huawei-wmi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold"
ACTION=="add" KERNEL=="lg-laptop" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold"
ACTION=="add" KERNEL=="lg-laptop" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold"
ACTION=="add" KERNEL=="msi-ec" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold"
ACTION=="add" KERNEL=="msi-ec" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold"
ACTION=="add" KERNEL=="samsung-galaxybook" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold"
ACTION=="add" KERNEL=="samsung-galaxybook" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold"
ACTION=="add" KERNEL=="system76_acpi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold"
ACTION=="add" KERNEL=="system76_acpi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold"
ACTION=="add" KERNEL=="thinkpad_acpi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold"
ACTION=="add" KERNEL=="thinkpad_acpi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold"
ACTION=="add" KERNEL=="toshiba_acpi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold"
ACTION=="add" KERNEL=="toshiba_acpi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold"
EOF
}
# conf_print_rules | sudo tee /etc/udev/rules.d/99-qtile.rules
conf_print_rules | sudo tee /usr/lib/rules.d/99-qtile.rules

sudo udevadm control --reload-rules

# END:Debian files (will be overridden by qtile debian package)

# START: ml4w configuration of qtile

conf_print_config() {
  cat <<EOF
# Config
# Icons: https://fontawesome.com/search?o=r&m=free

import os
import re
import socket
import subprocess
import psutil
import json
from libqtile import hook
from libqtile import qtile
from typing import List  
from libqtile import bar, layout, widget
from libqtile.config import Click, Drag, Group, Key, Match, Screen, ScratchPad, DropDown, KeyChord
from libqtile.lazy import lazy
from libqtile.utils import guess_terminal
from libqtile.widget import Spacer, Backlight
from libqtile.widget.image import Image
from libqtile.dgroups import simple_key_binder
from pathlib import Path
from libqtile.log_utils import logger

from qtile_extras import widget
from qtile_extras.widget.decorations import RectDecoration
from qtile_extras.widget.decorations import PowerLineDecoration

# --------------------------------------------------------
# Your configuration
# --------------------------------------------------------

# Keyboard layout in autostart.sh

# Show wlan status bar widget (set to False if wired network)
# show_wlan = True
show_wlan = False

# Show bluetooth status bar widget
# show_bluetooth = True
show_bluetooth = False

# --------------------------------------------------------
# General Variables
# --------------------------------------------------------

# Get home path
home = str(Path.home())

# --------------------------------------------------------
# Check for Desktop/Laptop
# --------------------------------------------------------

# 3 = Desktop
platform = int(os.popen("cat /sys/class/dmi/id/chassis_type").read())

# --------------------------------------------------------
# Set default apps
# --------------------------------------------------------

terminal = "wezterm"        

# --------------------------------------------------------
# Keybindings
# --------------------------------------------------------

mod = "mod4" # SUPER KEY

keys = [

    # Focus
    Key([mod], "Left", lazy.layout.left(), desc="Move focus to left"),
    Key([mod], "Right", lazy.layout.right(), desc="Move focus to right"),
    Key([mod], "Down", lazy.layout.down(), desc="Move focus down"),
    Key([mod], "Up", lazy.layout.up(), desc="Move focus up"),
    Key([mod], "space", lazy.layout.next(), desc="Move window focus to other window around"),
    
    # Move
    Key([mod, "shift"], "Left", lazy.layout.shuffle_left(), desc="Move window to the left"),
    Key([mod, "shift"], "Right", lazy.layout.shuffle_right(), desc="Move window to the right"),
    Key([mod, "shift"], "Down", lazy.layout.shuffle_down(), desc="Move window down"),
    Key([mod, "shift"], "Up", lazy.layout.shuffle_up(), desc="Move window up"),

    # Swap
    Key([mod, "shift"], "h", lazy.layout.swap_left()),
    Key([mod, "shift"], "l", lazy.layout.swap_right()),

    Key([mod], "Print", lazy.spawn(home + "$QTILE_SCRIPTS/screenshot.sh")),

    # Size
    Key([mod, "control"], "Down", lazy.layout.shrink(), desc="Grow window to the left"),
    Key([mod, "control"], "Up", lazy.layout.grow(), desc="Grow window to the right"),
    Key([mod], "n", lazy.layout.normalize(), desc="Reset all window sizes"),

    # Floating
    Key([mod], "t", lazy.window.toggle_floating(), desc='Toggle floating'),
    
    # Split
    Key([mod, "shift"], "Return", lazy.layout.toggle_split(), desc="Toggle between split and unsplit sides of stack"),

    # Toggle Layouts
    Key([mod], "Tab", lazy.next_layout(), desc="Toggle between layouts"),

    # Fullscreen
    Key([mod], "f", lazy.window.toggle_fullscreen()),

    #System
    Key([mod], "q", lazy.window.kill(), desc="Kill focused window"),
    Key([mod, "shift"], "r", lazy.reload_config(), desc="Reload the config"),
    Key([mod, "control"], "q", lazy.spawn(home + "$QTILE_SCRIPTS/powermenu.sh"), desc="Open Powermenu"),

    # Apps
    Key([mod], "Return", lazy.spawn(terminal), desc="Launch terminal"),
    Key([mod, "control"], "Return", lazy.spawn("rofi -show drun"), desc="Launch Rofi"),
    Key([mod], "b", lazy.spawn("bash " + home + "$QTILE_SETTINGS/browser.sh"), desc="Launch Browser"),
    Key([mod, "shift"], "w", lazy.spawn(home + "$QTILE_SCRIPTS/wallpaper.sh"), desc="Update Theme and Wallpaper"),
    Key([mod, "control"], "w", lazy.spawn(home + "$QTILE_SCRIPTS/wallpaper.sh select"), desc="Select Theme and Wallpaper"),

    Key([], "XF86MonBrightnessUp", lazy.spawn("brightnessctl -q s +20%")),
    Key([], "XF86MonBrightnessDown", lazy.spawn("brightnessctl -q s 20%-"))        
]

# --------------------------------------------------------
# Groups
# --------------------------------------------------------

groups = [
    Group("1", layout='monadtall'),
    Group("2", layout='monadtall'),
    Group("3", layout='monadtall'),
    Group("4", layout='monadtall'),
    Group("5", layout='monadtall'),
]

dgroups_key_binder = simple_key_binder(mod)

# --------------------------------------------------------
# Scratchpads
# --------------------------------------------------------

groups.append(ScratchPad("6", [
    DropDown("chatgpt", lazy.spawn("bash " + home + "$QTILE_SETTINGS/ai.sh"), x=0.3, y=0.1, width=0.40, height=0.4, on_focus_lost_hide=False ),
    DropDown("mousepad", "mousepad", x=0.3, y=0.1, width=0.40, height=0.4, on_focus_lost_hide=False ),
    DropDown("terminal", "wezterm", x=0.3, y=0.1, width=0.40, height=0.4, on_focus_lost_hide=False ),
    DropDown("scrcpy", "scrcpy -d", x=0.8, y=0.05, width=0.15, height=0.6, on_focus_lost_hide=False )
]))

keys.extend([
    Key([mod], 'F10', lazy.group["6"].dropdown_toggle("chatgpt")),
    Key([mod], 'F11', lazy.group["6"].dropdown_toggle("mousepad")),
    Key([mod], 'F12', lazy.group["6"].dropdown_toggle("terminal")),
    Key([mod], 'F9', lazy.group["6"].dropdown_toggle("scrcpy"))
])

# --------------------------------------------------------
# Pywal Colors
# --------------------------------------------------------

colors = os.path.expanduser('~/.cache/wal/colors.json')
colordict = json.load(open(colors))
Color0=(colordict['colors']['color0'])
Color1=(colordict['colors']['color1'])
Color2=(colordict['colors']['color2'])
Color3=(colordict['colors']['color3'])
Color4=(colordict['colors']['color4'])
Color5=(colordict['colors']['color5'])
Color6=(colordict['colors']['color6'])
Color7=(colordict['colors']['color7'])
Color8=(colordict['colors']['color8'])
Color9=(colordict['colors']['color9'])
Color10=(colordict['colors']['color10'])
Color11=(colordict['colors']['color11'])
Color12=(colordict['colors']['color12'])
Color13=(colordict['colors']['color13'])
Color14=(colordict['colors']['color14'])
Color15=(colordict['colors']['color15'])

# --------------------------------------------------------
# Setup Layout Theme
# --------------------------------------------------------

layout_theme = { 
    "border_width": 3,
    "margin": 15,
    "border_focus": Color2,
    "border_normal": "FFFFFF",
    "single_border_width": 3
}

# --------------------------------------------------------
# Layouts
# --------------------------------------------------------

layouts = [
    layout.Max(**layout_theme),
    layout.MonadTall(**layout_theme),
    layout.MonadWide(**layout_theme),
    layout.RatioTile(**layout_theme),
    layout.Floating()
]

# --------------------------------------------------------
# Setup Widget Defaults
# --------------------------------------------------------

widget_defaults = dict(
    font="Fira Sans SemiBold",
    fontsize=14,
    padding=3
)
extension_defaults = widget_defaults.copy()

# --------------------------------------------------------
# Decorations
# https://qtile-extras.readthedocs.io/en/stable/manual/how_to/decorations.html
# --------------------------------------------------------

decor_left = {
    "decorations": [
        PowerLineDecoration(
            path="arrow_left"
            # path="rounded_left"
            # path="forward_slash"
            # path="back_slash"
        )
    ],
}

decor_right = {
    "decorations": [
        PowerLineDecoration(
            path="arrow_right"
            # path="rounded_right"
            # path="forward_slash"
            # path="back_slash"
        )
    ],
}

# --------------------------------------------------------
# Widgets
# --------------------------------------------------------

widget_list = [
    widget.TextBox(
        **decor_left,
        background=Color1+".4",
        text='Apps',
        foreground='ffffff',
        desc='',
        padding=10,
        mouse_callbacks={"Button1": lambda: qtile.spawn("rofi -show drun")},
    ),
    widget.TextBox(
        **decor_left,
        background="#ffffff.4",
        text="  ",
        foreground="000000.6",
        fontsize=18,
        mouse_callbacks={"Button1": lambda: qtile.spawn(home + "$QTILE_SCRIPTS/wallpaper.sh select")},
    ),
    widget.GroupBox(
        **decor_left,
        background="#ffffff.7",
        highlight_method='block',
        highlight='ffffff',
        block_border='ffffff',
        highlight_color=['ffffff','ffffff'],
        block_highlight_text_color='000000',
        foreground='ffffff',
        rounded=False,
        this_current_screen_border='ffffff',
        active='ffffff'
  ),
  widget.TextBox(
      **decor_left,
      background="#ffffff.4",
      text=" ",
      foreground="000000.6",
      fontsize=18,
      mouse_callbacks={"Button1": lambda: qtile.spawn("bash " + home + "$QTILE_SETTINGS/browser.sh")},
  ),
  widget.TextBox(
      **decor_left,
      background="#ffffff.4",
      text=" ",
      foreground="000000.6",
      fontsize=18,
      mouse_callbacks={"Button1": lambda: qtile.spawn("bash " + home + "$QTILE_SETTINGS/filemanager.sh")}
  ),
  
  widget.WindowName(
      **decor_left,
      max_chars=50,
      background=Color2+".4",
      width=400,
      padding=10
  ),
  widget.Spacer(),
  widget.Spacer(
      length=30
  ),
  widget.TextBox(
      **decor_right,
      background="#000000.3"      
  ),    
  widget.Memory(
      **decor_right,
      background=Color10+".4",
      padding=10,        
      measure_mem='G',
      format="{MemUsed:.0f}{mm} ({MemTotal:.0f}{mm})"
  ),
  widget.Volume(
      **decor_right,
      background=Color12+".4",
      padding=10, 
      fmt='Vol: {}',
  ),
  widget.DF(
      **decor_right,
      padding=10, 
      background=Color8+".4",        
      visible_on_warn=False,
      format="{p} {uf}{m} ({r:.0f}%)"
  ),
  #widget.Bluetooth(
  #    **decor_right,
  #    background=Color2+".4",
  #    padding=10,
  #    mouse_callbacks={"Button1": lambda: qtile.spawn("blueman-manager")},
  #),
  widget.Wlan(
      **decor_right,
      background=Color2+".4",
      padding=10,
      format='{essid} {percent:2.0%}',
      mouse_callbacks={"Button1": lambda: qtile.spawn("alacritty -e nmtui")},
  ),
  widget.Clock(
      **decor_right,
      background=Color4+".4",   
      padding=10,      
      format="%Y-%m-%d / %I:%M %p",
  ),
  widget.TextBox(
      **decor_right,
      background=Color2+".4",     
      padding=5,    
      text=" ",
      fontsize=20,
      mouse_callbacks={"Button1": lambda: qtile.spawn(home + "$QTILE_SCRIPTS/powermenu.sh")},
  ),
]

# Hide Modules if not on laptop
if (show_wlan == False):
  del widget_list[13:14]

if (show_bluetooth == False):
  del widget_list[12:13]

# --------------------------------------------------------
# Screens
# --------------------------------------------------------

screens = [
  Screen(
      top=bar.Bar(
          widget_list,
          30,
          padding=20,
          opacity=0.7,
          border_width=[0, 0, 0, 0],
          margin=[0,0,0,0],
          background="#000000.3"
      ),
  ),
]

# --------------------------------------------------------
# Drag floating layouts
# --------------------------------------------------------

mouse = [
  Drag([mod], "Button1", lazy.window.set_position_floating(), start=lazy.window.get_position()),
  Drag([mod], "Button3", lazy.window.set_size_floating(), start=lazy.window.get_size()),
  Click([mod], "Button2", lazy.window.bring_to_front()),
]

# --------------------------------------------------------
# Define floating layouts
# --------------------------------------------------------

floating_layout = layout.Floating(
  border_width=3,
  border_focus=Color2,
  border_normal="FFFFFF",
  float_rules=[
  # Run the utility of $(xprop) to see the wm class and name of an X client.
      *layout.Floating.default_float_rules,
      Match(wm_class="confirmreset"),  # gitk
      Match(wm_class="makebranch"),  # gitk
      Match(wm_class="maketag"),  # gitk
      Match(wm_class="ssh-askpass"),  # ssh-askpass
      Match(title="branchdialog"),  # gitk
      Match(title="pinentry"),  # GPG key password entry
  ]
)

# --------------------------------------------------------
# General Setup
# --------------------------------------------------------

dgroups_app_rules = []  # type: list
follow_mouse_focus = True
bring_front_click = False
cursor_warp = False
auto_fullscreen = True
focus_on_window_activation = "smart"
reconfigure_screens = True

# If things like steam games want to auto-minimize themselves when losing
# focus, should we respect this or not?
auto_minimize = True

# XXX: Gasp! We're lying here. In fact, nobody really uses or cares about this
# string besides java UI toolkits; you can see several discussions on the
# mailing lists, GitHub issues, and other WM documentation that suggest setting
# this string if your java app doesn't work correctly. We may as well just lie
# and say that we're a working one by default.
#
# We choose LG3D to maximize irony: it is a 3D non-reparenting WM written in
# java that happens to be on java's whitelist.

# --------------------------------------------------------
# Windows Manager Name
# --------------------------------------------------------

wmname = "QTILE"

# --------------------------------------------------------
# Hooks
# --------------------------------------------------------

# HOOK startup
@hook.subscribe.startup_once
def autostart():
  autostartscript = "~/.config/qtile/autostart.sh"
  home = os.path.expanduser(autostartscript)
  subprocess.Popen([home])
EOF
}
conf_print_config | tee "${QTILE_HOME}/config.py"
chmod 644 "${QTILE_HOME}/config.py"
sudo chown "$USER:$USER" "${QTILE_HOME}/qtile" -R

# initializing wallpaper cache to ensure startup
conf_print_ensure_wal() {
  cat <<-'EOF'
#!/usr/bin/env bash
# ensure_wal.sh — guarantees that pywal has generated colors before Qtile starts

WAL_CACHE="$HOME/.cache/wal"
WALLPAPER_DIR="$HOME/wallpaper"

# 1. If we already have colors → do nothing
[ -f "$WAL_CACHE/colors.json" ] && exit 0

echo "[ensure_wal.sh] No pywal colors found → initializing..."

# 2. Create wallpaper folder if missing
mkdir -p "$WALLPAPER_DIR"

# 3. If the folder is empty, copy a default wallpaper from system (or you can ship one yourself)
if [ ! "$(ls -A "$WALLPAPER_DIR" 2>/dev/null)" ]; then
    echo "[ensure_wal.sh] Wallpaper folder empty → copying a default"
    cp /usr/share/backgrounds/archlinux/simple.png "$WALLPAPER_DIR/default.png" 2>/dev/null || \
    cp /usr/share/backgrounds/gnome/adwaita-day.jpg "$WALLPAPER_DIR/default.jpg" 2>/dev/null || \
    cp /usr/share/pixmaps/archlinux-logo.png "$WALLPAPER_DIR/default.png" 2>/dev/null || \
    cp /var/tmp/ml4w_dotfiles/dotfiles/wallpaper/default.png "$WALLPAPER_DIR/default.png" 2>/dev/null || \
    echo "[ensure_wal.sh] No system wallpaper found — using solid color fallback"
fi

# 4. Force pywal to generate colors (quietly)
wal -q -i "$WALLPAPER_DIR" >/dev/null 2>&1

echo "[ensure_wal.sh] Pywal initialized → Qtile can start safely"
EOF
}
conf_print_ensure_wal | tee "${QTILE_HOME}/scripts/ensure_wal.sh"
chmod +x "${QTILE_HOME}/scripts/ensure_wal.sh"

# autostart
conf_print_autostart() {
  cat <<-'EOF'
#!/bin/bash

# by Stephan Raabe (2023) 
# ----------------------------------------------------- 

# === ENSURE PYWAL IS INITIALIZED (critical!) ===
$HOME/.config/qtile/scripts/ensure_wal.sh

# My screen resolution
# xrandr --rate 120

# For Virtual Machine 
# xrandr --output Virtual-1 --mode 1920x1080

# Keyboard layout
setxkbmap gb

# Load picom
# picom &

# Load power manager
xfce4-power-manager &

# Load notification service
dunst &

# Setup Wallpaper and update colors
$HOME/.config/qtile/scripts/wallpaper.sh init
EOF
}
conf_print_autostart | tee "${QTILE_HOME}/autostart.sh"

# qtile scripts
conf_print_diagnosis() {
  cat <<-'EOF'
#!/bin/bash
clear
sleep 0.5
figlet "Diagnosis"
echo
echo "This script will check that essential packages and "
echo "execution commands are available on your system."
echo

_commandExists() {
    package="$1";
    if ! type $package > /dev/null 2>&1; then
        echo ":: ERROR: $package doesn't exists. Please install it with yay -S $2"
    else
        echo ":: OK: $package found."
    fi
}

_folderExists() {
    folder="$1";
    if [ ! -d $folder ]; then
        echo ":: ERROR: $folder doesn't exists."
    else
        echo ":: OK: $folder found."
    fi
}

_commandExists "rofi" "rofi-wayland"
_commandExists "dunst" "dunst"
_commandExists "wal" "python-pywal"
_commandExists "gum" "gum"
_commandExists "magick" "imagemagick"
_commandExists "figlet" "figlet"

echo
echo "Press return to exit"
read
EOF
}
conf_print_diagnosis | tee "${QTILE_HOME}/scripts/diagnosis.sh"

conf_print_loadbar() {
  cat <<-'EOF'
# Loadbar                                       
# by Stephan Raabe (2023) 
# ----------------------------------------------------- 
"""

echo "Loading Qtile status bar..."
EOF
}
conf_print_loadbar | tee "${QTILE_HOME}/scripts/loadbar.sh"

conf_print_powermenu() {
  cat <<-'EOF'
#!/bin/bash
# Powermenu
# by Stephan Raabe (2023) 
# ----------------------------------------------------- 

echo $XDG_SESSION_TYPE
lockapp=slock
echo "Using $lockapp to lock the screen."

option1="  lock"
option2="  logout"
option3="  reboot"
option4="  power off"

options="$option1\n"
options="$options$option2\n"
options="$options$option3\n$option4"

choice=$(echo -e "$options" | rofi -dmenu -replace -config ~/.config/rofi/config-power.rasi -i -no-show-icons -l 4 -width 30 -p "Powermenu") 

case $choice in
$option1)
  $lockapp ;;
$option2)
  qtile cmd-obj -o cmd -f shutdown ;;
$option3)
  systemctl reboot ;;
$option4)
  systemctl poweroff ;;
esac
EOF
}
conf_print_powermenu | tee "${QTILE_HOME}/scripts/powermenu.sh"

conf_print_screenshot() {
  cat <<-'EOF'
#!/bin/bash
# Screenshot
# by Stephan Raabe (2023) 
# ----------------------------------------------------- 

DIR="$HOME/Pictures/screenshots/"
NAME="screenshot_$(date +%d%m%Y_%H%M%S).png"

option1="Selected window (delay 3 sec)"
option2="Selected area"
option3="Fullscreen (delay 3 sec)"

options="$option2\n$option3\n$option1"

choice=$(echo -e "$options" | rofi -i -dmenu -replace -config ~/.config/rofi/config-screenshot.rasi -width 30 -l 3 -p "Take Screenshot")

case $choice in
    $option1)
        scrot $DIR$NAME -d 3 -e 'xclip -selection clipboard -t image/png -i $f' -c -z -u
        notify-send "Screenshot created" "Mode: Selected window"
    ;;
    $option2)
        scrot $DIR$NAME -s -e 'xclip -selection clipboard -t image/png -i $f'
        notify-send "Screenshot created" "Mode: Selected area"
    ;;
    $option3)
        scrot $DIR$NAME -d 3 -e 'xclip -selection clipboard -t image/png -i $f'
        notify-send "Screenshot created" "Mode: Fullscreen"
    ;;
esac
EOF
}
conf_print_screenshot | tee "${QTILE_HOME}/scripts/screenshot.sh"

conf_print_wallpaper() {
  cat <<EOF
#!/bin/bash
# ChangeTheme
# by Stephan Raabe (2023) 
# ----------------------------------------------------- 

# Cache file for holding the current wallpaper
wallpaper_folder="\$HOME/wallpaper"
if [ -f $QTILE_SETTINGS/wallpaper-folder.sh ] ;then
    source $QTILE_SETTINGS/wallpaper-folder.sh
fi
cache_file="$QTILE_THEME_CACHE/current_wallpaper"
blurred="$QTILE_THEME_CACHE/blurred_wallpaper.png"
rasi_file="$QTILE_THEME_CACHE/current_wallpaper.rasi"

# Create cache file if not exists
if [ ! -f \$cache_file ] ;then
    touch \$cache_file
    echo "\$wallpaper_folder/default.jpg" > "\$cache_file"
fi

# Create rasi file if not exists
if [ ! -f \$rasi_file ] ;then
    touch \$rasi_file
    echo "* { current-image: url(\"\$wallpaper_folder/default.jpg\", height); }" > "\$rasi_file"
fi

current_wallpaper=\$(cat "\$cache_file")

case \$1 in

    # Load wallpaper from .cache of last session 
    "init")
        if [ -f \$cache_file ]; then
            wal -q -i \$current_wallpaper
        else
            wal -q -i \$wallpaper_folder
        fi
    ;;

    # Select wallpaper with rofi
    "select")
        selected=\$(find "\$wallpaper_folder" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) -exec basename {} \; | sort -R | while read rfile; do
    echo -en "\$rfile\x00icon\x1f\$wallpaper_folder/\${rfile}\n"
  done | rofi -dmenu -replace -l 6 -config ~/.config/rofi/config-wallpaper.rasi)
        if [ ! "\$selected" ]; then
            echo "No wallpaper selected"
            exit
        fi
        wal -q -i \$wallpaper_folder/\$selected
    ;;

    # Randomly select wallpaper 
    *)
        wal -q -i \$wallpaper_folder/
    ;;

esac

# ----------------------------------------------------- 
# Reload qtile to color bar
# ----------------------------------------------------- 
qtile cmd-obj -o cmd -f reload_config

# ----------------------------------------------------- 
# Get new theme
# ----------------------------------------------------- 
source "\$HOME/.cache/wal/colors.sh"
echo "Wallpaper: \$wallpaper"
newwall=\$(echo \$wallpaper | sed "s|\$HOME/wallpaper/||g")

# ----------------------------------------------------- 
# Created blurred wallpaper
# ----------------------------------------------------- 
magick \$wallpaper -resize 50% \$blurred
echo ":: Resized to 50%"
magick \$blurred -blur 50x30 \$blurred
echo ":: Blurred"
# ----------------------------------------------------- 
# Write selected wallpaper into .cache files
# ----------------------------------------------------- 
echo "\$wallpaper" > "\$cache_file"
echo "* { current-image: url(\"\$blurred\", height); }" > "\$rasi_file"

sleep 1

# ----------------------------------------------------- 
# Send notification
# ----------------------------------------------------- 
notify-send "Colors and Wallpaper updated" "with image \$newwall"
echo "Done."
EOF
}
conf_print_wallpaper | tee "${QTILE_HOME}/scripts/wallpaper.sh"
chmod +x "${QTILE_HOME}/scripts/wallpaper.sh"

conf_print_browser() {
  cat <<-'EOF'

EOF
}
conf_print_browser | tee "${QTILE_SCRIPTS}/browser.sh"
chmod +x "${QTILE_SCRIPTS}/browser.sh"

# END: ml4w_dotfiles

# START: extensions

# If you're using a tiling window manager, you probably want to do something like this:
#    $ wezterm connect wuake --class org.wezfurlong.wezterm.wuake
#
# Now you can add org.wezfurlong.wezterm.wuake to your floating window exceptions and
# still use a normal tiled window when you open wezterm normally.

# END: extensions

# START: supporting app dotfiles

# dmenu-ish notification-daemon
conf_print_dunstrc() {
  cat <<-'EOF'
# See dunst(5) for all configuration options
[global]
    ### Display ###

    # Which monitor should the notifications be displayed on.
    monitor = 0

    # Display notification on focused monitor.  Possible modes are:
    #   mouse: follow mouse pointer
    #   keyboard: follow window with keyboard focus
    #   none: don't follow anything
    #
    # "keyboard" needs a window manager that exports the
    # _NET_ACTIVE_WINDOW property.
    # This should be the case for almost all modern window managers.
    #
    # If this option is set to mouse or keyboard, the monitor option
    # will be ignored.
    follow = mouse

    ### Geometry ###

    # dynamic width from 0 to 300
    # width = (0, 300)
    # constant width of 300
    width = (0, 400)

    # The maximum height of a single notification, excluding the frame.
    height = (0, 200)

    # Position the notification in the top right corner
    origin = top-right

    # Offset from the origin
    offset = (15, 65)

    # Scale factor. It is auto-detected if value is 0.
    scale = 0

    # Maximum number of notification (0 means no limit)
    notification_limit = 0

    ### Progress bar ###

    # Turn on the progess bar. It appears when a progress hint is passed with
    # for example dunstify -h int:value:12
    progress_bar = true

    # Set the progress bar height. This includes the frame, so make sure
    # it's at least twice as big as the frame width.
    progress_bar_height = 10

    # Set the frame width of the progress bar
    progress_bar_frame_width = 0

    # Set the minimum width for the progress bar
    progress_bar_min_width = 350

    # Set the maximum width for the progress bar
    progress_bar_max_width = 400


    # Show how many messages are currently hidden (because of
    # notification_limit).
    indicate_hidden = yes

    # The transparency of the window.  Range: [0; 100].
    # This option will only work if a compositing window manager is
    # present (e.g. xcompmgr, compiz, etc.). (X11 only)
    transparency = 0

    # Draw a line of "separator_height" pixel height between two
    # notifications.
    # Set to 0 to disable.
    # If gapsize is greater than 0, this setting will be ignored.
    separator_height = 2

    # Padding between text and separator.
    padding = 12

    # Horizontal padding.
    horizontal_padding = 15

    # Padding between text and icon.
    text_icon_padding = 0

    # Defines width in pixels of frame around the notification window.
    # Set to 0 to disable.
    frame_width = 2

    # Defines color of the frame around the notification window.
    frame_color = "#1bd5ab"

    # Size of gap to display between notifications - requires a compositor.
    # If value is greater than 0, separator_height will be ignored and a border
    # of size frame_width will be drawn around each notification instead.
    # Click events on gaps do not currently propagate to applications below.
    # WARNING: doesn't exist?
    gap_size = 5

    # Define a color for the separator.
    # possible values are:
    #  * auto: dunst tries to find a color fitting to the background;
    #  * foreground: use the same color as the foreground;
    #  * frame: use the same color as the frame;
    #  * anything else will be interpreted as a X color.
    separator_color = auto 
    # or: "#1bd5ab"

    # Sort messages by urgency.
    sort = yes

    # Don't remove messages, if the user is idle (no mouse or keyboard input)
    # for longer than idle_threshold seconds.
    # Set to 0 to disable.
    # A client can set the 'transient' hint to bypass this. See the rules
    # section for how to disable this if necessary
    # idle_threshold = 120

    ### Text ###

    font =  mononoki Nerd Font 16

    # The spacing between lines.  If the height is smaller than the
    # font height, it will get raised to the font height.
    line_height = 0

    # Possible values are:
    # full: Allow a small subset of html markup in notifications:
    #        <b>bold</b>
    #        <i>italic</i>
    #        <s>strikethrough</s>
    #        <u>underline</u>
    #
    #        For a complete reference see
    #        <https://docs.gtk.org/Pango/pango_markup.html>.
    #
    # strip: This setting is provided for compatibility with some broken
    #        clients that send markup even though it's not enabled on the
    #        server. Dunst will try to strip the markup but the parsing is
    #        simplistic so using this option outside of matching rules for
    #        specific applications *IS GREATLY DISCOURAGED*.
    #
    # no:    Disable markup parsing, incoming notifications will be treated as
    #        plain text. Dunst will not advertise that it has the body-markup
    #        capability if this is set as a global setting.
    #
    # It's important to note that markup inside the format option will be parsed
    # regardless of what this is set to.
    markup = full

    # The format of the message.  Possible variables are:
    #   %a  appname
    #   %s  summary
    #   %b  body
    #   %i  iconname (including its path)
    #   %I  iconname (without its path)
    #   %p  progress value if set ([  0%] to [100%]) or nothing
    #   %n  progress value if set without any extra characters
    #   %%  Literal %
    # Markup is allowed
    # format = "<b>%s</b>\n%b" # (default)
    format = "<b>%s</b>\n<span size="small">%b</span>"

    # Alignment of message text.
    # Possible values are "left", "center" and "right".
    alignment = center

    # Vertical alignment of message text and icon.
    # Possible values are "top", "center" and "bottom".
    vertical_alignment = center

    # Show age of message if message is older than show_age_threshold
    # seconds.
    # Set to -1 to disable.
    show_age_threshold = 60

    # Specify where to make an ellipsis in long lines.
    # Possible values are "start", "middle" and "end".
    ellipsize = "end"

    # Ignore newlines '\n' in notifications.
    ignore_newline = no

    # Stack together notifications with the same content
    stack_duplicates = true

    # Hide the count of stacked notifications with the same content
    hide_duplicate_count = false

    # Display indicators for URLs (U) and actions (A).
    show_indicators = yes

    ### Icons ###

    # Align icons left/right/top/off
    icon_position = left
    # Scale small icons up to this size, set to 0 to disable. Helpful
    # for e.g. small files or high-dpi screens. In case of conflict,
    # max_icon_size takes precedence over this.
    min_icon_size = 32

    # Scale larger icons down to this size, set to 0 to disable
    max_icon_size = 64

    # Paths to default icons.
    icon_path = /usr/share/icons/gnome/256x256/status/:/usr/share/icons/gnome/256x256/devices/
    icon_theme = "Papirus"
    enable_recursive_icon_lookup = true

    # always_run_scripts = true
    ### History ###

    # Should a notification popped up from history be sticky or timeout
    # as if it would normally do.
    sticky_history = yes

    # Maximum amount of notifications kept in history
    history_length = 20

    ### Misc/Advanced ###

    # dmenu path.
    dmenu = wofi --show dmenu -p dunst:

    # Browser for opening urls in context menu.
    browser = /usr/bin/xdg-open

    # Always run rule-defined scripts, even if the notification is suppressed
    always_run_script = true

    # Define the title of the windows spawned by dunst
    title = Dunst

    # Define the class of the windows spawned by dunst
    class = Dunst

    # Define the corner  of the notification window
    # in pixel size. If the radius is 0, you have no rounded
    # corners.
    # The radius will be automatically lowered if it exceeds half of the
    # notification height to avoid clipping text and/or icons.
    corner_radius = 10

    # Ignore the dbus closeNotification message.
    # Useful to enforce the timeout set by dunst configuration. Without this
    # parameter, an application may close the notification sent before the
    # user defined timeout.
    ignore_dbusclose = false

    ### Wayland ###
    # These settings are Wayland-specific. They have no effect when using X11

    # Uncomment this if you want to let notications appear under fullscreen
    # applications (default: overlay)
    layer = top

    # Set this to true to use X11 output on Wayland.
    force_xwayland = false

    ### Legacy

    # Use the Xinerama extension instead of RandR for multi-monitor support.
    # This setting is provided for compatibility with older nVidia drivers that
    # do not support RandR and using it on systems that support RandR is highly
    # discouraged.
    #
    # By enabling this setting dunst will not be able to detect when a monitor
    # is connected or disconnected which might break follow mode if the screen
    # layout changes.
    force_xinerama = false

    ### mouse

    # Defines list of actions for each mouse event
    # Possible values are:
    # * none: Don't do anything.
    # * do_action: Invoke the action determined by the action_name rule. If there is no
    #              such action, open the context menu.
    # * open_url: If the notification has exactly one url, open it. If there are multiple
    #             ones, open the context menu.
    # * close_current: Close current notification.
    # * close_all: Close all notifications.
    # * context: Open context menu for the notification.
    # * context_all: Open context menu for all notifications.
    # These values can be strung together for each mouse event, and
    # will be executed in sequence.
    mouse_left_click = close_current
    mouse_middle_click = context
    mouse_right_click = do_action

# Experimental features that may or may not work correctly. Do not expect them
# to have a consistent behaviour across releases.
[experimental]
    # Calculate the dpi to use on a per-monitor basis.
    # If this setting is enabled the Xft.dpi value will be ignored and instead
    # dunst will attempt to calculate an appropriate dpi value for each monitor
    # using the resolution and physical size. This might be useful in setups
    # where there are multiple screens with very different dpi values.
    per_monitor_dpi = false

[urgency_low]
    # IMPORTANT: colors have to be defined in quotation marks.
    # Otherwise the "#" and following would be interpreted as a comment.
    background = 	"#111019" # "#0f0f0f"
    foreground = 	"#F1F0F5" # "#89b4fa"
    frame_color = 	"#0B0A10" # "#89b4fa"
    timeout = 3
    highlight = "#AAC5A0"
    # script = ~/.scripts/dunst/sound-normal.sh
    # Icon for notifications with low urgency, uncomment to enable
    #default_icon = /path/to/icon

[urgency_normal]
    background = 	"#111019" # "#0f0f0f"
    foreground = 	"#F1F0F5" # "#a6e3a1"
    frame_color = 	"#0B0A10" # "#a6e3a1"
    timeout = 5
    highlight = "#A8C5E6"
    # script = ~/.scripts/dunst/sound-normal.sh
    # Icon for notifications with normal urgency, uncomment to enable
    # default_icon = /path/to/icon

[urgency_critical]
    background = 	"#111019" # "#0f0f0f"
    foreground = 	"#E97193" # "#f38ba8"
    frame_color = 	"#0B0A10" # "#f38ba8"
    timeout = 10
    highlight = "#E97193"
    # script = ~/.scripts/dunst/sound-critical.sh
    # Icon for notifications with critical urgency, uncomment to enable
    #default_icon = /path/to/icon

# Every section that isn't one of the above is interpreted as a rules to
# override settings for certain messages.
#
# Messages can be matched by
#    appname (discouraged, see desktop_entry)
#    body
#    category
#    desktop_entry
#    icon
#    match_transient
#    msg_urgency
#    stack_tag
#    summary
#
# and you can override the
#    background
#    foreground
#    format
#    frame_color
#    fullscreen
#    new_icon
#    set_stack_tag
#    set_transient
#    set_category
#    timeout
#    urgency
#    icon_position
#    skip_display
#    history_ignore
#    action_name
#    word_wrap
#    ellipsize
#    alignment
#    hide_text
#
# Shell-like globbing will get expanded.
#
# Instead of the appname filter, it's recommended to use the desktop_entry filter.
# GLib based applications export their desktop-entry name. In comparison to the appname,
# the desktop-entry won't get localized.
#
# SCRIPTING
# You can specify a script that gets run when the rule matches by
# setting the "script" option.
# The script will be called as follows:
#   script appname summary body icon urgency
# where urgency can be "LOW", "NORMAL" or "CRITICAL".
#
# NOTE: It might be helpful to run dunst -print in a terminal in order
# to find fitting options for rules.

# Disable the transient hint so that idle_threshold cannot be bypassed from the
# client
#[transient_disable]
#    match_transient = yes
#    set_transient = no
#
# Make the handling of transient notifications more strict by making them not
# be placed in history.
#[transient_history_ignore]
#    match_transient = yes
#    history_ignore = yes

# fullscreen values
# show: show the notifications, regardless if there is a fullscreen window opened
# delay: displays the new notification, if there is no fullscreen window active
#        If the notification is already drawn, it won't get undrawn.
# pushback: same as delay, but when switching into fullscreen, the notification will get
#           withdrawn from screen again and will get delayed like a new notification
#[fullscreen_delay_everything]
#    fullscreen = delay
#[fullscreen_show_critical]
#    msg_urgency = critical
#    fullscreen = show

#[espeak]
#    summary = "*"
#    script = dunst_espeak.sh

#[script-test]
#    summary = "*script*"
#    script = dunst_test.sh

#[ignore]
#    # This notification will not be displayed
#    summary = "foobar"
#    skip_display = true

#[history-ignore]
#    # This notification will not be saved in history
#    summary = "foobar"
#    history_ignore = yes

#[skip-display]
#    # This notification will not be displayed, but will be included in the history
#    summary = "foobar"
#    skip_display = yes

#[signed_on]
#    appname = Pidgin
#    summary = "*signed on*"
#    urgency = low
#
#[signed_off]
#    appname = Pidgin
#    summary = *signed off*
#    urgency = low
#
#[says]
#    appname = Pidgin
#    summary = *says*
#    urgency = critical
#
#[twitter]
#    appname = Pidgin
#    summary = *twitter.com*
#    urgency = normal
#
#[stack-volumes]
#    appname = "some_volume_notifiers"
#    set_stack_tag = "volume"
#
# [redirect]
# summary = "*"
# script = "~/.config/hypr/scripts/default/tools/notif"

# [logger]
# summary = "*"
# script = "~/.config/hypr/scripts/default/tools/notif"

# [spotify]
# summary = "*"
# script = "~/.scripts/music-art"

# rounded corners forced ?
# [Spotify]
#     appname = "Spotify"
#     script = "~/.config/dunst/scripts/round_image.sh"
#     new_icon = "~/.config/dunst/assets/album_cover.png"
# */
EOF
}
conf_print_config | tee "${DEST}/.config/dunst/dunstrc"

# END: supporting app dotfiles

# START settings files (ml4w) output of /var/tmp/automate/conf_print_gen.sh

conf_print_ai() {
  cat <<'EOF_ai_EOF'
$(cat ~/.config/ml4w/settings/browser.sh) --new-window https://chat.openai.com
EOF_ai_EOF
}
conf_print_ai | tee "${QTILE_SETTINGS}/ai.sh"

conf_print_aur() {
  cat <<'EOF_aur_EOF'
yay
EOF_aur_EOF
}
conf_print_aur | tee "${QTILE_SETTINGS}/aur.sh"

conf_print_bluetooth() {
  cat <<'EOF_bluetooth_EOF'
blueman-manager
EOF_bluetooth_EOF
}
conf_print_bluetooth | tee "${QTILE_SETTINGS}/bluetooth.sh"

conf_print_blur() {
  cat <<'EOF_blur_EOF'
50x30
EOF_blur_EOF
}
conf_print_blur | tee "${QTILE_SETTINGS}/blur.sh"

conf_print_browser() {
  cat <<'EOF_browser_EOF'
firefox
EOF_browser_EOF
}
conf_print_browser | tee "${QTILE_SETTINGS}/browser.sh"

conf_print_calculator() {
  cat <<'EOF_calculator_EOF'
gnome-calculator
EOF_calculator_EOF
}
conf_print_calculator | tee "${QTILE_SETTINGS}/calculator.sh"

conf_print_dock_border() {
  cat <<'EOF_dock_border_EOF'
window {
	border-width: 2px;
}

EOF_dock_border_EOF
}
conf_print_dock_border | tee "${QTILE_SETTINGS}/dock-border.css"

conf_print_dock_theme() {
  cat <<'EOF_dock_theme_EOF'
glass
EOF_dock_theme_EOF
}
conf_print_dock_theme | tee "${QTILE_SETTINGS}/dock-theme"

conf_print_dotfiles_folder() {
  cat <<'EOF_dotfiles_folder_EOF'
dotfiles
EOF_dotfiles_folder_EOF
}
conf_print_dotfiles_folder | tee "${QTILE_SETTINGS}/dotfiles-folder.sh"

conf_print_editor() {
  cat <<'EOF_editor_EOF'
gnome-text-editor
EOF_editor_EOF
}
conf_print_editor | tee "${QTILE_SETTINGS}/editor.sh"

conf_print_email() {
  cat <<'EOF_email_EOF'
evolution
EOF_email_EOF
}
conf_print_email | tee "${QTILE_SETTINGS}/email.sh"

conf_print_emojipicker() {
  cat <<'EOF_emojipicker_EOF'
flatpak run com.ml4w.sidebar
EOF_emojipicker_EOF
}
conf_print_emojipicker | tee "${QTILE_SETTINGS}/emojipicker.sh"

conf_print_filemanager() {
  cat <<'EOF_filemanager_EOF'
yazi

EOF_filemanager_EOF
}
conf_print_filemanager | tee "${QTILE_SETTINGS}/filemanager"

conf_print_filemanager() {
  cat <<'EOF_filemanager_EOF'
# #nautilus --new-window
rox


EOF_filemanager_EOF
}
conf_print_filemanager | tee "${QTILE_SETTINGS}/filemanager.sh"

conf_print_hyprpaper() {
  cat <<'EOF_hyprpaper_EOF'
# Preload Wallpapers
preload = WALLPAPER

# Set Wallpapers
wallpaper = ,WALLPAPER

# Disable Splash
splash = false
EOF_hyprpaper_EOF
}
conf_print_hyprpaper | tee "${QTILE_SETTINGS}/hyprpaper.tpl"

conf_print_hyprpicker() {
  cat <<'EOF_hyprpicker_EOF'
hyprpicker -a -f hex
EOF_hyprpicker_EOF
}
conf_print_hyprpicker | tee "${QTILE_SETTINGS}/hyprpicker.sh"

conf_print_hyprshade() {
  cat <<'EOF_hyprshade_EOF'
hyprshade_filter="blue-light-filter-50"
EOF_hyprshade_EOF
}
conf_print_hyprshade | tee "${QTILE_SETTINGS}/hyprshade.sh"

conf_print_installupdates() {
  cat <<'EOF_installupdates_EOF'
$(cat ~/.config/ml4w/settings/terminal.sh) --class dotfiles-floating -e ~/.config/ml4w/scripts/installupdates.sh
EOF_installupdates_EOF
}
conf_print_installupdates | tee "${QTILE_SETTINGS}/installupdates.sh"

conf_print_kitty_cursor_trail() {
  cat <<'EOF_kitty_cursor_trail_EOF'
cursor_trail 1

EOF_kitty_cursor_trail_EOF
}
conf_print_kitty_cursor_trail | tee "${QTILE_SETTINGS}/kitty-cursor-trail.conf"

conf_print_launcher() {
  cat <<'EOF_launcher_EOF'
rofi
EOF_launcher_EOF
}
conf_print_launcher | tee "${QTILE_SETTINGS}/launcher"

conf_print_networkmanager() {
  cat <<'EOF_networkmanager_EOF'
$(cat ~/.config/ml4w/settings/terminal.sh) --class dotfiles-floating -e nmtui
EOF_networkmanager_EOF
}
conf_print_networkmanager | tee "${QTILE_SETTINGS}/networkmanager.sh"

conf_print_printer_drivers() {
  cat <<'EOF_printer_drivers_EOF'
#!/usr/bin/env bash
# Installation of Printer Drivers
# Please add your drivers to the package list
# Example:
# yay -S brother-hll2360dw-lpr-bin brother-hll2360dw-cups-bin brother-mfc-l3770cdw brscan-skey brscan4 skanpage
EOF_printer_drivers_EOF
}
conf_print_printer_drivers | tee "${QTILE_SETTINGS}/printer-drivers.sh"

conf_print_rofi_border_radius() {
  cat <<'EOF_rofi_border_radius_EOF'
* { border-radius: 2em; }
EOF_rofi_border_radius_EOF
}
conf_print_rofi_border_radius | tee "${QTILE_SETTINGS}/rofi-border-radius.rasi"

conf_print_rofi_border() {
  cat <<'EOF_rofi_border_EOF'
* { border-width: 2px; }
EOF_rofi_border_EOF
}
conf_print_rofi_border | tee "${QTILE_SETTINGS}/rofi-border.rasi"

conf_print_rofi_font() {
  cat <<'EOF_rofi_font_EOF'
configuration { font: "Fira Sans 11"; }
EOF_rofi_font_EOF
}
conf_print_rofi_font | tee "${QTILE_SETTINGS}/rofi-font.rasi"

conf_print_screenshot_editor() {
  cat <<'EOF_screenshot_editor_EOF'
pinta
EOF_screenshot_editor_EOF
}
conf_print_screenshot_editor | tee "${QTILE_SETTINGS}/screenshot-editor"

conf_print_screenshot_filename() {
  cat <<'EOF_screenshot_filename_EOF'
screenshot_$(date +%Y%m%d_%H%M%S).jpg
EOF_screenshot_filename_EOF
}
conf_print_screenshot_filename | tee "${QTILE_SETTINGS}/screenshot-filename"

conf_print_screenshot_folder() {
  cat <<'EOF_screenshot_folder_EOF'
~/Pictures
EOF_screenshot_folder_EOF
}
conf_print_screenshot_folder | tee "${QTILE_SETTINGS}/screenshot-folder"

conf_print_sidepad_active() {
  cat <<'EOF_sidepad_active_EOF'
ml4w-kitty
EOF_sidepad_active_EOF
}
conf_print_sidepad_active | tee "${QTILE_SETTINGS}/sidepad-active"

conf_print_systemmonitor() {
  cat <<'EOF_systemmonitor_EOF'
btop
EOF_systemmonitor_EOF
}
conf_print_systemmonitor | tee "${QTILE_SETTINGS}/systemmonitor"

conf_print_system_monitor() {
  cat <<'EOF_system_monitor_EOF'
$(cat ~/.config/ml4w/settings/terminal.sh) --class dotfiles-floating -e btop
EOF_system_monitor_EOF
}
conf_print_system_monitor | tee "${QTILE_SETTINGS}/system-monitor.sh"

conf_print_terminal() {
  cat <<'EOF_terminal_EOF'
kitty
EOF_terminal_EOF
}
conf_print_terminal | tee "${QTILE_SETTINGS}/terminal.sh"

conf_print_walker_theme() {
  cat <<'EOF_walker_theme_EOF'
modern
EOF_walker_theme_EOF
}
conf_print_walker_theme | tee "${QTILE_SETTINGS}/walker-theme"

conf_print_wallpaper_automation() {
  cat <<'EOF_wallpaper_automation_EOF'
60
EOF_wallpaper_automation_EOF
}
conf_print_wallpaper_automation | tee "${QTILE_SETTINGS}/wallpaper-automation.sh"

conf_print_wallpaper_effect() {
  cat <<'EOF_wallpaper_effect_EOF'
off
EOF_wallpaper_effect_EOF
}
conf_print_wallpaper_effect | tee "${QTILE_SETTINGS}/wallpaper-effect.sh"

conf_print_wallpaper_engine() {
  cat <<'EOF_wallpaper_engine_EOF'
hyprpaper
EOF_wallpaper_engine_EOF
}
conf_print_wallpaper_engine | tee "${QTILE_SETTINGS}/wallpaper-engine.sh"

conf_print_wallpaper_folder() {
  cat <<'EOF_wallpaper_folder_EOF'
$HOME/wallpaper
EOF_wallpaper_folder_EOF
}
conf_print_wallpaper_folder | tee "${QTILE_SETTINGS}/wallpaper-folder"

conf_print_waybar_appmenu() {
  cat <<'EOF_waybar_appmenu_EOF'
True
EOF_waybar_appmenu_EOF
}
conf_print_waybar_appmenu | tee "${QTILE_SETTINGS}/waybar_appmenu.sh"

conf_print_waybar_backlight() {
  cat <<'EOF_waybar_backlight_EOF'
False
EOF_waybar_backlight_EOF
}
conf_print_waybar_backlight | tee "${QTILE_SETTINGS}/waybar_backlight.sh"

conf_print_waybar_chatgpt() {
  cat <<'EOF_waybar_chatgpt_EOF'
True
EOF_waybar_chatgpt_EOF
}
conf_print_waybar_chatgpt | tee "${QTILE_SETTINGS}/waybar_chatgpt.sh"

conf_print_waybar_dateformat() {
  cat <<'EOF_waybar_dateformat_EOF'
%a
EOF_waybar_dateformat_EOF
}
conf_print_waybar_dateformat | tee "${QTILE_SETTINGS}/waybar_dateformat.sh"

conf_print_waybar_network() {
  cat <<'EOF_waybar_network_EOF'
True
EOF_waybar_network_EOF
}
conf_print_waybar_network | tee "${QTILE_SETTINGS}/waybar_network.sh"

conf_print_waybar_quicklinks() {
  cat <<'EOF_waybar_quicklinks_EOF'
/*
Define your quick links for the statusbar here.
YOu can use icons from here https://fontawesome.com/search?ic=free
You can reload waybar with SUPER + SHIFT + B
*/
{
    "custom/quicklink_browser": {
        "format": "",
        "on-click": "~/.config/ml4w/settings/browser.sh",
        "tooltip-format": "Open Browser"
    },
    "custom/quicklink_filemanager": {
        "format": "",
        "on-click": "~/.config/ml4w/settings/filemanager.sh",
        "tooltip-format": "Open Filemanager"
    },
    "custom/quicklink_email": {
        "format": "",
        "on-click": "~/.config/ml4w/settings/email.sh",
        "tooltip-format": "Open Email Client"
    },
    "custom/quicklink_chromium": {
        "format": "",
        "on-click": "chromium",
        "tooltip-format": "Open Chromium"
    },
    "custom/quicklink_edge": {
        "format": "",
        "on-click": "edge",
        "tooltip-format": "Open Edge"
    },
    "custom/quicklink_firefox": {
        "format": "",
        "on-click": "firefox",
        "tooltip-format": "Open Firefox"
    },
    "custom/quicklink_thunderbird": {
        "format": "",
        "on-click": "thunderbird",
        "tooltip-format": "Open Thunderbird"
    },
    "custom/quicklink_calculator": {
        "format": "",
        "on-click": "~/.config/ml4w/settings/calculator.sh",
        "tooltip-format": "Open calculator"
    },
/*
Don't remove the quicklinkempty
*/
    "custom/quicklinkempty": {
    },
/*
Add your quicklinks in your desired order to the status bar
*/
    "group/quicklinks": {
        "orientation": "horizontal",
        "modules": [

            "custom/quicklink_browser",
            "custom/quicklink_email",
            "custom/quicklink_filemanager",

/*
Don't remove the quicklinkempty
*/
            "custom/quicklinkempty"
        ]
    }
}

EOF_waybar_quicklinks_EOF
}
conf_print_waybar_quicklinks | tee "${QTILE_SETTINGS}/waybar-quicklinks.json"

conf_print_waybar_quicklinks() {
  cat <<'EOF_waybar_quicklinks_EOF'
False
EOF_waybar_quicklinks_EOF
}
conf_print_waybar_quicklinks | tee "${QTILE_SETTINGS}/waybar_quicklinks.sh"

conf_print_waybar_screenlock() {
  cat <<'EOF_waybar_screenlock_EOF'
True
EOF_waybar_screenlock_EOF
}
conf_print_waybar_screenlock | tee "${QTILE_SETTINGS}/waybar_screenlock.sh"

conf_print_waybar_settings() {
  cat <<'EOF_waybar_settings_EOF'
True
EOF_waybar_settings_EOF
}
conf_print_waybar_settings | tee "${QTILE_SETTINGS}/waybar_settings.sh"

conf_print_waybar_systray() {
  cat <<'EOF_waybar_systray_EOF'
True
EOF_waybar_systray_EOF
}
conf_print_waybar_systray | tee "${QTILE_SETTINGS}/waybar_systray.sh"

conf_print_waybar_taskbar() {
  cat <<'EOF_waybar_taskbar_EOF'
False
EOF_waybar_taskbar_EOF
}
conf_print_waybar_taskbar | tee "${QTILE_SETTINGS}/waybar_taskbar.sh"

conf_print_waybar_theme() {
  cat <<'EOF_waybar_theme_EOF'
/ml4w-glass;/ml4w-glass/default
EOF_waybar_theme_EOF
}
conf_print_waybar_theme | tee "${QTILE_SETTINGS}/waybar-theme.sh"

conf_print_waybar_timeformat() {
  cat <<'EOF_waybar_timeformat_EOF'
%H:%M
EOF_waybar_timeformat_EOF
}
conf_print_waybar_timeformat | tee "${QTILE_SETTINGS}/waybar_timeformat.sh"

conf_print_waybar_toggle() {
  cat <<'EOF_waybar_toggle_EOF'
True
EOF_waybar_toggle_EOF
}
conf_print_waybar_toggle | tee "${QTILE_SETTINGS}/waybar_toggle.sh"

conf_print_waybar_window() {
  cat <<'EOF_waybar_window_EOF'
True
EOF_waybar_window_EOF
}
conf_print_waybar_window | tee "${QTILE_SETTINGS}/waybar_window.sh"

conf_print_wlogout_parameters() {
  cat <<'EOF_wlogout_parameters_EOF'
-b 3
EOF_wlogout_parameters_EOF
}
conf_print_wlogout_parameters | tee "${QTILE_SETTINGS}/wlogout-parameters.sh"
