# coding=utf-8
# python 2

# Copyright (c) 2026 TormachTips.com. All rights reserved.
# Licensed under the TormachTips Personal Use License.
# Permission is granted only for private personal use and private personal modification.
# No sharing, publication, distribution, resale, sublicensing, screenshots, code excerpts,
# benchmarks, or videos are permitted without prior written permission.
# Requests:         tormach.1100m@gmail.com
# Information page: https://tormachtips.com/plugins.htm

#############################################
##                                         ##
##          Main Tab F Key 0.97            ##
##          www.tormachtips.com            ##
##                                         ##
#############################################

# 0.97 - set tab color                          - 6/06/2026
# 0.96 - F-key is user-configurable by constant - 6/06/2026
# 0.95 - public beta                            - 6/06/2026

import os
import gtk
import glib
import constants
import singletons
from ui_hooks import plugin

CURRENT_VER          = "0.97"
SCRIPT_NAME          = "Main Tab F Key Plugin"
DESCRIPTION          = "Binds a user-selected F key to the PathPilot Main tab and renames the tab label."
ENABLED              = 1
DEV_MACHINE          = 1
DEV_MACHINE_FLAG     = "/home/operator/gcode/python/dev_machine.txt"
START_DELAY_MS       = 3000
MAIN_TAB_F_KEY       = "F6"
MAIN_PAGE_ID         = "notebook_main_fixed"
MAIN_TAB_LABEL_TEXT  = "Main (%s)" % MAIN_TAB_F_KEY
MAIN_TAB_LABEL_COLOR = "AUTO"

# Set to "AUTO" to match the existing Main tab label style when possible.
# Or force a color with "white", "black", "#ffffff", "#000000", etc.

class UserPlugin(plugin):
    def __init__(self):
        plugin.__init__(self, SCRIPT_NAME)
        self._key_handler_id = None
        self._ui = None
        self._main_tab_keyval = None
        dev_machine_found = os.path.exists(DEV_MACHINE_FLAG)
        if dev_machine_found:
            plugin_enabled = DEV_MACHINE
        else:
            plugin_enabled = ENABLED
        if plugin_enabled:
            glib.timeout_add(START_DELAY_MS, self.start_process)
        else:
            if dev_machine_found:
                self.error_handler.write("[%s] Dev machine found. Plugin loaded, but disabled by DEV_MACHINE." % SCRIPT_NAME,constants.ALARM_LEVEL_QUIET)
            else:
                self.error_handler.write("[%s] Plugin loaded, but disabled." % SCRIPT_NAME,constants.ALARM_LEVEL_QUIET)

    def start_process(self):
        try:
            ui = singletons.g_Machine
            if not ui:
                self.error_handler.write("[%s] Machine UI not ready yet." % SCRIPT_NAME,constants.ALARM_LEVEL_LOW)
                return True
            self._ui = ui
            self._main_tab_keyval = self.get_configured_keyval()
            if self._main_tab_keyval is None:
                self.error_handler.write("[%s] Invalid MAIN_TAB_F_KEY setting: %s" % (SCRIPT_NAME, MAIN_TAB_F_KEY),constants.ALARM_LEVEL_LOW)
                return False
            self.set_main_tab_label(ui)
            self.bind_main_tab_key(ui)
            self.error_handler.write("[%s] %s bound to Main tab." % (SCRIPT_NAME, MAIN_TAB_F_KEY),constants.ALARM_LEVEL_QUIET)
        except Exception as e:
            self.error_handler.write("[%s] Startup error: %s" % (SCRIPT_NAME, str(e)),constants.ALARM_LEVEL_LOW)
        return False

    def get_configured_keyval(self):
        try:
            key_name = str(MAIN_TAB_F_KEY).strip().upper()
            if key_name == "":
                return None
            return getattr(gtk.keysyms, key_name)
        except Exception:
            return None

    def bind_main_tab_key(self, ui):
        if self._key_handler_id is not None:
            return
        if not hasattr(ui, "window") or ui.window is None:
            raise Exception("UI window not available")
        self._key_handler_id = ui.window.connect("key-press-event",self.on_key_press)

    def on_key_press(self, widget, event):
        try:
            if self._main_tab_keyval is not None and event.keyval == self._main_tab_keyval:
                self.go_to_main_tab()
                return True
        except Exception as e:
            try:
                self.error_handler.write("[%s] %s handler error: %s" % (SCRIPT_NAME, MAIN_TAB_F_KEY, str(e)),constants.ALARM_LEVEL_LOW)
            except Exception:
                pass
        return False

    def go_to_main_tab(self):
        ui = self._ui
        if ui is None:
            ui = singletons.g_Machine
        if ui is None:
            return
        page = None
        try:
            page = ui.builder.get_object(MAIN_PAGE_ID)
        except Exception:
            page = None
        if page is None:
            try:
                page = getattr(ui, MAIN_PAGE_ID)
            except Exception:
                page = None
        if page is None:
            self.error_handler.write("[%s] Main tab page not found: %s" % (SCRIPT_NAME, MAIN_PAGE_ID),constants.ALARM_LEVEL_LOW)
            return
        page_num = ui.notebook.page_num(page)
        if page_num == -1:
            self.error_handler.write("[%s] Main tab is not present in notebook." % SCRIPT_NAME,constants.ALARM_LEVEL_LOW)
            return
        ui.notebook.set_current_page(page_num)

    def set_main_tab_label(self, ui):
        try:
            page = ui.builder.get_object(MAIN_PAGE_ID)
            if page is None:
                return
            tab_widget = ui.notebook.get_tab_label(page)
            if tab_widget is None:
                return
            label = self.find_label_widget(tab_widget)
            if label is None:
                return
            if self.use_markup_for_tab_label(label):
                color = self.get_tab_label_color(label)
                if color:
                    label.set_use_markup(True)
                    label.set_markup(
                        '<span foreground="%s">%s</span>' %
                        (color, self.escape_markup(MAIN_TAB_LABEL_TEXT)))
                else:
                    label.set_text(MAIN_TAB_LABEL_TEXT)
            else:
                label.set_text(MAIN_TAB_LABEL_TEXT)
        except Exception as e:
            self.error_handler.write(
                "[%s] Could not set Main tab label: %s" % (SCRIPT_NAME, str(e)),
                constants.ALARM_LEVEL_LOW)

    def use_markup_for_tab_label(self, label):
        try:
            forced_color = str(MAIN_TAB_LABEL_COLOR).strip()
            if forced_color.upper() != "AUTO":
                return True
            text = label.get_label()
            if "<span" in text or "foreground=" in text:
                return True
        except Exception:
            pass
        return False

    def get_tab_label_color(self, label):
        try:
            forced_color = str(MAIN_TAB_LABEL_COLOR).strip()
            if forced_color and forced_color.upper() != "AUTO":
                return forced_color
            existing_text = label.get_label()
            match = None
            try:
                import re
                match = re.search(
                    r'foreground\s*=\s*["\']([^"\']+)["\']',
                    existing_text,
                    re.IGNORECASE)
            except Exception:
                match = None
            if match:
                return match.group(1)
            style = label.get_style()
            if style:
                color = style.fg[gtk.STATE_NORMAL]
                # Convert GTK 16-bit color values to CSS-style #RRGGBB.
                red = int(color.red / 257)
                green = int(color.green / 257)
                blue = int(color.blue / 257)
                return "#%02x%02x%02x" % (red, green, blue)
        except Exception:
            pass
        return ""

    def escape_markup(self, text):
        try:
            return glib.markup_escape_text(str(text))
        except Exception:
            text = str(text)
            text = text.replace("&", "&amp;")
            text = text.replace("<", "&lt;")
            text = text.replace(">", "&gt;")
            return text

    def find_label_widget(self, widget):
        try:
            if isinstance(widget, gtk.Label):
                return widget
            if hasattr(widget, "get_children"):
                for child in widget.get_children():
                    found = self.find_label_widget(child)
                    if found is not None:
                        return found
        except Exception:
            pass
        return None