from libqtile import bar, layout, qtile, widget, hook
from libqtile.config import Click, Drag, Group, Key, Match, Screen, KeyChord, ScratchPad, DropDown
from libqtile.lazy import lazy

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

import os

mod = "mod4"
terminal = "alacritty"
control = "control"
shift = "shift"
alt = "mod1"
home = os.path.expanduser('~')

discord_mod = "vesktop --enable-features=UseOsonePlatform --ozone-platform=wayland"
discord = "abaddon"

tapeta = '/home/godot/.config/qtile/wallpapers/theater_by_flaviobollo.jpg' 
#tapeta = '/home/godot/.config/qtile/wallpapers/McEscher-Street.jpg'

colors = [["#293136", "#293136"],   #bg_dim [0]
		  ["#333C43", "#333C43"],   #bg_0   [1]
          ["#3A464C", "#3A464C"],   #bg_1   [2]
          ["#434F55", "#434F55"],   #bg_2   [3]
          ["#4D5960", "#4D5960"],   #bg_3   [4]
          ["#555F66", "#555F66"],   #bg_4   [5]
          ["#7FBBB3", "#7FBBB3"],   #blue   [6]
		  ["#A7C080", "#A7C080"],   #green  [7]          
          ["#DBBC7F", "#DBBC7F"],   #yellow [8]
          ["#E69875", "#E69875"],   #orange [9]
		  ['#ED8082', '#ED8080'],   #red    [10]
        ['#00000000', '#00000000'], #transparent [11]
] 



keys = [
    #Kills focused window
    Key([mod], "q", lazy.window.kill(), desc="Kill focused window"), 
    # Switch between windows
    Key([mod], "h", lazy.layout.left(), desc="Move focus to left"),
    Key([mod], "l", lazy.layout.right(), desc="Move focus to right"),
    Key([mod], "j", lazy.layout.down(), desc="Move focus down"),
    Key([mod], "k", lazy.layout.up(), desc="Move focus up"),
    Key([mod], "space", lazy.layout.next(), desc="Move window focus to other window"),
    # Move windows between left/right columns or move up/down in current stack.
    # Moving out of range in Columns layout will create new column.
    Key([mod, "shift"], "h", lazy.layout.shuffle_left(), desc="Move window to the left"),
    Key([mod, "shift"], "l", lazy.layout.shuffle_right(), desc="Move window to the right"),
    Key([mod, "shift"], "j", lazy.layout.shuffle_down(), desc="Move window down"),
    Key([mod, "shift"], "k", lazy.layout.shuffle_up(), desc="Move window up"),
    # Grow windows. If current window is on the edge of screen and direction
    # will be to screen edge - window would shrink.
    Key([mod, "control"], "h", lazy.layout.grow_left(), desc="Grow window to the left"),
    Key([mod, "control"], "l", lazy.layout.grow_right(), desc="Grow window to the right"),
    Key([mod, "control"], "j", lazy.layout.grow_down(), desc="Grow window down"),
    Key([mod, "control"], "k", lazy.layout.grow_up(), desc="Grow window up"),
    Key([mod], "n", lazy.layout.normalize(), desc="Reset all window sizes"),
    # Toggle between split and unsplit sides of stack.
    # Split = all windows displayed
    # Unsplit = 1 window displayed, like Max layout, but still with
    # multiple stack panes
    Key(
        [mod, "shift"],
        "Return",
        lazy.layout.toggle_split(),
        desc="Toggle between split and unsplit sides of stack",
    ),
    # Toggle between different layouts as defined below
    Key([mod], "Tab", lazy.next_layout(), desc="Toggle between layouts"),
    Key([mod], "f", lazy.window.toggle_floating(), desc="Toggle floating on the focused window"),
    
    # Reload and shutdown
    Key([mod, "control"], "r", lazy.reload_config(), desc="Reload the config"),
    Key([mod, "control"], "q", lazy.shutdown(), desc="Shutdown Qtile"),

    # Shortcuts
    Key([mod], "Return", lazy.spawn('alacritty'), desc="Launch terminal"),
    Key([mod], "w", lazy.spawn("firefox"), desc="Launch firefox"),
    Key([mod], "e", lazy.spawn("betterbird"), desc="Launch betterbird"),
    Key([mod], "a", lazy.spawn(discord_mod), desc="Launch Vesktop"),
    Key([mod], "d", lazy.spawn(discord), desc="Launch Abaddon"),
    Key([mod], "k", lazy.spawn("keepassxc"), desc="Launch KeePassXC"),

    Key([mod], "s", lazy.spawn('rofi -show ssh'), desc="Spawn rofi SSH"),
    Key([mod], "r", lazy.spawn("rofi -show drun -show-icons"), desc="Spawn rofi drun"),
    
    # Scratchpads
    Key([mod], 'c', lazy.group['scratchpad'].dropdown_toggle('term')),
    Key([mod], 'v', lazy.group['scratchpad'].dropdown_toggle('btop')),

    # WLR-RANDR for second screen
    Key([mod, "control"], "Down", lazy.spawn("wlr-randr --output VGA-1 --transform normal"), desc="sets second monitor to normal rotation"),
    Key([mod, "control"], "Left", lazy.spawn("wlr-randr --output VGA-1 --transform 90"), desc="sets second monitor to 90 rotation"),
    Key([mod, "control"], "Up", lazy.spawn("wlr-randr --output VGA-1 --transform 180"), desc="sets second monitor to 180 rotation"),
    Key([mod, "control"], "Right", lazy.spawn("wlr-randr --output VGA-1 --transform 270"), desc="sets second monitor to 270 rotation"),

    # Change keyboard layout
    Key([mod], "z", lazy.widget["keyboardlayout"].next_keyboard(), desc="Next keyboard layout"),

]

# Add key bindings to switch VTs in Wayland.
# We can't check qtile.core.name in default config as it is loaded before qtile is started
# We therefore defer the check until the key binding is run by using .when(func=...)
for vt in range(1, 8):
    keys.append(
        Key(
            ["control", "mod1"],
            f"f{vt}",
            lazy.core.change_vt(vt).when(func=lambda: qtile.core.name == "wayland"),
            desc=f"Switch to VT{vt}",
        )
    )


groups = [
    ScratchPad("scratchpad", [
        DropDown("term", "alacritty",           width=0.8, height=0.8, x=0.1, y=0.1, opacity=1),
        DropDown("btop", "alacritty -e btop",   width=0.8, height=0.8, x=0.1, y=0.1, opacity=1),
    ]),
   
    Group("1"),
    Group("2"),
    Group("3"),
    Group("4"),
    Group("5"),
    Group("6"),
    Group("7"),
    Group("8"),
    Group("9"),
    Group("0"),
]

for i in groups:
    keys.extend(
        [
            # mod + group number = switch to group
            Key(
                [mod],
                i.name,
                lazy.group[i.name].toscreen(),
                desc=f"Switch to group {i.name}",
            ),
            # mod + shift + group number = switch to & move focused window to group
            Key(
                [mod, "shift"],
                i.name,
                lazy.window.togroup(i.name, switch_group=True),
                desc=f"Switch to & move focused window to group {i.name}",
            ),
            # Or, use below if you prefer not to switch to that group.
            # # mod + shift + group number = move focused window to group
            # Key([mod, "shift"], i.name, lazy.window.togroup(i.name),
            #     desc="move focused window to group {}".format(i.name)),
        ]
    )

layouts = [
    layout.Columns(),
    # layout.Max(),
    # layout.Stack(num_stacks=2),
    # layout.Bsp(),
    # layout.Matrix(),
    # layout.MonadTall(),
    # layout.MonadWide(),
    # layout.RatioTile(),
    # layout.Tile(),
    # layout.TreeTab(),
    # layout.VerticalTile(),
    # layout.Zoomy(),
]

widget_defaults = dict(
    font="JetBrainsMono Nerd Font",
    fontsize=12,
    padding=3,
)
extension_defaults = widget_defaults.copy()

# Eye candy widgets

rounded_left = {
    "decorations": [
        PowerLineDecoration(
            path='rounded_left',
            size=10,
        )
    ]
}

rounded_right = {
    "decorations": [
        PowerLineDecoration(
            path='rounded_right',
            size=10,
        )
    ]
}


# Funciton widgets

icon = widget.TextBox(
    text='  ',
    mouse_callbacks={"Button1":lazy.spawn("rofi -show drun -show-icons")},
    fontsize=20,
    margin=4,
    padding=3,
    background= colors[0],
    **rounded_left,
)

group_box = widget.GroupBox(
    highlight_method='line',
    highlight_color= colors[11],
    background = colors[2],
    other_current_screen_border = colors[6],
    other_screen_border = colors[6],
    **rounded_left,
)

#spacer needs fixed length so 1 for every screen
spacer_main = widget.Spacer(
        background = colors[11],   #transparent
       **rounded_right,
)

spacer_sec = widget.Spacer(
        background = colors[11],   #transparent
       **rounded_right,
)

kb_layout = widget.KeyboardLayout(
    configured_keyboards=['us', 'cz qwerty'],
    display_map={'us':'US', 'cz qwerty':'CZ'},
    fmt="  {} ",
    background=colors[4],
    **rounded_right,
) 

wifi = widget.Wlan(
    format = "󰖩  {essid} {percent:2.0%} ",    
    interface = "wlp2s0",
    mouse_callbacks={"Button1":lazy.spawn("alacritty --class float -e nmcli device wifi")},
    background=colors[2],
    **rounded_right,
)

vpn = widget.GenPollCommand(
    update_interval = 3600,
    background = colors[2],
    shell = True,
    cmd = "tailscale status --peers --json   | jq '.ExitNodeStatus.ID as $node_id | .Peer[] | select(.ID==$node_id) | .HostName'",
    **rounded_right,
)

ram = widget.Memory(
    format = " {MemFree:.0f} 󰓡 {SwapFree:.0f}",
    mouse_callbacks={"Button1":lazy.group['scratchpad'].dropdown_toggle('btop')},
    background=colors[6],
    mesure_mem="M",
    mesure_swap="M",
)

cpu = widget.CPU(
    format = " {load_percent}% ",
    mouse_callbacks={"Button1":lazy.group['scratchpad'].dropdown_toggle('btop')},
    background=colors[6],
    **rounded_right,
)

battery = widget.Battery(
    format="{char} {percent:2.0%} {hour:d}:{min:02d} ",
    background=colors[8],
    low_background=colors[10],
    charge_char = "󰂄",
    discharge_char = "󰁼",
    empty_char= "󱃍",
    **rounded_right,
)

clock = widget.Clock(
    format="  %y-%m-%d %a %H:%M ",
    background=colors[0],
    padding = 5,
)

screens = [
    Screen(
        wallpaper = tapeta,
        wallpaper_mode ='stretch' ,

        left=bar.Gap(5),
        right=bar.Gap(5),
        bottom=bar.Gap(5),

        top=bar.Bar(
            [
                icon,
                group_box,
                spacer_main,
                kb_layout,
                wifi,
                vpn,
                ram,
                cpu,
                battery,
                clock,
            ], 30,
            margin = 6,
        ),
    ),
    Screen(
        wallpaper= tapeta,
        wallpaper_mode= 'fill',
        
        left=bar.Gap(5),
        right=bar.Gap(5),
        bottom=bar.Gap(5),

        top=bar.Bar(
            [
                icon,
                group_box,
                spacer_sec,
                kb_layout,
                wifi,
                vpn,
                ram,
                cpu,
                battery,
                clock,
            ], 30,
            margine = 6,
        ),
    ),
]

# 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()),
]

dgroups_key_binder = None
dgroups_app_rules = []  # type: list
follow_mouse_focus = True
bring_front_click = False
floats_kept_above = True
cursor_warp = False
floating_layout = layout.Floating(
    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 
        Match(wm_class="float"), #onclick widget
    ]
)

# !TODO breaking changes
#autostart bash script
#@hook.subscribe.startup_once
#def autostart():
#    script = os.path.expanduser("~/.config/qtile/autostart.sh")
#    subprocess.run([script])


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

# When using the Wayland backend, this can be used to configure input devices.
wl_input_rules = None

# xcursor theme (string or None) and size (integer) for Wayland backend
wl_xcursor_theme = None
wl_xcursor_size = 24

# 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.
wmname = "LG3D"
