#!/usr/bin/env python3

import subprocess
from pathlib import Path

import gi

gi.require_version("Gtk", "3.0")
gi.require_version("GtkLayerShell", "0.1")

from gi.repository import Gtk, Gdk, GdkPixbuf, GLib, GtkLayerShell


CONFIG_FILE = Path("/etc/ekklesia-classroom/device.conf")
CSS_FILE = Path("/etc/ekklesia-classroom/dock/style.css")
ICON_DIR = Path("/etc/ekklesia-classroom/icons")


def read_device_config():
    config = {}

    if not CONFIG_FILE.exists():
        return config

    for raw_line in CONFIG_FILE.read_text().splitlines():
        line = raw_line.strip()

        if not line or line.startswith("#") or "=" not in line:
            continue

        key, value = line.split("=", 1)
        config[key.strip()] = value.strip()

    return config


def enabled(config, key, default=False):
    if key not in config:
        return default

    return config[key].lower() in {
        "1",
        "true",
        "yes",
        "on",
        "enabled",
    }


def launch(command):
    subprocess.Popen(
        command,
        start_new_session=True,
    )


def notify(title, message):
    launch([
        "notify-send",
        "--app-name=Ekklesia Classroom",
        title,
        message,
    ])


def themed_icon(*names):
    theme = Gtk.IconTheme.get_default()

    for name in names:
        if theme.has_icon(name):
            return Gtk.Image.new_from_icon_name(name, Gtk.IconSize.DIALOG)

    return Gtk.Image.new_from_icon_name(
        "application-x-executable",
        Gtk.IconSize.DIALOG,
    )


def custom_icon(filename, size):
    path = ICON_DIR / filename

    if path.exists():
        pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
            str(path),
            size,
            size,
            True,
        )
        return Gtk.Image.new_from_pixbuf(pixbuf)

    return None


class ClassroomDock(Gtk.Window):
    def __init__(self):
        super().__init__()
        screen = self.get_screen()
        visual = screen.get_rgba_visual()

        if visual is not None:
            self.set_visual(visual)

        self.set_app_paintable(True)
        self.config = read_device_config()

        self.set_name("classroom-dock")
        self.set_decorated(False)
        self.set_resizable(False)

        GtkLayerShell.init_for_window(self)
        GtkLayerShell.set_layer(self, GtkLayerShell.Layer.TOP)

        GtkLayerShell.set_anchor(
            self,
            GtkLayerShell.Edge.BOTTOM,
            True,
        )

        GtkLayerShell.set_margin(
            self,
            GtkLayerShell.Edge.BOTTOM,
            12,
        )

        GtkLayerShell.set_keyboard_interactivity(self, False)

        dock = Gtk.Box(
            orientation=Gtk.Orientation.HORIZONTAL,
            spacing=10,
        )
        dock.get_style_context().add_class("dock")

        dock.pack_start(
            self.make_button(
                self.browser_icon(),
                "Browser",
                lambda *_: launch(
                    ["/usr/local/bin/classroom-browser"]
                ),
            ),
            False,
            False,
            0,
        )

        if enabled(self.config, "DVD_ENABLED", False):
            dock.pack_start(
                self.make_button(
                    self.dvd_icon(),
                    "DVD",
                    lambda *_: notify(
                        "DVD",
                        "DVD support is being prepared.",
                    ),
                ),
                False,
                False,
                0,
            )

        dock.pack_start(
            self.make_button(
                self.sanctuary_icon(),
                "Sanctuary",
                lambda *_: notify(
                    "Sanctuary",
                    "Sanctuary live view is being prepared.",
                ),
            ),
            False,
            False,
            0,
        )

        self.add(dock)

    def browser_icon(self):
        image = custom_icon("browser.svg", 28)
        if image is not None:
            return image

        image = themed_icon("web-browser-symbolic", "internet-web-browser-symbolic")
        image.set_pixel_size(28)
        return image

    def dvd_icon(self):
        image = custom_icon("dvd.svg", 40)

        if image is not None:
            return image

        image = themed_icon(
            "media-optical-symbolic",
            "media-optical",
        )
        image.set_pixel_size(28)
        return image

    def sanctuary_icon(self):
        is_live = enabled(
            self.config,
            "SANCTUARY_LIVE",
            False,
        )

        filename = "live.svg" if is_live else "live-off.svg"

        image = custom_icon(filename, 38)

        if image is not None:
            return image

        image = themed_icon(
            "video-display-symbolic",
            "video-display",
        )
        image.set_pixel_size(28)

        return image

    def make_button(self, image, tooltip, callback):
        button = Gtk.Button()
        button.set_relief(Gtk.ReliefStyle.NONE)
        button.get_style_context().add_class("dock-button")

        button.add(image)
        button.connect("clicked", callback)

        return button

class ClassroomClock(Gtk.Window):
    def __init__(self):
        super().__init__()
        screen = self.get_screen()
        visual = screen.get_rgba_visual()

        if visual is not None:
            self.set_visual(visual)

        self.set_app_paintable(True)

        self.set_name("classroom-clock")
        self.set_decorated(False)
        self.set_resizable(False)

        GtkLayerShell.init_for_window(self)
        GtkLayerShell.set_layer(self, GtkLayerShell.Layer.TOP)

        GtkLayerShell.set_anchor(
            self,
            GtkLayerShell.Edge.BOTTOM,
            True,
        )

        GtkLayerShell.set_anchor(
            self,
            GtkLayerShell.Edge.RIGHT,
            True,
        )

        GtkLayerShell.set_margin(
            self,
            GtkLayerShell.Edge.BOTTOM,
            16,
        )

        GtkLayerShell.set_margin(
            self,
            GtkLayerShell.Edge.RIGHT,
            20,
        )

        GtkLayerShell.set_keyboard_interactivity(self, False)

        self.label = Gtk.Label()
        self.label.get_style_context().add_class("clock")
        self.add(self.label)

        self.update_time()
        GLib.timeout_add_seconds(15, self.update_time)

    def update_time(self):
        from datetime import datetime

        self.label.set_text(
            datetime.now().strftime("%-I:%M %p")
        )

        return True

def load_css():
    provider = Gtk.CssProvider()
    provider.load_from_path(str(CSS_FILE))

    screen = Gdk.Screen.get_default()

    Gtk.StyleContext.add_provider_for_screen(
        screen,
        provider,
        Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
    )


def main():
    load_css()

    dock = ClassroomDock()
    dock.connect("destroy", Gtk.main_quit)
    dock.show_all()

    clock = ClassroomClock()
    clock.show_all()

    Gtk.main()


if __name__ == "__main__":
    main()