#!/usr/bin/python3

import setproctitle
import os
import gi
import gettext
import sys
import glob
from SettingsWidgets import *

gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gio, GLib

try:
    import lsb_release
except:
    pass

setproctitle.setproctitle("lightdm-settings")

gettext.install("lightdm-settings", "/usr/share/locale")

CONF_PATH = "/etc/lightdm/slick-greeter.conf"
LIGHTDM_CONF_PATH = "/etc/lightdm/lightdm.conf"
LIGHTDM_GROUP_NAMES = ["SeatDefaults", "Seat:*"]

class Application(Gtk.Application):
    ''' Create the UI '''
    def __init__(self):

        Gtk.Application.__init__(self, application_id='com.linuxmint.lightdm-settings', flags=Gio.ApplicationFlags.FLAGS_NONE)

    def do_activate(self):
        list = self.get_windows()
        if len(list) > 0:
            # Application is already running, focus the window
            self.get_active_window().present()
        else:
            self.window = Gtk.ApplicationWindow.new(self)
            self.window.set_title(_("Login Window"))
            self.window.set_icon_name("lightdm-settings")
            self.window.set_default_size(640, 400)
            self.create_window()
            self.window.show_all()

    def _is_gnome(self):
        if "XDG_CURRENT_DESKTOP" in os.environ:
            if "GNOME" in os.environ["XDG_CURRENT_DESKTOP"]:
                return True

        return False

    # callback function for "quit"
    def quit_cb(self, action, parameter):
        self.quit()

    def do_startup(self):
        Gtk.Application.do_startup(self)

        if self._is_gnome():
            menu = Gio.Menu()
            menu.append(_("Quit"), "app.quit")
            quit_action = Gio.SimpleAction.new("quit", None)
            quit_action.connect("activate", self.quit_cb)
            self.add_action(quit_action)
            self.set_app_menu(menu)

    def create_window(self):
        if self._is_gnome():
            headerbar = Gtk.HeaderBar.new()
            headerbar.set_show_close_button(True)
            headerbar.set_title(_("Login Window"))
            self.window.set_titlebar(headerbar)
            self.window.set_show_menubar(False)
        else:
            self.add_window(self.window)

        self.main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

        # Toolbar
        # toolbar = Gtk.Toolbar()
        # toolbar.get_style_context().add_class("primary-toolbar")
        # self.main_box.pack_start(toolbar, False, False, 0)

        self.main_stack = Gtk.Stack()
        self.main_stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
        self.main_stack.set_transition_duration(150)
        self.main_box.pack_start(self.main_stack, True, True, 0)

        # stack_switcher = Gtk.StackSwitcher()
        # stack_switcher.set_stack(self.main_stack)
        # tool_item = Gtk.ToolItem()
        # tool_item.set_expand(True)
        # tool_item.get_style_context().add_class("raised")
        # toolbar.insert(tool_item, 0)
        # switch_holder = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        # switch_holder.set_border_width(1)
        # tool_item.add(switch_holder)
        # # switch_holder.pack_start(stack_switcher, True, True, 0)
        # stack_switcher.set_halign(Gtk.Align.CENTER)
        # toolbar.show_all()

        settings = Gio.Settings("x.dm.slick-greeter")

        debug = False
        if len(sys.argv) > 1 and sys.argv[1] == "debug":
            debug = True

        # Slick settings
        keyfile = GLib.KeyFile()
        try:
            keyfile.load_from_file(CONF_PATH, 0)
        except:
            print("Could not load %s." % CONF_PATH)

        # LightDM settings
        lightdm_keyfile = GLib.KeyFile()
        try:
            lightdm_keyfile.load_from_file(LIGHTDM_CONF_PATH, GLib.KeyFileFlags.KEEP_COMMENTS)
        except:
            print("Could not load %s." % LIGHTDM_CONF_PATH)

        page = SettingsPage()

        section = page.add_section(_("Settings"))

        section.add_row(SettingsRow(Gtk.Label(_("Draw a grid")), SettingsSwitch(keyfile, settings, "draw-grid")))

        try:
            distro = lsb_release.get_lsb_information()['ID']
            if distro.lower() in ['linuxmint', 'ubuntu', 'elementary']:
                # AccountsService doesn't support Background selection. It's something that is patched in Ubuntu, so only support this feature
                # in Ubuntu derivatives
                section.add_row(SettingsRow(Gtk.Label(_("Draw user backgrounds")), SettingsSwitch(keyfile, settings, "draw-user-backgrounds")))
        except:
            pass
        section.add_row(SettingsRow(Gtk.Label(_("Show hostname")), SettingsSwitch(keyfile, settings, "show-hostname")))

        row = section.add_row(SettingsRow(Gtk.Label(_("Logo")), SettingsPictureChooser(keyfile, settings, "logo")))
        row = section.add_row(SettingsRow(Gtk.Label(_("Background logo")), SettingsPictureChooser(keyfile, settings, "background-logo")))
        row = section.add_row(SettingsRow(Gtk.Label(_("Background")), SettingsPictureChooser(keyfile, settings, "background")))

        row = section.add_row(SettingsRow(Gtk.Label(_("Background color")), SettingsColorChooser(keyfile, settings, "background-color")))

        row = section.add_row(SettingsRow(Gtk.Label(_("GTK theme")), SettingsCombo(keyfile, settings, "theme-name", self.get_gtk_themes(), "string")))
        row = section.add_row(SettingsRow(Gtk.Label(_("Icon theme")), SettingsCombo(keyfile, settings, "icon-theme-name", self.get_icon_themes(), "string")))

        hidpi_options = []
        hidpi_options.append(["auto", _("Auto")])
        hidpi_options.append(["on", _("Enable")])
        hidpi_options.append(["off", _("Disable")])
        section.add_row(SettingsRow(Gtk.Label(_("HiDPI support")), SettingsCombo(keyfile, settings, "enable-hidpi", hidpi_options, "string")))


        guest_sessions_allowed = self.get_lightdm_config ("allow-guest", True)
        row  = SettingsRow(Gtk.Label(_("Allow guest sessions")), LightDMSwitch(lightdm_keyfile, "allow-guest", guest_sessions_allowed))
        row.set_tooltip_text(_("Reboot for this option to take effect"))
        section.add_row(row)

        self.window.add(self.main_box)

        self.main_stack.add_titled(page, "settings", _("Settings"))

        self.window.show_all()

    def walk_directories(self, dirs, filter_func, return_directories=False):
        # If return_directories is False: returns a list of valid subdir names
        # Else: returns a list of valid tuples (subdir-names, parent-directory)
        valid = []
        try:
            for thdir in dirs:
                if os.path.isdir(thdir):
                    for t in os.listdir(thdir):
                        if filter_func(os.path.join(thdir, t)):
                            if return_directories:
                                valid.append([t, thdir])
                            else:
                                valid.append(t)
        except:
            pass
            #logging.critical("Error parsing directories", exc_info=True)
        return valid


    def filter_func_gtk_dir(self, directory):
        # returns whether a directory is a valid GTK theme
        if os.path.exists(os.path.join(directory, "gtk-2.0")):
            if os.path.exists(os.path.join(directory, "gtk-3.0")):
                return True
            else:
                for subdir in glob.glob("%s/gtk-3.*" % directory):
                    return True
        return False

    def get_gtk_themes(self):
        try:
            """ Only shows themes that have variations for gtk+-3 and gtk+-2 """
            dirs = ["/usr/share/themes"]
            valid = self.walk_directories(dirs, self.filter_func_gtk_dir, return_directories=True)
            valid.sort(key=lambda a: a[0].lower())
            res = []
            for i in valid:
                for j in res:
                    if i[0] == j[0]:
                        if i[1] == dirs[0]:
                            continue
                        else:
                            res.remove(j)
                res.append((i[0], i[0]))
            return res
        except:
            print ("WOW")

    def get_icon_themes(self):
        dirs = ("/usr/share/icons", os.path.join(os.path.expanduser("~"), ".icons"))
        walked = self.walk_directories(dirs, lambda d: os.path.isdir(d), return_directories=True)
        valid = []
        for directory in walked:
            path = os.path.join(directory[1], directory[0], "index.theme")
            if os.path.exists(path):
                try:
                    for line in list(open(path)):
                        if line.startswith("Directories="):
                            valid.append(directory)
                            break
                except Exception as e:
                    print (e)

        valid.sort(key=lambda a: a[0].lower())
        res = []
        for i in valid:
            for j in res:
                if i[0] == j:
                    if i[1] == dirs[0]:
                        continue
                    else:
                        res.remove(j)
            res.append([i[0], i[0]])
        return res

    def get_lightdm_config (self, key, default_value):
        value = default_value
        for path in ["/usr/share/lightdm/lightdm.conf.d", "/etc/lightdm/lightdm.conf.d", "/etc/lightdm/lightdm.conf"]:
            if os.path.exists(path):
                if os.path.isdir(path):
                    files = sorted(os.listdir(path))
                    for file in files:
                        if file.endswith(".conf"):
                            full_path = os.path.join(path, file)
                            try:
                                keyfile = GLib.KeyFile()
                                keyfile.load_from_file(full_path, 0)
                                for group in LIGHTDM_GROUP_NAMES:
                                    if keyfile.has_group(group):
                                        value = keyfile.get_boolean(group, key)
                            except:
                                pass
                else:
                    try:
                        keyfile = GLib.KeyFile()
                        keyfile.load_from_file(path, 0)
                        for group in LIGHTDM_GROUP_NAMES:
                            if keyfile.has_group(group):
                                value = keyfile.get_boolean(group, key)
                    except:
                        pass
        return (value)

if __name__ == "__main__":
    app = Application()
    app.run(None)
