"""
Regex Builder tab component for the Excel Filter GUI
"""

import tkinter as tk
from tkinter import ttk, messagebox
import tkinter.font as tkfont
import re
import os
import sys

# Update the import to use absolute path
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from translations import Translations


class RegexBuilderTab:

    def __init__(self, parent_frame, win11_colors, scale_factor=1.0, main_gui=None):
        """
        Initialize the enhanced regex builder tab

        Args:
            parent_frame: Parent frame to attach to
            win11_colors: Windows 11 color palette dictionary
            scale_factor: DPI scaling factor for high-resolution displays
            main_gui: Reference to main GUI for pattern application
        """
        self.frame = ttk.Frame(parent_frame)
        self.win11_colors = win11_colors
        self.scale_factor = scale_factor
        self.main_gui = main_gui
        self.translations = getattr(main_gui, 'translations', Translations()) if main_gui else Translations()

        # Scale factors for DPI-aware sizing - ensure minimum text size of 12
        self.scaled_padding = int(10 * self.scale_factor)
        self.scaled_title_font = max(int(14 * self.scale_factor), 12)
        self.scaled_normal_font = max(int(10 * self.scale_factor), 12)
        self.scaled_bold_font = max(int(11 * self.scale_factor), 12)

        # Variables for pattern building and testing
        self.regex_pattern_var = tk.StringVar()
        self.test_text_var = tk.StringVar(value=self.translations.get("default_test_text", "Beispieltext mit error und warning 123 Zahlen und E-Mail: test@example.com"))
        self.test_result_var = tk.StringVar(value=self.translations.get("default_result", "Hier erscheint das Testergebnis..."))
        self.test_matches_var = tk.StringVar(value=self.translations.get("no_matches", "Keine Treffer"))
        self.pattern_description_var = tk.StringVar(value=self.translations.get("auto_desc", "Beschreibung wird automatisch generiert..."))

        # New variables for intuitive builder
        self.current_char_type = tk.StringVar(value="")
        self.current_quantity_type = tk.StringVar(value="")
        self.custom_quantity_var = tk.StringVar(value="1")
        self.min_quantity_var = tk.StringVar(value="1")
        self.max_quantity_var = tk.StringVar(value="5")
        self.custom_text_var = tk.StringVar(value="")
        self.current_preview_var = tk.StringVar(value=self.translations.get("select_char_first", "Wählen Sie zuerst einen Zeichentyp aus..."))
        self.builder_description_var = tk.StringVar(value="")

        # Undo/Redo functionality
        self.pattern_history = []
        self.history_index = -1

        # Tooltips storage
        self.tooltips = {}

        self.create_widgets()
    
    def create_widgets(self):
        """
        Create all widgets for the regex builder tab
        """
        # Scale factors for DPI-aware sizing
        scaled_padding = int(10 * self.scale_factor)
        scaled_title_font = int(14 * self.scale_factor)
        scaled_normal_font = int(10 * self.scale_factor)
        scaled_bold_font = int(11 * self.scale_factor)

        # Main container - minimal padding for maximum space
        regex_main_frame = ttk.Frame(self.frame)
        regex_main_frame.pack(fill=tk.BOTH, expand=True, padx=2, pady=2)

    
        # Main notebook for different views
        self.notebook = ttk.Notebook(regex_main_frame)
        self.notebook.pack(fill=tk.BOTH, expand=True)

        # Tab 1: Builder
        builder_frame = ttk.Frame(self.notebook)
        self.notebook.add(builder_frame, text=self.translations.get("tab_builder", "🧱 Baustein-Builder"))

        # Tab 2: Tester
        self.tester_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.tester_frame, text=self.translations.get("tab_tester", "🧪 Tester"))

        # Tab 3: Examples
        examples_frame = ttk.Frame(self.notebook)
        self.notebook.add(examples_frame, text=self.translations.get("tab_examples", "📚 Beispiele"))

        # Builder tab content
        self.create_builder_tab(builder_frame)

        # Tester tab content
        self.create_tester_tab(self.tester_frame)

        # Examples tab content
        self.create_examples_tab(examples_frame)
    
    def create_builder_tab(self, builder_frame):
        """
        Create the intuitive step-by-step regex builder interface
        """
        builder_main = ttk.Frame(builder_frame)
        builder_main.pack(fill=tk.BOTH, expand=True, padx=2, pady=2)

        # No title or intro text - maximum space utilization

        # Step indicator (compact version)
        steps_frame = ttk.Frame(builder_main)
        steps_frame.pack(fill=tk.X, pady=(0, int(5 * self.scale_factor)))

        # Three-column layout for the steps
        steps_container = ttk.Frame(builder_main)
        steps_container.pack(fill=tk.BOTH, expand=True, pady=(0, int(10 * self.scale_factor)))

        # STEP 1: Character Type Selection (Left Column)
        step1_frame = ttk.LabelFrame(steps_container, text=self.translations.get("step_1", "📝 Schritt 1: Zeichen suchen"),
                                    padding=str(int(6 * self.scale_factor)))
        step1_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, int(3 * self.scale_factor)))

        char_types = [
            (self.translations.get("btn_letters", "🔤 Buchstaben"), "letters", "[a-zA-Z]", self.translations.get("desc_letters", "a-z, A-Z")),
            (self.translations.get("btn_digits", "🔢 Zahlen"), "digits", "\\d", self.translations.get("desc_digits", "0-9")),
            (self.translations.get("btn_alphanum", "🔤🔢 Alphanum."), "alphanum", "[a-zA-Z0-9]", self.translations.get("desc_alphanum", "Buchst.+Zahlen")),
            (self.translations.get("btn_any", "❓ Beliebig"), "any", ".", self.translations.get("desc_any", "Ein Zeichen")),
            (self.translations.get("btn_custom", "📝 Eigener Text"), "custom", "", self.translations.get("desc_custom", "Ihr Text")),
            (self.translations.get("btn_special", "⚙️ Spezial"), "special", "", self.translations.get("desc_special", "Satzzeichen"))
        ]

        self.char_buttons = []
        for name, value, pattern, desc in char_types:
            # Button frame
            btn_frame = ttk.Frame(step1_frame)
            btn_frame.pack(fill=tk.X, pady=int(1 * self.scale_factor))

            btn = ttk.Button(btn_frame, text=name,
                           command=lambda v=value, p=pattern: self.select_char_type(v, p))
            btn.pack(fill=tk.X, padx=int(1 * self.scale_factor), pady=(0, int(1 * self.scale_factor)))
            self.char_buttons.append(btn)

            # Description below button
            desc_label = ttk.Label(btn_frame, text=desc,
                                 font=('Helvetica', max(self.scaled_normal_font - 2, 12)),
                                 foreground="gray")
            desc_label.pack(anchor=tk.W, padx=int(3 * self.scale_factor))

        # Custom text input (shown when "Eigener Text" is selected)
        self.custom_text_frame = ttk.Frame(step1_frame)
        ttk.Label(self.custom_text_frame, text="Text:", font=('Helvetica', max(int((self.scaled_normal_font - 1) * self.scale_factor), 12))).pack(side=tk.LEFT, padx=int(2 * self.scale_factor))
        self.custom_entry = ttk.Entry(self.custom_text_frame, textvariable=self.custom_text_var, width=15,
                                    font=('Segoe UI', max(int(self.scaled_normal_font * self.scale_factor), 12)) if 'Segoe UI' in tkfont.families() else ('Helvetica', max(int(self.scaled_normal_font * self.scale_factor), 12)))
        self.custom_entry.pack(side=tk.LEFT, padx=int(2 * self.scale_factor), fill=tk.X, expand=True)
        # Initially hidden
        self.custom_text_frame.pack_forget()

        # STEP 2: Quantity Selection (Middle Column)
        step2_frame = ttk.LabelFrame(steps_container, text=self.translations.get("step_2", "🔢 Schritt 2: Wie oft?"),
                                    padding=str(int(6 * self.scale_factor)))
        step2_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, int(3 * self.scale_factor)))

        quantity_types = [
            (self.translations.get("btn_once", "🎯 1-mal"), "once", "", self.translations.get("desc_once", "Genau einmal")),
            (self.translations.get("btn_one_plus", "➕ 1+ mal"), "one_or_more", "+", self.translations.get("desc_one_plus", "Mindestens 1-mal")),
            (self.translations.get("btn_zero_one", "❓ 0-1 mal"), "zero_or_one", "?", self.translations.get("desc_zero_one", "Optional")),
            (self.translations.get("btn_zero_plus", "♾️ 0+ mal"), "zero_or_more", "*", self.translations.get("desc_zero_plus", "Beliebig oft")),
            (self.translations.get("btn_n_times", "📏 N-mal"), "exactly_n", "{n}", self.translations.get("desc_n_times", "Genau N-mal")),
            (self.translations.get("btn_m_n_times", "📊 M-N mal"), "between_m_n", "{m,n}", self.translations.get("desc_m_n_times", "M bis N-mal"))
        ]

        self.quantity_buttons = []
        for name, value, pattern, desc in quantity_types:
            # Button frame
            btn_frame = ttk.Frame(step2_frame)
            btn_frame.pack(fill=tk.X, pady=int(1 * self.scale_factor))

            btn = ttk.Button(btn_frame, text=name,
                           command=lambda v=value, p=pattern: self.select_quantity_type(v, p))
            btn.pack(fill=tk.X, padx=int(1 * self.scale_factor), pady=(0, int(1 * self.scale_factor)))
            self.quantity_buttons.append(btn)

            # Description below button
            desc_label = ttk.Label(btn_frame, text=desc,
                                 font=('Helvetica', max(self.scaled_normal_font - 2, 12)),
                                 foreground="gray")
            desc_label.pack(anchor=tk.W, padx=int(3 * self.scale_factor))

        # Custom quantity inputs
        self.exactly_frame = ttk.Frame(step2_frame)
        ttk.Label(self.exactly_frame, text="N:", font=('Helvetica', max(int((self.scaled_normal_font - 1) * self.scale_factor), 12))).pack(side=tk.LEFT, padx=int(2 * self.scale_factor))
        ttk.Spinbox(self.exactly_frame, from_=1, to=99, textvariable=self.custom_quantity_var, width=3,
                    font=('Segoe UI', max(int(self.scaled_normal_font * self.scale_factor), 12)) if 'Segoe UI' in tkfont.families() else ('Helvetica', max(int(self.scaled_normal_font * self.scale_factor), 12))).pack(side=tk.LEFT)
        self.exactly_frame.pack_forget()

        self.between_frame = ttk.Frame(step2_frame)
        ttk.Label(self.between_frame, text="M:", font=('Helvetica', max(int((self.scaled_normal_font - 1) * self.scale_factor), 12))).pack(side=tk.LEFT, padx=int(2 * self.scale_factor))
        ttk.Spinbox(self.between_frame, from_=0, to=99, textvariable=self.min_quantity_var, width=3,
                    font=('Segoe UI', max(int(self.scaled_normal_font * self.scale_factor), 12)) if 'Segoe UI' in tkfont.families() else ('Helvetica', max(int(self.scaled_normal_font * self.scale_factor), 12))).pack(side=tk.LEFT)
        ttk.Label(self.between_frame, text="N:", font=('Helvetica', max(int((self.scaled_normal_font - 1) * self.scale_factor), 12))).pack(side=tk.LEFT, padx=int(2 * self.scale_factor))
        ttk.Spinbox(self.between_frame, from_=1, to=99, textvariable=self.max_quantity_var, width=3,
                    font=('Segoe UI', max(int(self.scaled_normal_font * self.scale_factor), 12)) if 'Segoe UI' in tkfont.families() else ('Helvetica', max(int(self.scaled_normal_font * self.scale_factor), 12))).pack(side=tk.LEFT)
        self.between_frame.pack_forget()

        # STEP 3: Modifiers and Anchors (Right Column)
        step3_frame = ttk.LabelFrame(steps_container, text=self.translations.get("step_3", "⚙️ Schritt 3: Optionen"),
                                    padding=str(int(6 * self.scale_factor)))
        step3_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        # Compact button layout with descriptions
        btn_frame = ttk.Frame(step3_frame)
        btn_frame.pack(fill=tk.BOTH, expand=True)

        # Row 1: Anchors with descriptions
        anchor_row = ttk.Frame(btn_frame)
        anchor_row.pack(fill=tk.X, pady=int(1 * self.scale_factor))

        # ^ Anfang
        anchor_start_frame = ttk.Frame(anchor_row)
        anchor_start_frame.pack(side=tk.LEFT, padx=int(1 * self.scale_factor), expand=True, fill=tk.X)
        ttk.Button(anchor_start_frame, text=self.translations.get("btn_start", "^ Anfang"), command=lambda: self.add_modifier("^")).pack(fill=tk.X)
        ttk.Label(anchor_start_frame, text=self.translations.get("desc_start", "Zeilenanfang"), font=('Helvetica', max(self.scaled_normal_font - 2, 12)), foreground="gray").pack(anchor=tk.W)

        # $ Ende
        anchor_end_frame = ttk.Frame(anchor_row)
        anchor_end_frame.pack(side=tk.LEFT, padx=int(1 * self.scale_factor), expand=True, fill=tk.X)
        ttk.Button(anchor_end_frame, text=self.translations.get("btn_end", "$ Ende"), command=lambda: self.add_modifier("$")).pack(fill=tk.X)
        ttk.Label(anchor_end_frame, text=self.translations.get("desc_end", "Zeilenende"), font=('Helvetica', max(self.scaled_normal_font - 2, 12)), foreground="gray").pack(anchor=tk.W)

        # \b Wort
        word_boundary_frame = ttk.Frame(anchor_row)
        word_boundary_frame.pack(side=tk.LEFT, padx=int(1 * self.scale_factor), expand=True, fill=tk.X)
        ttk.Button(word_boundary_frame, text=self.translations.get("btn_word", "\\b Wort"), command=lambda: self.add_modifier("\\b")).pack(fill=tk.X)
        ttk.Label(word_boundary_frame, text=self.translations.get("desc_word", "Wortgrenze"), font=('Helvetica', max(self.scaled_normal_font - 2, 12)), foreground="gray").pack(anchor=tk.W)

        # Row 2: Groups with descriptions
        group_row = ttk.Frame(btn_frame)
        group_row.pack(fill=tk.X, pady=int(1 * self.scale_factor))

        # ( ) Gruppe
        group_frame = ttk.Frame(group_row)
        group_frame.pack(side=tk.LEFT, padx=int(1 * self.scale_factor), expand=True, fill=tk.X)
        ttk.Button(group_frame, text=self.translations.get("btn_group", "( ) Gruppe"), command=lambda: self.add_modifier("()")).pack(fill=tk.X)
        ttk.Label(group_frame, text=self.translations.get("desc_group", "Gruppierung"), font=('Helvetica', max(self.scaled_normal_font - 2, 12)), foreground="gray").pack(anchor=tk.W)

        # | ODER
        or_frame = ttk.Frame(group_row)
        or_frame.pack(side=tk.LEFT, padx=int(1 * self.scale_factor), expand=True, fill=tk.X)
        ttk.Button(or_frame, text=self.translations.get("btn_or", "| ODER"), command=lambda: self.add_modifier("|")).pack(fill=tk.X)
        ttk.Label(or_frame, text=self.translations.get("desc_or", "Alternative"), font=('Helvetica', max(self.scaled_normal_font - 2, 12)), foreground="gray").pack(anchor=tk.W)

        # (?: ) Alt.
        non_capture_frame = ttk.Frame(group_row)
        non_capture_frame.pack(side=tk.LEFT, padx=int(1 * self.scale_factor), expand=True, fill=tk.X)
        ttk.Button(non_capture_frame, text=self.translations.get("btn_alt", "(?: ) Alt."), command=lambda: self.add_modifier("(?:)")).pack(fill=tk.X)
        ttk.Label(non_capture_frame, text=self.translations.get("desc_alt", "Gruppe o. Speicher"), font=('Helvetica', max(self.scaled_normal_font - 2, 12)), foreground="gray").pack(anchor=tk.W)

        # Combined compact preview and pattern section
        combined_frame = ttk.Frame(builder_main)
        combined_frame.pack(fill=tk.BOTH, expand=True, pady=(0, int(5 * self.scale_factor)))

        # Left side: Live Preview (ultra-compact)
        preview_frame = ttk.LabelFrame(combined_frame, text=self.translations.get("preview", "👀 Vorschau"),
                                      padding=str(int(4 * self.scale_factor)))
        preview_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, int(3 * self.scale_factor)))

        ttk.Label(preview_frame, text=self.translations.get("selection", "Auswahl:"), font=('Helvetica', max(self.scaled_normal_font, 12))).pack(anchor=tk.W)
        preview_display = ttk.Label(preview_frame, textvariable=self.current_preview_var,
                                   font=('Courier', max(self.scaled_bold_font - 1, 12)),
                                   background="#f0f0f0", relief="sunken", padding=int(2 * self.scale_factor))
        preview_display.pack(fill=tk.X, pady=int(2 * self.scale_factor))

        ttk.Label(preview_frame, textvariable=self.builder_description_var,
                 wraplength=int(300 * self.scale_factor), justify=tk.LEFT,
                 foreground="blue", font=('Helvetica', max(self.scaled_normal_font - 1, 12))).pack(fill=tk.X)

        # Action buttons (side by side)
        button_frame = ttk.Frame(preview_frame)
        button_frame.pack(fill=tk.X, pady=int(2 * self.scale_factor))

        ttk.Button(button_frame, text=self.translations.get("btn_add", "➕ Hinzufügen"),
                  command=self.add_to_pattern).pack(side=tk.LEFT, padx=(0, int(2 * self.scale_factor)), expand=True, fill=tk.X)
        ttk.Button(button_frame, text=self.translations.get("btn_reset", "🔄 Zurücksetzen"),
                  command=self.reset_builder_selection).pack(side=tk.LEFT, expand=True, fill=tk.X)

        # Right side: Final regex pattern (ultra-compact)
        pattern_frame = ttk.LabelFrame(combined_frame, text=self.translations.get("regex_result", "🎯 Regex-Muster"),
                                      padding=str(int(4 * self.scale_factor)))
        pattern_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        self.regex_entry = ttk.Entry(pattern_frame, textvariable=self.regex_pattern_var,
                                   font=('Courier', max(self.scaled_bold_font - 1, 12)))
        self.regex_entry.pack(fill=tk.X, pady=int(2 * self.scale_factor))

        ttk.Label(pattern_frame, textvariable=self.pattern_description_var,
                 wraplength=int(300 * self.scale_factor), justify=tk.LEFT,
                 foreground="gray", font=('Helvetica', max(self.scaled_normal_font - 1, 12))).pack(fill=tk.X)

        # Bottom action buttons (shared)
        final_action_frame = ttk.Frame(builder_main)
        final_action_frame.pack(fill=tk.X, pady=int(5 * self.scale_factor))

        ttk.Button(final_action_frame, text=self.translations.get("btn_manage", "📝 Muster verwalten"), command=self.manage_presets).pack(side=tk.LEFT, padx=int(5 * self.scale_factor))
        ttk.Button(final_action_frame, text=self.translations.get("btn_save_preset", "💾 Als Muster speichern"), command=self.save_as_preset).pack(side=tk.LEFT, padx=int(5 * self.scale_factor))
        ttk.Button(final_action_frame, text=self.translations.get("btn_copy", "📋 Kopieren"), command=self.copy_regex_to_clipboard).pack(side=tk.LEFT, padx=int(5 * self.scale_factor))
        ttk.Button(final_action_frame, text=self.translations.get("btn_reset_pattern", "🔄 Muster zurücksetzen"), command=self.reset_pattern).pack(side=tk.LEFT, padx=int(5 * self.scale_factor))
        ttk.Button(final_action_frame, text=self.translations.get("btn_undo", "↶ Rückgängig"), command=self.undo_pattern).pack(side=tk.LEFT, padx=int(5 * self.scale_factor))
        ttk.Button(final_action_frame, text=self.translations.get("btn_redo", "↷ Wiederholen"), command=self.redo_pattern).pack(side=tk.LEFT, padx=int(5 * self.scale_factor))
        ttk.Button(final_action_frame, text=self.translations.get("btn_apply", "💾 In Hauptfenster übernehmen"), command=self.apply_regex_to_main).pack(side=tk.LEFT, padx=int(5 * self.scale_factor))
        ttk.Button(final_action_frame, text=self.translations.get("btn_test", "🧪 Testen"), command=lambda: self.notebook.select(self.tester_frame)).pack(side=tk.RIGHT, padx=int(5 * self.scale_factor))

        # Bind pattern changes to description update
        self.regex_pattern_var.trace_add("write", lambda *args: self.update_pattern_description())

        # Bind custom text changes to preview update
        self.custom_text_var.trace_add("write", lambda *args: self.update_preview())
        self.custom_quantity_var.trace_add("write", lambda *args: self.update_preview())
        self.min_quantity_var.trace_add("write", lambda *args: self.update_preview())
        self.max_quantity_var.trace_add("write", lambda *args: self.update_preview())

        # Initialize the builder
        self.reset_builder_selection()
    
    def create_tester_tab(self, tester_frame):
        
        tester_main = ttk.Frame(tester_frame)
        tester_main.pack(fill=tk.BOTH, expand=True, padx=self.scaled_padding, pady=self.scaled_padding)

        # Test-Text Eingabe
        test_label = ttk.Label(tester_main, text=self.translations.get("test_input", "Testtext eingeben:"),
                              font=('Helvetica', max(self.scaled_bold_font, 12), 'bold'))
        test_label.pack(anchor=tk.W, pady=(0, int(5 * self.scale_factor)))

        test_frame = ttk.LabelFrame(tester_main, text=self.translations.get("test_text_frame", "📝 Testtext"), padding=str(int(5 * self.scale_factor)))
        test_frame.pack(fill=tk.X, pady=(0, int(10 * self.scale_factor)))

        test_entry = ttk.Entry(test_frame, textvariable=self.test_text_var,
                             font=('Segoe UI', max(self.scaled_normal_font, 12)) if 'Segoe UI' in tkfont.families() else ('Helvetica', max(self.scaled_normal_font, 12)))
        test_entry.pack(fill=tk.X, pady=int(5 * self.scale_factor))

        # Regex-Muster Eingabe
        regex_label = ttk.Label(tester_main, text=self.translations.get("regex_pattern", "Regex-Muster:"),
                              font=('Segoe UI', max(self.scaled_bold_font, 12), 'bold') if 'Segoe UI' in tkfont.families() else ('Helvetica', max(self.scaled_bold_font, 12), 'bold'))
        regex_label.pack(anchor=tk.W, pady=(int(10 * self.scale_factor), int(5 * self.scale_factor)))

        regex_frame = ttk.LabelFrame(tester_main, text=self.translations.get("test_pattern_frame", "🔍 Regex-Muster"), padding=str(int(5 * self.scale_factor)))
        regex_frame.pack(fill=tk.X, pady=(0, int(10 * self.scale_factor)))

        regex_test_entry = ttk.Entry(regex_frame, textvariable=self.regex_pattern_var,
                                   font=('Courier', max(self.scaled_bold_font, 12)) if 'Courier' in tkfont.families() else ('Helvetica', max(self.scaled_bold_font, 12)))
        regex_test_entry.pack(fill=tk.X, pady=int(5 * self.scale_factor))

        # Test-Buttons
        test_button_frame = ttk.Frame(tester_main)
        test_button_frame.pack(fill=tk.X, pady=(int(10 * self.scale_factor), 0))

        ttk.Button(test_button_frame, text=self.translations.get("btn_test", "🔍 Testen"), command=self.test_regex_pattern).pack(side=tk.LEFT, padx=int(5 * self.scale_factor))
        ttk.Button(test_button_frame, text=self.translations.get("btn_load_example", "📋 Beispiel laden"), command=self.load_test_example).pack(side=tk.LEFT, padx=int(5 * self.scale_factor))
        ttk.Button(test_button_frame, text=self.translations.get("btn_reset", "🔄 Zurücksetzen"), command=self.reset_test_fields).pack(side=tk.LEFT, padx=int(5 * self.scale_factor))

        # Testergebnis
        result_label = ttk.Label(tester_main, text=self.translations.get("result_label", "Ergebnis:"),
                                font=('Helvetica', max(self.scaled_bold_font, 12), 'bold'))
        result_label.pack(anchor=tk.W, pady=(int(15 * self.scale_factor), int(5 * self.scale_factor)))

        result_display = ttk.Label(tester_main, textvariable=self.test_result_var,
                                 wraplength=int(800 * self.scale_factor), justify=tk.LEFT,
                                 relief="sunken", padding=int(5 * self.scale_factor))
        result_display.pack(fill=tk.X, pady=(0, int(10 * self.scale_factor)))

        # Treffer-Anzeige
        matches_label = ttk.Label(tester_main, text=self.translations.get("matches_label", "Gefundene Treffer:"),
                                font=('Helvetica', max(self.scaled_bold_font, 12), 'bold'))
        matches_label.pack(anchor=tk.W, pady=(int(10 * self.scale_factor), int(5 * self.scale_factor)))

        matches_display = ttk.Label(tester_main, textvariable=self.test_matches_var,
                                  wraplength=int(800 * self.scale_factor), justify=tk.LEFT,
                                  foreground="green", relief="sunken", padding=int(5 * self.scale_factor))
        matches_display.pack(fill=tk.X, pady=(0, int(10 * self.scale_factor)))
    
    def create_examples_tab(self, examples_frame):
     
        examples_main = ttk.Frame(examples_frame)
        examples_main.pack(fill=tk.BOTH, expand=True, padx=self.scaled_padding, pady=self.scaled_padding)

        # Beispiele-Kategorien
        examples_label = ttk.Label(examples_main, text=self.translations.get("common_examples", "📚 Häufig verwendete Regex-Beispiele"),
                                  font=('Helvetica', max(int(12 * self.scale_factor), 12), 'bold'))
        examples_label.pack(anchor=tk.W, pady=(0, int(10 * self.scale_factor)))

        # Scrollbar für Beispiele
        examples_scrollbar = ttk.Scrollbar(examples_main)
        examples_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        examples_text = tk.Text(examples_main, wrap=tk.WORD, bg="white",
                              font=('Segoe UI', max(self.scaled_normal_font, 12)) if 'Segoe UI' in tkfont.families() else ('Helvetica', max(self.scaled_normal_font, 12)),
                              borderwidth=1, relief="solid", padx=int(10 * self.scale_factor), pady=int(10 * self.scale_factor),
                              selectbackground=self.win11_colors.get('primary', '#0078d4'),
                              selectforeground='white',
                              yscrollcommand=examples_scrollbar.set)
        examples_text.pack(fill=tk.BOTH, expand=True, padx=int(2 * self.scale_factor), pady=int(2 * self.scale_factor))
        examples_scrollbar.config(command=examples_text.yview)

        # Beispiele einfügen - Keeping this untranslated for now as it's complex content
        examples_content = """
        HÄUFIGE REGEX-BEISPIELE
        ==========================

        1. E-MAIL-ADRESSEN
        -------------------------------
        Muster: [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}
        Beispiele:
        • user@example.com ✅
        • test.email+tag@domain.co.uk ✅
        • invalid-email@ ❌ (fehlende Domain)
        • user@.com ❌ (ungültige Domain)

        2. DEUTSCHE TELEFONNUMMERN
        --------------------------
        Muster: \\+49\\s?[0-9\\s]{8,14}|[0-9\\s]{8,14}
        Beispiele:
        • +49 123 456789 ✅ (internationale Schreibweise)
        • 0123 456789 ✅ (deutsche Schreibweise)
        • 0151 23456789 ✅ (Handynummer)
        • 123 ❌ (zu kurz)

        3. DATUMSFORMATE (ISO 8601)
        ---------------------------
        YYYY-MM-DD: \\b\\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\\d|3[01])\\b
        Beispiele:
        • 2024-12-31 ✅
        • 2024-02-29 ✅ (Schaltjahr)
        • 2024-13-01 ❌ (ungültiger Monat)
        • 2024-02-32 ❌ (ungültiger Tag)

        Deutsche Schreibweise DD.MM.YYYY: \\b(?:0[1-9]|[12]\\d|3[01])\\.(?:0[1-9]|1[0-2])\\.\\d{4}\\b
        • 31.12.2024 ✅
        • 01.01.2024 ✅
        • 32.12.2024 ❌ (ungültiger Tag)

        4. ZEITFORMATE (24h)
        -------------------
        HH:MM:SS: \\b(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\b
        Beispiele:
        • 14:30:45 ✅
        • 09:15:30 ✅
        • 25:00:00 ❌ (ungültige Stunde)

        HH:MM: \\b(?:[01]\\d|2[0-3]):[0-5]\\d\\b
        • 14:30 ✅
        • 09:15 ✅
        • 25:00 ❌ (ungültige Stunde)

        5. PREISE UND BETRÄGE
        ----------------------
        €-Format (deutsch): \\b\\d{1,3}(?:\\.\\d{3})*,\\d{2}\\s?€\\b
        Beispiele:
        • 1.234,56 € ✅
        • 123,45 € ✅
        • 1.234.567,89 € ✅
        • 123,456 € ❌ (zu viele Dezimalstellen)

        $-Format (englisch): \\b\\$\\d{1,3}(?:,\\d{3})*(?:\\.\\d{2})?\\b
        • $1,234.56 ✅
        • $123.45 ✅
        • $1,234,567.89 ✅

        6. SEMANTISCHE VERSIONIERUNG
        ----------------------------
        Standard: \\b\\d+\\.\\d+\\.\\d+(?:-[a-zA-Z0-9.-]+)?(?:\\+[a-zA-Z0-9.-]+)?\\b
        Beispiele:
        • 1.2.3 ✅
        • 2.0.0-alpha.1 ✅
        • 1.0.0+build.123 ✅
        • 1.2 ❌ (fehlende Patch-Version)

        7. IP-ADRESSEN (IPv4)
        -------------------
        Streng: \\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b
        Beispiele:
        • 192.168.1.1 ✅
        • 10.0.0.1 ✅
        • 172.16.0.1 ✅
        • 999.999.999.999 ❌ (Werte zu hoch)

        Einfach (für meisten Fälle): \\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b
        • 192.168.1.1 ✅
        • 999.999.999.999 ⚠️ (technisch ungültig, aber matched)

        8. URLs (HTTP/HTTPS)
        ------------------
        Vollständig: \\bhttps?://(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)*[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?::\\d{1,5})?(?:/[^\\s]*)?\\b
        Beispiele:
        • https://www.example.com ✅
        • http://sub.domain.co.uk:8080/path?query=value ✅
        • ftp://example.com ❌ (nur HTTP/HTTPS)

        Einfach: \\bhttps?://[^\\s/$.?#][^\\s]*\\b
        • https://example.com ✅
        • https://sub.example.com/path ✅

        9. HASHTAGS
        -----------
        Twitter: \\B#\\w+[a-zA-Z0-9_]*\\b
        Beispiele:
        • #Regex ✅
        • #Python3 ✅
        • #Windkraft ✅
        • #123 ❌ (muss mit Buchstabe beginnen)
        • #hashtag-with-dash ✅

        10. SOZIALE MEDIEN HANDLES
        -------------------------
        Twitter: \\B@\\w{1,15}\\b
        Beispiele:
        • @username ✅
        • @user_name ✅
        • @user-name ❌ (Bindestriche nicht erlaubt)
        • @verylongusername ❌ (zu lang)

        Instagram: \\B@\\w{1,30}\\b (ähnlich wie Twitter)

         REGEX-TIPPS
        ==============================

        1. Verwende Anker für Präzision
        - ❌ \\d{4} (findet auch 12345)
        - ✅ \\b\\d{4}\\b (nur 4-stellige Zahlen als ganzes Wort)

        2. Verwende Negative Lookbehinds für Ausschlüsse
        - ❌ password.*admin (findet auch "password123admin")
        - ✅ password(?!.*admin) (schließt "admin" aus)

        3. Verwende Named Groups für bessere Lesbarkeit
        - ❌ (\\d{4})-(\\d{2})-(\\d{2})
        - ✅ (?P<year>\\d{4})-(?P<month>\\d{2})-(?P<day>\\d{2})

        4. Setze Quantoren sparsam ein
        - ❌ .* (zu gierig, kann Performance-Probleme verursachen)
        - ✅ [^\\n]* (spezifischer und effizienter)

        5. Validierung vs. Extraktion
        - Für Validierung: Verwende ^ und $ für vollständige Übereinstimmung
        - Für Extraktion: Verwende \\b für Wortgrenzen

        6. Beachte Zeichenkodierung
        - Verwende \\w mit Vorsicht (bedeutet [a-zA-Z0-9_] in ASCII)
        - Für Unicode: Verwende \\p{L} (falls unterstützt) oder [\\wäöüÄÖÜß]

        7. Performance-Optimierung
        - Vermeide verschachtelte Quantoren wie (a+)+
        - Verwende nicht-capturing Groups (?:) wenn möglich
        - Teste mit repräsentativen Datenmengen
        """

        examples_text.insert(tk.END, examples_content)
        examples_text.config(state=tk.DISABLED)
    
    def add_regex_component(self, component):
        """
        Add a regex component to the current pattern with undo support

        Args:
            component: Regex component to add
        """
        current_pattern = self.regex_pattern_var.get()
        self.save_to_history(current_pattern)
        self.regex_pattern_var.set(current_pattern + component)

    def apply_regex_to_main(self):
        """Apply the regex pattern to the main configuration"""
        pattern = self.regex_pattern_var.get()
        if pattern:
            # Check if apply_to_main callback is set (from main GUI)
            if hasattr(self, 'apply_to_main') and self.apply_to_main:
                # Use the callback provided by main GUI
                self.apply_to_main()
                messagebox.showinfo(self.translations.get("success", "Erfolg"), self.translations.get("msg_pattern_applied", "Regex-Muster wurde in das Hauptfenster übernommen!"))
            elif self.main_gui:
                # Fallback: Apply to main GUI pattern field directly
                self.main_gui.pattern_var.set(pattern)
                messagebox.showinfo(self.translations.get("success", "Erfolg"), self.translations.get("msg_pattern_applied", "Regex-Muster wurde in das Hauptfenster übernommen!"))
            else:
                messagebox.showwarning(self.translations.get("error", "Fehler"), self.translations.get("msg_main_not_avail", "Hauptfenster-Referenz nicht verfügbar. Kopieren Sie das Muster manuell."))
        else:
            messagebox.showwarning(self.translations.get("error", "Fehler"), self.translations.get("msg_no_pattern_apply", "Kein Regex-Muster zum Übernehmen verfügbar"))

    def copy_regex_to_clipboard(self):
        """Copy the current regex pattern to clipboard"""
        pattern = self.regex_pattern_var.get()
        if pattern:
            self.frame.clipboard_clear()
            self.frame.clipboard_append(pattern)
            self.frame.update()
            messagebox.showinfo(self.translations.get("success", "Erfolg"), self.translations.get("msg_copied", "Regex-Muster wurde in die Zwischenablage kopiert!"))
        else:
            messagebox.showwarning(self.translations.get("error", "Fehler"), self.translations.get("msg_no_pattern_copy", "Kein Regex-Muster zum Kopieren verfügbar"))

    def reset_pattern(self):
        """Reset the regex pattern and clear results"""
        self.save_to_history(self.regex_pattern_var.get())
        self.regex_pattern_var.set("")
        self.test_result_var.set(self.translations.get("default_result", "Hier erscheint das Testergebnis..."))
        self.test_matches_var.set(self.translations.get("no_matches", "Keine Treffer"))
        self.pattern_description_var.set(self.translations.get("auto_desc", "Beschreibung wird automatisch generiert..."))

    def undo_pattern(self):
        """Undo the last pattern change"""
        if self.history_index > 0:
            self.history_index -= 1
            self.regex_pattern_var.set(self.pattern_history[self.history_index])
        elif self.history_index == 0:
            self.regex_pattern_var.set("")
        else:
            messagebox.showinfo(self.translations.get("success", "Info"), self.translations.get("msg_no_undo", "Keine weiteren Rückgängig-Aktionen verfügbar"))

    def redo_pattern(self):
        """Redo the last undone pattern change"""
        if self.history_index < len(self.pattern_history) - 1:
            self.history_index += 1
            self.regex_pattern_var.set(self.pattern_history[self.history_index])
        else:
            messagebox.showinfo(self.translations.get("success", "Info"), self.translations.get("msg_no_redo", "Keine Wiederholen-Aktionen verfügbar"))

    def save_to_history(self, pattern):
        """Save current pattern to history for undo/redo"""
        # Remove any history after current index
        self.pattern_history = self.pattern_history[:self.history_index + 1]
        # Add new pattern
        self.pattern_history.append(pattern)
        self.history_index = len(self.pattern_history) - 1
        # Limit history to 50 entries
        if len(self.pattern_history) > 50:
            self.pattern_history.pop(0)
            self.history_index -= 1

    def test_regex_pattern(self):
        """Test the current regex pattern with enhanced feedback"""
        pattern = self.regex_pattern_var.get()
        test_text = self.test_text_var.get()

        if not pattern:
            self.test_result_var.set(self.translations.get("msg_enter_pattern", "❌ Bitte geben Sie ein Regex-Muster ein"))
            self.test_matches_var.set(self.translations.get("no_matches", "Keine Treffer"))
            return

        if not test_text:
            self.test_result_var.set(self.translations.get("msg_enter_text", "❌ Bitte geben Sie einen Testtext ein"))
            self.test_matches_var.set(self.translations.get("no_matches", "Keine Treffer"))
            return

        try:
            # Compile regex for better error handling
            regex = re.compile(pattern)
            matches = regex.findall(test_text)

            if matches:
                unique_matches = list(set(matches))  # Remove duplicates for display
                msg = self.translations.get("msg_pattern_found", "✅ Muster gefunden! {} Treffer (davon {} einzigartig)").format(len(matches), len(unique_matches))
                self.test_result_var.set(msg)
                match_display = ", ".join([f"'{match}'" for match in unique_matches[:10]])  # Limit display
                if len(unique_matches) > 10:
                    match_display += f" ... {self.translations.get('more_columns', '(+{} weitere)').format(count=len(unique_matches) - 10) if hasattr(self.translations, 'get') else f'(+{len(unique_matches) - 10} weitere)'}"
                self.test_matches_var.set(match_display)
            else:
                self.test_result_var.set(self.translations.get("msg_no_matches", "❌ Keine Treffer gefunden"))
                self.test_matches_var.set(self.translations.get("no_matches", "Keine Treffer"))

        except re.error as e:
            self.test_result_var.set(self.translations.get("msg_invalid_regex", "❌ Ungültiges Regex-Muster: {}").format(e))
            self.test_matches_var.set(self.translations.get("no_matches", "Keine Treffer"))

    def load_test_example(self):
        example = "Fehler in Zeile 42: error_code=123, warning_level=high, status=critical. E-Mail: user@example.com, Telefon: +49 123 456789, Datum: 2024-12-31, IP: 192.168.1.1"
        self.test_text_var.set(example)
        self.test_result_var.set(self.translations.get("msg_example_loaded", "Beispiel geladen - klicken Sie auf 'Testen'"))
        self.test_matches_var.set(self.translations.get("no_matches", "Keine Treffer"))

    def reset_test_fields(self):
        """Reset all test fields"""
        self.test_text_var.set(self.translations.get("default_test_text", "Beispieltext mit error und warning 123 Zahlen und E-Mail: test@example.com"))
        self.regex_pattern_var.set("")
        self.test_result_var.set(self.translations.get("default_result", "Hier erscheint das Testergebnis..."))
        self.test_matches_var.set(self.translations.get("no_matches", "Keine Treffer"))





    def update_pattern_description(self):
        """Update the pattern description based on current regex"""
        pattern = self.regex_pattern_var.get()
        if not pattern:
            self.pattern_description_var.set(self.translations.get("auto_desc", "Beschreibung wird automatisch generiert..."))
            return

        try:
            # Simple pattern analysis
            descriptions = []

            if '^' in pattern and '$' in pattern:
                descriptions.append("Ganze Zeile muss passen")
            elif '^' in pattern:
                descriptions.append("Beginnt am Zeilenanfang")
            elif '$' in pattern:
                descriptions.append("Endet am Zeilenende")

            if '\\b' in pattern:
                descriptions.append("Verwendet Wortgrenzen")

            if '|' in pattern:
                descriptions.append("Enthält Alternativen (ODER)")

            if '\\d' in pattern:
                descriptions.append("Sucht nach Zahlen")

            if '[a-zA-Z]' in pattern or '[A-Za-z]' in pattern:
                descriptions.append("Sucht nach Buchstaben")

            if '@' in pattern:
                descriptions.append("Könnte E-Mail-Adressen finden")

            if not descriptions:
                descriptions.append("Benutzerdefiniertes Muster")

            self.pattern_description_var.set(" • ".join(descriptions))

        except:
            self.pattern_description_var.set("Muster-Analyse nicht möglich")

    def select_char_type(self, char_type, base_pattern):
        """
        Handle character type selection and show/hide relevant inputs

        Args:
            char_type: Type of character selected
            base_pattern: Base regex pattern for this character type
        """
        self.current_char_type.set(char_type)

        # Hide custom text frame by default
        self.custom_text_frame.pack_forget()

        # Show custom text input for custom type
        if char_type == "custom":
            self.custom_text_frame.pack(fill=tk.X, pady=int(5 * self.scale_factor))
            base_pattern = ""  # Will be filled by user input

        # Show special characters selection
        elif char_type == "special":
            # For now, just show common special chars
            base_pattern = "[\\s\\.,\\-\\_]"

        # Update preview
        self.update_preview()

    def select_quantity_type(self, quantity_type, pattern_modifier):
        """
        Handle quantity type selection and show/hide custom inputs

        Args:
            quantity_type: Type of quantity selected
            pattern_modifier: Regex modifier for quantity
        """
        self.current_quantity_type.set(quantity_type)

        # Hide custom input frames
        self.exactly_frame.pack_forget()
        self.between_frame.pack_forget()

        # Show relevant custom inputs
        if quantity_type == "exactly_n":
            self.exactly_frame.pack(fill=tk.X, pady=int(5 * self.scale_factor))
        elif quantity_type == "between_m_n":
            self.between_frame.pack(fill=tk.X, pady=int(5 * self.scale_factor))

        # Update preview
        self.update_preview()

    def add_modifier(self, modifier):
        """
        Add a modifier (anchor, group, etc.) to the current selection

        Args:
            modifier: Modifier to add
        """
        current_preview = self.current_preview_var.get()
        if current_preview == self.translations.get("select_char_first", "Wählen Sie zuerst einen Zeichentyp aus..."):
            # If no selection yet, just set the modifier
            self.current_preview_var.set(modifier)
        else:
            # Add modifier to existing selection
            if modifier in ["^", "$"]:
                # Anchors go at start/end
                if modifier == "^":
                    self.current_preview_var.set(modifier + current_preview)
                else:
                    self.current_preview_var.set(current_preview + modifier)
            elif modifier == "\\b":
                # Word boundaries wrap the content
                self.current_preview_var.set(modifier + current_preview + modifier)
            else:
                # Other modifiers (groups, etc.)
                if modifier == "()":
                    self.current_preview_var.set("(" + current_preview + ")")
                elif modifier == "|":
                    self.current_preview_var.set(current_preview + "|")
                elif modifier == "(?:)":
                    self.current_preview_var.set("(?:)" + current_preview)

        self.update_preview_description()

    def update_preview(self):
        """
        Update the live preview based on current selections
        """
        char_type = self.current_char_type.get()
        quantity_type = self.current_quantity_type.get()

        if not char_type:
            self.current_preview_var.set(self.translations.get("select_char_first", "Wählen Sie zuerst einen Zeichentyp aus..."))
            self.builder_description_var.set("")
            return

        # Get base pattern
        base_pattern = ""
        if char_type == "letters":
            base_pattern = "[a-zA-Z]"
        elif char_type == "digits":
            base_pattern = "\\d"
        elif char_type == "alphanum":
            base_pattern = "[a-zA-Z0-9]"
        elif char_type == "any":
            base_pattern = "."
        elif char_type == "custom":
            custom_text = self.custom_text_var.get()
            if custom_text:
                # Escape special regex characters
                base_pattern = re.escape(custom_text)
            else:
                base_pattern = "[Ihr-Text]"
        elif char_type == "special":
            base_pattern = "[\\s\\.,\\-\\_]"

        # Apply quantity
        if quantity_type:
            if quantity_type == "once":
                # No modifier needed
                pass
            elif quantity_type == "one_or_more":
                base_pattern += "+"
            elif quantity_type == "zero_or_one":
                base_pattern += "?"
            elif quantity_type == "zero_or_more":
                base_pattern += "*"
            elif quantity_type == "exactly_n":
                n = self.custom_quantity_var.get()
                if n.isdigit() and int(n) > 0:
                    base_pattern += f"{{{n}}}"
                else:
                    base_pattern += "{N}"
            elif quantity_type == "between_m_n":
                min_val = self.min_quantity_var.get()
                max_val = self.max_quantity_var.get()
                if min_val.isdigit() and max_val.isdigit():
                    min_int = int(min_val)
                    max_int = int(max_val)
                    if min_int <= max_int:
                        base_pattern += f"{{{min_int},{max_int}}}"
                    else:
                        base_pattern += "{Min-Max}"
                else:
                    base_pattern += "{Min-Max}"

        self.current_preview_var.set(base_pattern)
        self.update_preview_description()

    def update_preview_description(self):
        """
        Update the description of the current preview
        """
        char_type = self.current_char_type.get()
        quantity_type = self.current_quantity_type.get()
        preview = self.current_preview_var.get()

        if not char_type or preview == self.translations.get("select_char_first", "Wählen Sie zuerst einen Zeichentyp aus..."):
            self.builder_description_var.set("")
            return

        descriptions = []

        # Character type description
        if char_type == "letters":
            descriptions.append(self.translations.get("builder_desc_letters", "Buchstaben (a-z, A-Z)"))
        elif char_type == "digits":
            descriptions.append(self.translations.get("builder_desc_digits", "Zahlen (0-9)"))
        elif char_type == "alphanum":
            descriptions.append(self.translations.get("builder_desc_alphanum", "Buchstaben und Zahlen"))
        elif char_type == "any":
            descriptions.append(self.translations.get("builder_desc_any", "Ein beliebiges Zeichen"))
        elif char_type == "custom":
            custom_text = self.custom_text_var.get()
            if custom_text:
                descriptions.append(self.translations.get("builder_desc_custom", "Der Text: '{}'").format(custom_text))
            else:
                descriptions.append(self.translations.get("builder_desc_custom_generic", "Ihr eigener Suchtext"))
        elif char_type == "special":
            descriptions.append(self.translations.get("builder_desc_special", "Sonderzeichen (Leerzeichen, Punkt, Komma, etc.)"))

        # Quantity description
        if quantity_type:
            if quantity_type == "once":
                descriptions.append(self.translations.get("builder_desc_once", "erscheint genau einmal"))
            elif quantity_type == "one_or_more":
                descriptions.append(self.translations.get("builder_desc_one_plus", "erscheint ein- oder mehrmals"))
            elif quantity_type == "zero_or_one":
                descriptions.append(self.translations.get("builder_desc_zero_one", "ist optional (0- oder 1-mal)"))
            elif quantity_type == "zero_or_more":
                descriptions.append(self.translations.get("builder_desc_zero_plus", "erscheint beliebig oft (0-mal oder mehr)"))
            elif quantity_type == "exactly_n":
                n = self.custom_quantity_var.get()
                if n.isdigit() and int(n) > 0:
                    descriptions.append(self.translations.get("builder_desc_n_times", "erscheint genau {}-mal").format(n))
                else:
                    descriptions.append("erscheint genau N-mal")
            elif quantity_type == "between_m_n":
                min_val = self.min_quantity_var.get()
                max_val = self.max_quantity_var.get()
                if min_val.isdigit() and max_val.isdigit():
                    descriptions.append(self.translations.get("builder_desc_m_n_times", "erscheint {} bis {}-mal").format(min_val, max_val))
                else:
                    descriptions.append("erscheint zwischen Min- und Max-mal")

        # Check for anchors and modifiers
        if preview.startswith("^"):
            descriptions.append(self.translations.get("builder_desc_start", "am Zeilenanfang"))
        if preview.endswith("$"):
            descriptions.append(self.translations.get("builder_desc_end", "am Zeilenende"))
        if preview.startswith("\\b") and preview.endswith("\\b"):
            descriptions.append(self.translations.get("builder_desc_word", "als ganzes Wort"))
        if "|" in preview:
            descriptions.append(self.translations.get("builder_desc_or", "mit Alternativen"))

        self.builder_description_var.set(" • ".join(descriptions))

    def add_to_pattern(self):
        """
        Add the current preview to the main regex pattern
        """
        preview = self.current_preview_var.get()
        if preview and preview != self.translations.get("select_char_first", "Wählen Sie zuerst einen Zeichentyp aus..."):
            current_pattern = self.regex_pattern_var.get()
            self.save_to_history(current_pattern)
            new_pattern = current_pattern + preview
            self.regex_pattern_var.set(new_pattern)

            # Reset builder selection for next component
            self.reset_builder_selection()
        else:
            messagebox.showwarning(self.translations.get("error", "Hinweis"), "Bitte wählen Sie zuerst einen Zeichentyp und optional eine Anzahl aus.")

    def reset_builder_selection(self):
        """
        Reset the current builder selection
        """
        self.current_char_type.set("")
        self.current_quantity_type.set("")
        self.custom_text_var.set("")
        self.current_preview_var.set(self.translations.get("select_char_first", "Wählen Sie zuerst einen Zeichentyp aus..."))
        self.builder_description_var.set("")

        # Hide custom input frames
        self.custom_text_frame.pack_forget()
        self.exactly_frame.pack_forget()
        self.between_frame.pack_forget()

    def manage_presets(self):
        """
        Open presets management dialog
        """
        # Get main GUI reference to access manage_presets method
        if hasattr(self, 'main_gui') and self.main_gui and hasattr(self.main_gui, 'manage_presets'):
            self.main_gui.manage_presets()

    def save_as_preset(self):
        """
        Save the current regex pattern as a new preset
        """
        pattern = self.regex_pattern_var.get().strip()
        if not pattern:
            messagebox.showwarning(self.translations.get("error", "Warnung"), self.translations.get("msg_no_pattern_copy", "Kein Regex-Muster zum Speichern verfügbar"))
            return

        # Ask for preset name
        name_dialog = tk.Toplevel(self.frame)
        name_dialog.title(self.translations.get("save_pattern", "Muster speichern"))
        name_dialog.geometry("400x200")
        name_dialog.resizable(False, False)
        name_dialog.transient(self.frame)
        name_dialog.grab_set()

        # Center the dialog
        name_dialog.update_idletasks()
        width = name_dialog.winfo_width()
        height = name_dialog.winfo_height()
        x = (self.frame.winfo_toplevel().winfo_width() // 2) - (width // 2) + self.frame.winfo_toplevel().winfo_x()
        y = (self.frame.winfo_toplevel().winfo_height() // 2) - (height // 2) + self.frame.winfo_toplevel().winfo_y()
        name_dialog.geometry(f'{width}x{height}+{x}+{y}')

        # Content
        content_frame = ttk.Frame(name_dialog, padding="15")
        content_frame.pack(fill=tk.BOTH, expand=True)

        ttk.Label(content_frame, text=self.translations.get("name_for_pattern", "Name für das neue Muster:")).pack(anchor=tk.W, pady=(0, 5))

        name_var = tk.StringVar()
        name_entry = ttk.Entry(content_frame, textvariable=name_var, width=40, font=('Segoe UI', 12))
        name_entry.pack(fill=tk.X, pady=(0, 10))
        name_entry.focus()

        # Buttons
        button_frame = ttk.Frame(content_frame)
        button_frame.pack(fill=tk.X, pady=(10, 0))

        def on_save():
            name = name_var.get().strip()
            if not name:
                messagebox.showerror(self.translations.get("error", "Fehler"), self.translations.get("enter_name", "Bitte geben Sie einen Namen ein"))
                return

            # Check if name already exists
            if hasattr(self, 'main_gui') and self.main_gui and name in self.main_gui.pattern_presets:
                if not messagebox.askyesno(self.translations.get("save_button", "Überschreiben"), self.translations.get("overwrite_confirm", "Ein Muster mit dem Namen '{}' existiert bereits. Möchten Sie es überschreiben?").format(name)):
                    return

            # Save the preset
            if hasattr(self, 'main_gui') and self.main_gui:
                self.main_gui.pattern_presets[name] = pattern
                self.main_gui.pattern_descriptions[name] = f"Muster aus Regex-Builder: {pattern[:50]}{'...' if len(pattern) > 50 else ''}"
                self.main_gui.save_presets()

                messagebox.showinfo(self.translations.get("success", "Erfolg"), self.translations.get("msg_save_success", "Muster '{}' wurde gespeichert").format(name))
                name_dialog.destroy()
            else:
                messagebox.showerror(self.translations.get("error", "Fehler"), self.translations.get("error_main_gui_not_connected", "Haupt-GUI nicht verfügbar"))

        def on_cancel():
            name_dialog.destroy()

        ttk.Button(button_frame, text=self.translations.get("save_button", "💾 Speichern"), command=on_save).pack(side=tk.RIGHT, padx=(5, 0))
        ttk.Button(button_frame, text="❌ Abbrechen", command=on_cancel).pack(side=tk.RIGHT)

        # Bind Enter key to save
        name_entry.bind('<Return>', lambda e: on_save())
        name_entry.bind('<Escape>', lambda e: on_cancel())

    def get_frame(self):
        """
        Get the frame for this tab

        Returns:
            The frame containing all widgets
        """
        return self.frame
