import wx
import sys

wx_msw_dark_mode = 1

# Function to detect dark mode on Windows
def is_dark_mode_windows():
    if sys.platform != 'win32':
        return None  # Not Windows
    try:
        import winreg
        registry = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
        key_path = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize'
        key = winreg.OpenKey(registry, key_path)
        # The value 'AppsUseLightTheme' is 0 for dark, 1 for light
        value, regtype = winreg.QueryValueEx(key, 'AppsUseLightTheme')
        winreg.CloseKey(key)
        return 'Light' if value == 1 else 'Dark'
    except Exception:
        return None

# Function to detect dark mode on macOS
def is_dark_mode_macos():
    import subprocess
    try:
        result = subprocess.run(
            ['defaults', 'read', '-g', 'AppleInterfaceStyle'],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True
        )
        if 'Dark' in result.stdout:
            return 'Dark'
        else:
            return 'Light'
    except Exception:
        return None

# Function to detect dark mode on Linux
def is_dark_mode_linux():
    import subprocess

    # First attempt: use the 'color-scheme' key (recommended method) - Okay for Fedora 43
    try:
        result = subprocess.check_output(
            ['gsettings', 'get', 'org.gnome.desktop.interface', 'color-scheme'],
            text=True
        ).strip()

        # The value usually returns 'prefer-dark' or 'prefer-light' (with single quotes)
        if result.lower() == "'prefer-dark'":
            return 'Dark'
        elif result.lower() == "'prefer-light'":
            return 'Light'
        # If the value is different, we can continue with the fallback method
    except Exception:
        # If the key does not exist or there is an error, we switch to the fallback method.
        pass

    # Second attempt: using the GTK theme - Okay for Mint 21
    try:
        theme = subprocess.check_output(
            ['gsettings', 'get', 'org.gnome.desktop.interface', 'gtk-theme'],
            text=True
        ).strip()

        # Check if the theme contains 'dark' or 'Dark'
        if 'dark' in theme.lower():
            return 'Dark'
        else:
            return 'Light'
    except Exception:
        return None

# Function to detect the overall theme
def get_os_theme():
    if sys.platform == 'win32':
        mode = is_dark_mode_windows()
        if mode:
            return mode
        else:
            return 'Light'
    elif sys.platform == 'darwin':
        mode = is_dark_mode_macos()
        if mode:
            return mode
        else:
            return 'Light'
    else:
        # Linux (GNOME)
        mode = is_dark_mode_linux()
        if mode:
            return mode
        else:
            return 'Light'

class MyPanel(wx.Panel):
    def __init__(self, parent):
        super().__init__(parent)
        
        theme = get_os_theme()

        # A font can be retrieved from the OS default font
        # and modified
        font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
        font.SetStyle(wx.NORMAL)
        fontSize = self.GetFont().GetPointSize()
        font.SetPointSize(fontSize+4)
        
        # Display the information in the panel
        msg_1 = f"Current system theme : {theme}"
        label_1 = wx.StaticText(self, label=msg_1, style=wx.ALIGN_CENTER)
        msg_2 = f"Works correctly with :"
        label_2 = wx.StaticText(self, label=msg_2, style=wx.ALIGN_CENTER)
        msg_3 = f"● wxPython 4.2.5, wxWidgets 3.2.9"
        label_3 = wx.StaticText(self, label=msg_3, style=wx.ALIGN_CENTER)
        msg_4 = f"● Windows 11"
        label_4 = wx.StaticText(self, label=msg_4, style=wx.ALIGN_CENTER)
        msg_5 = f"● Mint 21"
        label_5 = wx.StaticText(self, label=msg_5, style=wx.ALIGN_CENTER)
        msg_6 = f"● Fedora 43"
        label_6 = wx.StaticText(self, label=msg_6, style=wx.ALIGN_CENTER)
        
        font.SetWeight(wx.BOLD)
        label_1.SetFont(font)
        font.SetWeight(wx.NORMAL)
        label_2.SetFont(font)
        label_3.SetFont(font)
        label_4.SetFont(font)
        label_5.SetFont(font)
        label_6.SetFont(font)
        
        # Layout
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.AddStretchSpacer()
        sizer.Add(label_1, 0, wx.ALL | wx.CENTER, 10)
        sizer.Add(label_2, 0, wx.ALL | wx.CENTER, 10)
        sizer.Add(label_3, 0, wx.ALL | wx.CENTER, 10)
        sizer.Add(label_4, 0, wx.ALL | wx.CENTER, 10)
        sizer.Add(label_5, 0, wx.ALL | wx.CENTER, 10)
        sizer.Add(label_6, 0, wx.ALL | wx.CENTER, 10)
        sizer.AddStretchSpacer()
        self.SetSizer(sizer)
        
class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title="Retrieve the system theme", size=(600, 400))
        
        self.panel = MyPanel(self)
        self.Show()

class MyApp(wx.App):
    def OnInit(self):
        # The following does not work with wxpython-4.3.0a16030 :
        # wx.SystemOptions.SetOption("msw.dark-mode", True)
        # or
        # self.SetAppearance()   # System | Dark | Light
        
        self.frame = MyFrame()
        self.frame.Show()
        return True

if __name__ == "__main__":
    app = MyApp()
    app.MainLoop()
