#!/usr/bin/python3

#   swaycaffeine - Easy access to Sway's idle inhibitors
#   Copyright (C) 2023  Damian Ludwig <ludwigd@fedoraproject.org>
#
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <https://www.gnu.org/licenses/>.

import sys
from argparse import ArgumentParser
from i3ipc import Connection as Sway

class SwayCaffeine:
    
    def __init__(self, title_format_default, title_format_inhibitor):
        self.wm = Sway()
        self.title_format_default = title_format_default
        self.title_format_inhibitor = title_format_inhibitor

    def set_or_toggle_inhibitor(self, win, inhibitor, toggle=False):
        user_inhibitor = win.ipc_data['idle_inhibitors']['user']
        if user_inhibitor != 'none' and toggle:
            self.set_inhibitor(win, 'none')
            self.set_window_title_format(win, self.title_format_default)
        else:
            self.set_inhibitor(win, inhibitor)
            self.set_window_title_format(win, self.title_format_inhibitor)

    def clear_all_inhibitors(self):
        windows = self.wm.get_tree().leaves()
        for win in windows:
            self.set_inhibitor(win, 'none')
            self.set_window_title_format(win, self.title_format_default)

    def set_inhibitor(self, win, inhibitor):
        win.command("inhibit_idle \"{0}\"".format(inhibitor))
        
    def set_window_title_format(self, win, title_format):
        win.command("title_format \"{0}\"".format(title_format))

    def list_windows(self):
        windows = self.wm.get_tree().leaves()
        print("{0:>10} {1:>4} {2}".format("INHIBITOR", "ID", "NAME"))
        for win in windows:
            inhibitor = win.ipc_data['idle_inhibitors']['user']
            print("{0:>10} {1:>4} {2}".format(inhibitor, win.id, win.name[0:50]))
        print()

    def get_window(self, id):
        if id > 0:
            win = self.wm.get_tree().find_by_id(id)
        else:
            win = self.wm.get_tree().find_focused()
        if win == None:
            print("Unknown window id. Exit!")
            exit(1)
        return win

if __name__=="__main__":
    parser = ArgumentParser(prog='swaycaffeine',
                            description='Easy access Sway\'s idle inhibitors.',
                            epilog='Author: ludwigd@fedoraproject.org')
    parser.add_argument('-i', '--inhibitor',
                        choices=['visible', 'focus', 'fullscreen', 'open', 'none'],
                        required=False,
                        default='open',
                        action='store',
                        help='The idle inhibitor to set.')
    parser.add_argument('-t', '--toggle',
                        required=False,
                        action='store_true',
                        help='Toggles the inhibitor instead of setting it.')
    parser.add_argument('-w', '--window',
                        required=False,
                        action='store',
                        default=-1,
                        type=int,
                        help='ID of the target window.')
    parser.add_argument('-c', '--clear-all',
                        required=False,
                        action='store_true',
                        help='Clear idle inhibitors for all windows.')
    parser.add_argument('-l', '--list',
                        required=False,
                        action='store_true',
                        help='Lists all windows and their idle inhibitors.')
    parser.add_argument('-f', '--title-format-default',
                        required=False,
                        default='%title',
                        action='store',
                        help='Title format for windows without idle inhibitor.')
    parser.add_argument('-F', '--title-format-inhibitor',
                        required=False,
                        default='&#9749; %title',
                        action='store',
                        help='Title format for windows with idle inhibitor.')
    args = parser.parse_args()
    
    caffeine = SwayCaffeine(args.title_format_default, args.title_format_inhibitor)

    if args.list or len(sys.argv)==1:
        caffeine.list_windows()
    elif args.clear_all:
        caffeine.clear_all_inhibitors()
    else:
        win = caffeine.get_window(args.window)
        caffeine.set_or_toggle_inhibitor(win, args.inhibitor, args.toggle)
