# -*- coding: utf-8 -*-
# gui/components/model_view/contour/legacy_contour_binding_component.py

from __future__ import annotations

from inspect import isfunction
from types import MethodType
from typing import TYPE_CHECKING

from gui.components.model_view.contour.contour_definition_component import ContourDefinitionComponent
from gui.components.model_view.contour.contour_definition_component_part2 import (
    ContourDefinitionComponentPart2,
)
from gui.components.model_view.contour.contour_overlay_component import ContourOverlayComponent
from gui.components.model_view.contour.contour_overlay_component_part2 import (
    ContourOverlayComponentPart2,
)
from gui.components.model_view.contour.contour_overlay_selection_component import (
    ContourOverlaySelectionComponent,
)
from gui.components.model_view.contour.contour_visualization_component import (
    ContourVisualizationComponent,
)
from gui.components.model_view.contour.contour_visualization_component_part2 import (
    ContourVisualizationComponentPart2,
)
from gui.components.model_view.contour.contour_geometry_component import ContourGeometryComponent
from gui.components.model_view.contour.contour_geometry_component_part2 import (
    ContourGeometryComponentPart2,
)
from gui.components.model_view.contour.contour_selection_component import ContourSelectionComponent
from gui.components.model_view.contour.contour_preview_component import ContourPreviewComponent
from gui.components.model_view.contour.contour_preview_component_part2 import (
    ContourPreviewComponentPart2,
)
from gui.components.model_view.contour.contour_preview_contour_component import (
    ContourPreviewContourComponent,
)

if TYPE_CHECKING:
    from gui.components.model_view_widget import ModelViewWidget


class LegacyContourBindingComponent:
    """Компонент привязки legacy contour-методов к ModelViewWidget.

    Нужен как транзитный слой: позволяет убрать contour mixin-ы из MRO,
    сохранив поведение через композицию.
    """

    def __init__(self, model_view: "ModelViewWidget") -> None:
        self._mv = model_view
        self._classes = (
            ContourDefinitionComponent,
            ContourDefinitionComponentPart2,
            ContourOverlayComponent,
            ContourOverlayComponentPart2,
            ContourOverlaySelectionComponent,
            ContourVisualizationComponent,
            ContourVisualizationComponentPart2,
            ContourGeometryComponent,
            ContourGeometryComponentPart2,
            ContourSelectionComponent,
            ContourPreviewComponent,
            ContourPreviewComponentPart2,
            ContourPreviewContourComponent,
        )

    def install(self) -> None:
        host = self._mv
        for cls in self._classes:
            self._bind_class_methods(host, cls)

    @staticmethod
    def _bind_class_methods(host: object, cls: type) -> None:
        for name, member in cls.__dict__.items():
            if name.startswith("__"):
                continue
            if not isfunction(member):
                continue
            # Не перезаписываем существующие методы/атрибуты.
            if hasattr(host, name):
                continue
            setattr(host, name, MethodType(member, host))
