# DearEIS is licensed under the GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.html).
# Copyright 2022 DearEIS developers
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
# The licenses of DearEIS' dependencies and/or sources of portions of code are included in
# the LICENSES folder.

import dearpygui.dearpygui as dpg
from deareis.utility import calculate_window_position_dimensions
from deareis.tooltips import attach_tooltip
import deareis.tooltips as tooltips
from deareis.enums import (
    Method,
    Mode,
    Test,
    Weight,
    label_to_method,
    label_to_mode,
    label_to_test,
    label_to_weight,
    method_to_label,
    mode_to_label,
    test_to_label,
    weight_to_label,
)
from deareis.data import (
    FitSettings,
    SimulationSettings,
    TestSettings,
)
from deareis.config import (
    DEFAULT_TEST_SETTINGS,
    DEFAULT_FIT_SETTINGS,
    DEFAULT_SIMULATION_SETTINGS,
)
from deareis.gui.plotting.export import (
    EXTENSIONS,
    LEGEND_LOCATIONS,
    PREVIEW_LIMITS,
    UNITS_PER_INCH,
)
from deareis.signals import Signal
import deareis.signals as signals


def show_defaults_settings_window(state):
    x: int
    y: int
    w: int
    h: int
    x, y, w, h = calculate_window_position_dimensions(374, 540)

    window: int = dpg.generate_uuid()
    key_handler: int = dpg.generate_uuid()

    def close_window():
        if dpg.does_item_exist(window):
            dpg.delete_item(window)
        if dpg.does_item_exist(key_handler):
            dpg.delete_item(key_handler)
        signals.emit(Signal.UNBLOCK_KEYBINDINGS)

    with dpg.handler_registry(tag=key_handler):
        dpg.add_key_release_handler(
            key=dpg.mvKey_Escape,
            callback=close_window,
        )

    with dpg.window(
        label="Settings - defaults",
        modal=True,
        pos=(
            x,
            y,
        ),
        width=w,
        height=h,
        no_resize=True,
        on_close=close_window,
        tag=window,
    ):
        label_pad: int
        # TODO: Timeout when generating certain outputs (e.g. SymPy and LaTeX expressions)
        # with dpg.collapsing_header(label="General", default_open=True):
        with dpg.collapsing_header(label="Kramers-Kronig tab", default_open=True):
            test_test_combo: int = dpg.generate_uuid()
            test_mode_combo: int = dpg.generate_uuid()
            test_mu_crit_slider: int = dpg.generate_uuid()
            test_add_cap_checkbox: int = dpg.generate_uuid()
            test_add_ind_checkbox: int = dpg.generate_uuid()
            test_method_combo: int = dpg.generate_uuid()
            test_max_nfev_input: int = dpg.generate_uuid()

            def update_default_test_settings():
                state.config.default_test_settings = TestSettings(
                    label_to_test.get(dpg.get_value(test_test_combo), Test.COMPLEX),
                    label_to_mode.get(dpg.get_value(test_mode_combo), Mode.EXPLORATORY),
                    999,
                    dpg.get_value(test_mu_crit_slider),
                    dpg.get_value(test_add_cap_checkbox),
                    dpg.get_value(test_add_ind_checkbox),
                    label_to_method.get(
                        dpg.get_value(test_method_combo), Method.LEASTSQ
                    ),
                    dpg.get_value(test_max_nfev_input),
                )

            def restore_default_test_settings():
                dpg.set_value(
                    test_test_combo, test_to_label[DEFAULT_TEST_SETTINGS.test]
                )
                dpg.set_value(
                    test_mode_combo, mode_to_label[DEFAULT_TEST_SETTINGS.mode]
                )
                dpg.set_value(test_mu_crit_slider, DEFAULT_TEST_SETTINGS.mu_criterion)
                dpg.set_value(
                    test_add_cap_checkbox, DEFAULT_TEST_SETTINGS.add_capacitance
                )
                dpg.set_value(
                    test_add_ind_checkbox, DEFAULT_TEST_SETTINGS.add_inductance
                )
                dpg.set_value(
                    test_method_combo, method_to_label[DEFAULT_TEST_SETTINGS.method]
                )
                dpg.set_value(test_max_nfev_input, DEFAULT_TEST_SETTINGS.max_nfev)
                update_default_test_settings()

            label_pad = 22
            with dpg.child_window(border=False, width=350, height=180):
                with dpg.group(horizontal=True):
                    dpg.add_text("Test".rjust(label_pad))
                    attach_tooltip(tooltips.kramers_kronig.test)
                    dpg.add_combo(
                        items=list(label_to_test.keys()),
                        default_value=test_to_label.get(
                            state.config.default_test_settings.test
                        ),
                        callback=update_default_test_settings,
                        tag=test_test_combo,
                        width=-1,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Mode".rjust(label_pad))
                    attach_tooltip(tooltips.kramers_kronig.mode)
                    dpg.add_combo(
                        items=list(label_to_mode.keys()),
                        default_value=mode_to_label.get(
                            state.config.default_test_settings.mode
                        ),
                        callback=update_default_test_settings,
                        tag=test_mode_combo,
                        width=-1,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Add capacitor".rjust(label_pad))
                    attach_tooltip(tooltips.kramers_kronig.add_capacitance)
                    dpg.add_checkbox(
                        default_value=state.config.default_test_settings.add_capacitance,
                        callback=update_default_test_settings,
                        tag=test_add_cap_checkbox,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Add inductor".rjust(label_pad))
                    attach_tooltip(tooltips.kramers_kronig.add_inductance)
                    dpg.add_checkbox(
                        default_value=state.config.default_test_settings.add_inductance,
                        callback=update_default_test_settings,
                        tag=test_add_ind_checkbox,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Mu-criterion".rjust(label_pad))
                    attach_tooltip(tooltips.kramers_kronig.mu_criterion)
                    dpg.add_slider_float(
                        default_value=state.config.default_test_settings.mu_criterion,
                        min_value=0.01,
                        max_value=0.99,
                        clamped=True,
                        format="%.2f",
                        callback=update_default_test_settings,
                        tag=test_mu_crit_slider,
                        width=-1,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Fitting method".rjust(label_pad))
                    attach_tooltip(tooltips.kramers_kronig.method)
                    dpg.add_combo(
                        items=list(label_to_method.keys()),
                        default_value=method_to_label.get(
                            state.config.default_test_settings.method
                        ),
                        callback=update_default_test_settings,
                        tag=test_method_combo,
                        width=-1,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Max. num. func. eval.".rjust(label_pad))
                    attach_tooltip(tooltips.kramers_kronig.nfev)
                    dpg.add_input_int(
                        default_value=state.config.default_test_settings.max_nfev,
                        min_value=0,
                        min_clamped=True,
                        step=0,
                        on_enter=True,
                        callback=update_default_test_settings,
                        tag=test_max_nfev_input,
                        width=-1,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("".rjust(label_pad))
                    dpg.add_button(
                        label="Restore defaults",
                        callback=restore_default_test_settings,
                    )
            dpg.add_spacer(height=8)

        with dpg.collapsing_header(label="Fitting tab", default_open=True):
            fit_cdc_input: int = dpg.generate_uuid()
            fit_method_combo: int = dpg.generate_uuid()
            fit_weight_combo: int = dpg.generate_uuid()
            fit_max_nfev_input: int = dpg.generate_uuid()

            def update_default_fit_settings():
                state.config.default_fit_settings = FitSettings(
                    dpg.get_value(fit_cdc_input),
                    label_to_method.get(dpg.get_value(fit_method_combo), Method.AUTO),
                    label_to_weight.get(dpg.get_value(fit_weight_combo), Weight.AUTO),
                    dpg.get_value(fit_max_nfev_input),
                )

            def restore_default_fit_settings():
                dpg.set_value(fit_cdc_input, DEFAULT_FIT_SETTINGS.cdc)
                dpg.set_value(
                    fit_method_combo,
                    method_to_label.get(DEFAULT_FIT_SETTINGS.method, "Auto"),
                )
                dpg.set_value(
                    fit_weight_combo,
                    weight_to_label.get(DEFAULT_FIT_SETTINGS.weight, "Auto"),
                )
                dpg.set_value(fit_max_nfev_input, DEFAULT_FIT_SETTINGS.max_nfev)
                update_default_fit_settings()

            label_pad = 22
            with dpg.child_window(border=False, width=350, height=112):
                with dpg.group(horizontal=True):
                    dpg.add_text("Circuit".rjust(label_pad))
                    attach_tooltip(tooltips.fitting.cdc)
                    dpg.add_input_text(
                        default_value=state.config.default_fit_settings.cdc,
                        on_enter=True,
                        callback=update_default_fit_settings,
                        width=-1,
                        tag=fit_cdc_input,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Method".rjust(label_pad))
                    attach_tooltip(tooltips.fitting.method)
                    dpg.add_combo(
                        items=["Auto"] + list(label_to_method.keys()),
                        default_value=method_to_label.get(
                            state.config.default_fit_settings.method, "Auto"
                        ),
                        width=-1,
                        callback=update_default_fit_settings,
                        tag=fit_method_combo,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Weight function".rjust(label_pad))
                    attach_tooltip(tooltips.fitting.weight)
                    dpg.add_combo(
                        items=["Auto"] + list(label_to_weight.keys()),
                        default_value=weight_to_label.get(
                            state.config.default_fit_settings.weight, "Auto"
                        ),
                        width=-1,
                        callback=update_default_fit_settings,
                        tag=fit_weight_combo,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Max. num. func. eval.".rjust(label_pad))
                    attach_tooltip(tooltips.fitting.nfev)
                    dpg.add_input_int(
                        default_value=state.config.default_fit_settings.max_nfev,
                        min_value=0,
                        min_clamped=True,
                        step=0,
                        on_enter=True,
                        callback=update_default_fit_settings,
                        tag=fit_max_nfev_input,
                        width=-1,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("".rjust(label_pad))
                    dpg.add_button(
                        label="Restore defaults",
                        callback=restore_default_fit_settings,
                    )
            dpg.add_spacer(height=8)

        with dpg.collapsing_header(label="Simulation tab", default_open=True):
            sim_cdc_input: int = dpg.generate_uuid()
            sim_max_freq_input: int = dpg.generate_uuid()
            sim_min_freq_input: int = dpg.generate_uuid()
            sim_per_decade_input: int = dpg.generate_uuid()

            def update_default_sim_settings():
                state.config.default_simulation_settings = SimulationSettings(
                    dpg.get_value(sim_cdc_input),
                    dpg.get_value(sim_min_freq_input),
                    dpg.get_value(sim_max_freq_input),
                    dpg.get_value(sim_per_decade_input),
                )

            def restore_default_sim_settings():
                dpg.set_value(sim_cdc_input, DEFAULT_SIMULATION_SETTINGS.cdc)
                dpg.set_value(
                    sim_min_freq_input, DEFAULT_SIMULATION_SETTINGS.min_frequency
                )
                dpg.set_value(
                    sim_max_freq_input, DEFAULT_SIMULATION_SETTINGS.max_frequency
                )
                dpg.set_value(
                    sim_per_decade_input, DEFAULT_SIMULATION_SETTINGS.num_per_decade
                )
                update_default_sim_settings()

            label_pad = 22
            with dpg.child_window(border=False, width=350, height=112):
                with dpg.group(horizontal=True):
                    dpg.add_text("Circuit".rjust(label_pad))
                    attach_tooltip(tooltips.simulation.cdc)
                    dpg.add_input_text(
                        default_value=state.config.default_simulation_settings.cdc,
                        on_enter=True,
                        callback=update_default_sim_settings,
                        width=-1,
                        tag=sim_cdc_input,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Max. frequency".rjust(label_pad))
                    attach_tooltip(tooltips.simulation.max_freq)
                    dpg.add_input_float(
                        label="Hz",
                        default_value=state.config.default_simulation_settings.max_frequency,
                        min_value=1e-20,
                        max_value=1e20,
                        min_clamped=True,
                        max_clamped=True,
                        on_enter=True,
                        format="%.3E",
                        step=0.0,
                        width=-22,
                        callback=update_default_sim_settings,
                        tag=sim_max_freq_input,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Min. frequency".rjust(label_pad))
                    attach_tooltip(tooltips.simulation.min_freq)
                    dpg.add_input_float(
                        label="Hz",
                        default_value=state.config.default_simulation_settings.min_frequency,
                        min_value=1e-20,
                        max_value=1e20,
                        min_clamped=True,
                        max_clamped=True,
                        on_enter=True,
                        format="%.3E",
                        step=0.0,
                        width=-22,
                        callback=update_default_sim_settings,
                        tag=sim_min_freq_input,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Num. points per decade".rjust(label_pad))
                    attach_tooltip(tooltips.simulation.per_decade)
                    dpg.add_input_int(
                        default_value=state.config.default_simulation_settings.num_per_decade,
                        min_value=1,
                        min_clamped=True,
                        step=0,
                        on_enter=True,
                        callback=update_default_sim_settings,
                        tag=sim_per_decade_input,
                        width=-1,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("".rjust(label_pad))
                    dpg.add_button(
                        label="Restore defaults",
                        callback=restore_default_sim_settings,
                    )
            dpg.add_spacer(height=8)

        with dpg.collapsing_header(label="Export plot", default_open=True):
            export_units: int = dpg.generate_uuid()
            export_width: int = dpg.generate_uuid()
            export_height: int = dpg.generate_uuid()
            export_dpi: int = dpg.generate_uuid()
            export_preview: int = dpg.generate_uuid()
            export_title: int = dpg.generate_uuid()
            export_legend: int = dpg.generate_uuid()
            export_legend_location: int = dpg.generate_uuid()
            export_grid: int = dpg.generate_uuid()
            export_tight: int = dpg.generate_uuid()
            export_num_per_decade: int = dpg.generate_uuid()
            export_extension: int = dpg.generate_uuid()
            export_experimental_clear_registry: int = dpg.generate_uuid()
            export_experimental_disable_previews: int = dpg.generate_uuid()

            def restore_default_export_settings():
                state.config.export_units = 1
                state.config.export_width = 10.0
                state.config.export_height = 6.0
                state.config.export_dpi = 100
                state.config.export_preview = 4
                state.config.export_title = True
                state.config.export_legend = True
                state.config.export_legend_location = 0
                state.config.export_grid = False
                state.config.export_tight = False
                state.config.export_num_per_decade = 100
                state.config.export_extension = ".png"
                state.config.export_experimental_clear_registry = True
                state.config.export_experimental_disable_previews = False
                dpg.set_value(
                    export_units, list(UNITS_PER_INCH)[state.config.export_units]
                )
                dpg.set_value(export_width, state.config.export_width)
                dpg.set_value(export_height, state.config.export_height)
                dpg.set_value(export_dpi, state.config.export_dpi)
                dpg.set_value(
                    export_preview, list(PREVIEW_LIMITS)[state.config.export_preview]
                )
                dpg.set_value(export_title, state.config.export_title)
                dpg.set_value(export_legend, state.config.export_legend)
                dpg.set_value(
                    export_legend_location,
                    list(LEGEND_LOCATIONS)[state.config.export_legend_location],
                )
                dpg.set_value(export_grid, state.config.export_grid)
                dpg.set_value(export_tight, state.config.export_tight)
                dpg.set_value(export_num_per_decade, state.config.export_num_per_decade)
                dpg.set_value(export_extension, state.config.export_extension)
                dpg.set_value(
                    export_experimental_clear_registry,
                    state.config.export_experimental_clear_registry,
                )
                dpg.set_value(
                    export_experimental_disable_previews,
                    state.config.export_experimental_disable_previews,
                )
                state.plot_exporter.update_settings(state.config)

            def update_export_units(unit: str):
                state.config.export_units = list(UNITS_PER_INCH).index(unit)
                state.plot_exporter.update_settings(state.config)

            def update_export_width(width: float):
                state.config.export_width = width
                state.plot_exporter.update_settings(state.config)

            def update_export_height(height: float):
                state.config.export_height = height
                state.plot_exporter.update_settings(state.config)

            def update_export_dpi(dpi: float):
                state.config.export_dpi = dpi
                state.plot_exporter.update_settings(state.config)

            def update_export_preview(limit: str):
                state.config.export_preview = list(PREVIEW_LIMITS).index(limit)
                state.plot_exporter.update_settings(state.config)

            def update_export_title(flag: bool):
                state.config.export_title = flag
                state.plot_exporter.update_settings(state.config)

            def update_export_legend(flag: bool):
                state.config.export_legend = flag
                state.plot_exporter.update_settings(state.config)

            def update_export_legend_location(location: str):
                state.config.export_legend_location = LEGEND_LOCATIONS[location]
                state.plot_exporter.update_settings(state.config)

            def update_export_grid(flag: bool):
                state.config.export_grid = flag
                state.plot_exporter.update_settings(state.config)

            def update_export_tight(flag: bool):
                state.config.export_tight = flag
                state.plot_exporter.update_settings(state.config)

            def update_export_num_per_decade(num: int):
                state.config.export_num_per_decade = num
                state.plot_exporter.update_settings(state.config)

            def update_export_extension(ext: str):
                state.config.export_extension = EXTENSIONS.index(ext)
                state.plot_exporter.update_settings(state.config)

            def update_export_experimental_clear_registry(flag: bool):
                state.config.export_experimental_clear_registry = flag
                state.plot_exporter.update_settings(state.config)

            def update_export_experimental_disable_previews(flag: bool):
                state.config.export_experimental_disable_previews = flag
                state.plot_exporter.update_settings(state.config)

            with dpg.child_window(border=False, width=350, height=320):
                with dpg.group(horizontal=True):
                    dpg.add_text("Units".rjust(label_pad))
                    attach_tooltip(tooltips.plotting.export_units)
                    dpg.add_combo(
                        width=-1,
                        items=list(UNITS_PER_INCH.keys()),
                        default_value=list(UNITS_PER_INCH.keys())[
                            state.config.export_units
                        ],
                        callback=lambda s, a, u: update_export_units(a),
                        tag=export_units,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Width".rjust(label_pad))
                    attach_tooltip(tooltips.plotting.export_width)
                    dpg.add_input_float(
                        width=-1,
                        default_value=state.config.export_width,
                        min_value=0.01,
                        min_clamped=True,
                        step=0.0,
                        format="%.2f",
                        on_enter=True,
                        callback=lambda s, a, u: update_export_width(a),
                        tag=export_width,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Height".rjust(label_pad))
                    attach_tooltip(tooltips.plotting.export_height)
                    dpg.add_input_float(
                        width=-1,
                        default_value=state.config.export_height,
                        min_value=0.01,
                        min_clamped=True,
                        step=0.0,
                        format="%.2f",
                        on_enter=True,
                        callback=lambda s, a, u: update_export_height(a),
                        tag=export_height,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("DPI".rjust(label_pad))
                    attach_tooltip(tooltips.plotting.export_dpi)
                    dpg.add_input_int(
                        width=-1,
                        default_value=state.config.export_dpi,
                        min_value=1,
                        min_clamped=True,
                        step=0,
                        on_enter=True,
                        callback=lambda s, a, u: update_export_dpi(a),
                        tag=export_dpi,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Preview".rjust(label_pad))
                    attach_tooltip(tooltips.plotting.export_preview)
                    dpg.add_combo(
                        width=-1,
                        items=list(PREVIEW_LIMITS.keys()),
                        default_value=list(PREVIEW_LIMITS.keys())[
                            state.config.export_preview
                        ],
                        callback=lambda s, a, u: update_export_preview(a),
                        tag=export_preview,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Title".rjust(label_pad))
                    attach_tooltip(tooltips.plotting.export_title)
                    dpg.add_checkbox(
                        default_value=state.config.export_title,
                        callback=lambda s, a, u: update_export_title(a),
                        tag=export_title,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Legend".rjust(label_pad))
                    attach_tooltip(tooltips.plotting.export_legend)
                    dpg.add_checkbox(
                        default_value=state.config.export_legend,
                        callback=lambda s, a, u: update_export_legend(a),
                        tag=export_legend,
                    )
                    dpg.add_combo(
                        width=-1,
                        items=list(LEGEND_LOCATIONS.keys()),
                        default_value=list(LEGEND_LOCATIONS.keys())[0],
                        callback=lambda s, a, u: update_export_legend_location(a),
                        tag=export_legend_location,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Grid".rjust(label_pad))
                    attach_tooltip(tooltips.plotting.export_grid)
                    dpg.add_checkbox(
                        default_value=state.config.export_grid,
                        callback=lambda s, a, u: update_export_grid(a),
                        tag=export_grid,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Tight".rjust(label_pad))
                    attach_tooltip(tooltips.plotting.export_tight)
                    dpg.add_checkbox(
                        default_value=state.config.export_tight,
                        callback=lambda s, a, u: update_export_tight(a),
                        tag=export_tight,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Points per decade".rjust(label_pad))
                    attach_tooltip(tooltips.plotting.export_num_per_decade)
                    dpg.add_input_int(
                        width=-1,
                        default_value=state.config.export_num_per_decade,
                        min_value=1,
                        min_clamped=True,
                        step=0,
                        on_enter=True,
                        callback=lambda s, a, u: update_export_num_per_decade(a),
                        tag=export_num_per_decade,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Extension".rjust(label_pad))
                    attach_tooltip(tooltips.plotting.export_extension)
                    dpg.add_combo(
                        width=-1,
                        items=EXTENSIONS,
                        default_value=EXTENSIONS[state.config.export_extension],
                        callback=lambda s, a, u: update_export_extension(a),
                        tag=export_extension,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Clear texture registry".rjust(label_pad))
                    attach_tooltip(tooltips.plotting.export_experimental_clear_registry)
                    dpg.add_checkbox(
                        default_value=state.config.export_experimental_clear_registry,
                        callback=lambda s, a, u: update_export_experimental_clear_registry(
                            a
                        ),
                        tag=export_experimental_clear_registry,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("Disable plot previews".rjust(label_pad))
                    attach_tooltip(tooltips.plotting.export_experimental_disable_previews)
                    dpg.add_checkbox(
                        default_value=state.config.export_experimental_disable_previews,
                        callback=lambda s, a, u: update_export_experimental_disable_previews(
                            a
                        ),
                        tag=export_experimental_disable_previews,
                    )
                with dpg.group(horizontal=True):
                    dpg.add_text("".rjust(label_pad))
                    dpg.add_button(
                        label="Restore defaults",
                        callback=restore_default_export_settings,
                    )
    signals.emit(Signal.BLOCK_KEYBINDINGS, window=window)
