"""
Пример пользовательского приложения на базе axipy.
Запускать необходимо из среды python.
"""

from PySide2.QtCore import Qt, Slot
from PySide2.QtWidgets import QMainWindow, QDockWidget, QStackedWidget, QAction

from axipy import (Notifications, LayerControlWidget, DataManagerWidget, NotificationWidget,
                   PythonConsoleWidget, view_manager, init_axioma, provider_manager, Layer, Map,
                   View, ActionManager, data_manager, open_file_dialog)


class MainWindow(QMainWindow):
    """
    Главное окно приложения
    """

    def __init__(self):
        super().__init__()
        self.setWindowTitle("Пример окна приложения")

        self._stacked_widget = QStackedWidget()
        view_manager.active_changed.connect(self.set_stacked_widget)

        self.setCentralWidget(self._stacked_widget)
        self.__initButtons()

    def _add_action(self, id):
        """
        Добавление встроенного действия
        """
        act = ActionManager[id]
        if act:
            self.toolbar.addAction(act)

    def __open_file(self):
        """
        Открытие файла
        """
        fileName = open_file_dialog(filter_arg='MapInfo Tab (*.tab)', selected_filter='MapInfo Tab (*.tab)' )
        if fileName:
            # Открываем таблицу
            table = provider_manager.openfile(fileName)
            data_manager.add(table)
            # создаем слой
            layer = Layer.create(table)
            # если карты нет, то создаем ее
            if not view_manager.active:
                map_ = Map([layer])
                mapview = view_manager.create_mapview(map_)
                # Первое окно как основное
                main_window.set_center_widget(mapview)
            # если есть, добавляем слой в окно карты
            else:
                view_manager.active.map.layers.append(layer)

    def __initButtons(self):
        """
        Инициализация панели инструментов
        """
        self.toolbar = self.addToolBar('Панель')
        # Пользовательское действие открытия файла
        self.action_open = QAction(ActionManager.icon_by_name("open"), "Открыть файл")
        self.action_open.triggered.connect(self.__open_file)
        self.toolbar.addAction(self.action_open)
        self._add_action('SaveTables')
        self.toolbar.addSeparator()
        self._add_action('Select')
        self._add_action('SelectInRect')
        self._add_action('Pan')
        self._add_action('ZoomIn')
        self._add_action('ZoomOut')
        self.toolbar.addSeparator()
        self._add_action('PointDraw')
        self._add_action('PolylineDraw')
        self._add_action('PolygonDraw')
        self.toolbar.addSeparator()
        self._add_action('SymbolStyle')
        self._add_action('LineStyle')
        self._add_action('PolygonStyle')

    def _create_maps_dock(self):
        """
        Окно управления слоями
        """
        self._layer_control_w = LayerControlWidget()
        self._layer_control_w.mapview_activated.connect(self.set_center_widget)
        dock_layer_control = QDockWidget(self._layer_control_w.widget.windowTitle(), self)
        dock_layer_control.setWidget(self._layer_control_w.widget)
        self.addDockWidget(Qt.LeftDockWidgetArea, dock_layer_control)

    def _create_data_manager_dock(self):
        """
        Открытые источники
        """
        data_manager_w = DataManagerWidget()
        dock_catalog = QDockWidget(data_manager_w.widget.windowTitle())
        dock_catalog.setWidget(data_manager_w.widget)

        def notify_selection():
            """
            Отслеживание выборки в списке открытых данных.
            """
            objects = data_manager_w.objects
            if len(objects) > 0:
                names = ', '.join(obj.name for obj in objects)
                Notifications.push("Выбрано", names, Notifications.Warning)

        data_manager_w.selection_changed.connect(notify_selection)
        self.addDockWidget(Qt.LeftDockWidgetArea, dock_catalog)

    def _create_notification_dock(self):
        """
        Окно уведомлений
        """
        notification_w = NotificationWidget()
        notification_w.widget.setFixedHeight(150)
        dock_notification = QDockWidget(notification_w.widget.windowTitle())
        dock_notification.setWidget(notification_w.widget)
        self.addDockWidget(Qt.BottomDockWidgetArea, dock_notification)

    def _create_python_dock(self):
        """
        Окно консоли python
        """
        notification_w = PythonConsoleWidget()
        notification_w.widget.setFixedHeight(150)
        dock_notification = QDockWidget(notification_w.widget.windowTitle())
        dock_notification.setWidget(notification_w.widget)
        self.addDockWidget(Qt.BottomDockWidgetArea, dock_notification)

    def init_gui(self):
        """
        Инициализация оконного интерфейса
        """
        self._create_maps_dock()
        self._create_data_manager_dock()
        self._create_notification_dock()
        self._create_python_dock()

    @Slot(View)
    def set_center_widget(self, inp_view: View):
        """
        Устанавливает активное окно.
        """
        view_manager.activate(inp_view)

    @Slot()
    def set_stacked_widget(self):
        w = view_manager.active.widget
        i = self._stacked_widget.indexOf(w)
        if i == -1:
            self._stacked_widget.insertWidget(0, w)
        else:
            self._stacked_widget.setCurrentIndex(i)


# Инициализция ядра
app = init_axioma()

# Создаем главное окно приложения
main_window = MainWindow()
main_window.init_gui()

# Левый верхний угол окна
x, y = 200, 10
# Ширина и высота окна
width, height = 1200, 800
main_window.resize(width, height)
main_window.move(x, y)

# Показываем главное окно
main_window.show()
app.exec_()
