# -*- coding: utf-8 -*-

from typing import Tuple

import wx.aui

from outwiker.api.core.text import positionInside

from .gui.toolswindow import ToolsPane
from .i18n import get_
from .tokentex import InlineTexToken
from .defines import TOOLS_PANE_NAME


class ToolsWindowController:
    def __init__(self, application):
        self._application = application
        self._toolsPane = None
        self._prevPositionInsideEquation = False
        self._auiManager = self._application.mainWindow.auiManager

    def initialize(self):
        global _
        _ = get_()

        self._application.onTextEditorCaretMove += self.__onTextEditorCaretMove
        self._auiManager.Bind(wx.aui.EVT_AUI_PANE_CLOSE, handler=self._onPaneClose)

    def destroy(self):
        self._auiManager.Unbind(wx.aui.EVT_AUI_PANE_CLOSE, handler=self._onPaneClose)
        self._application.onTextEditorCaretMove -= self.__onTextEditorCaretMove
        self._destroyToolsWindow()

    def _destroyToolsWindow(self):
        self._hideToolsWindow()
        if self._toolsPane is not None:
            self._toolsPane.close()
            self._toolsPane = None

    def __onTextEditorCaretMove(self, page, params) -> None:
        if params.startSelection != params.endSelection:
            return

        editor = params.editor
        position = params.startSelection
        text = editor.GetText()
        insideEquation = positionInside(text, position, "{$", "$}")

        if insideEquation:
            # May be the window was closed by user
            if not self._prevPositionInsideEquation:
                self._showToolsWindow()
                editor.SetFocus()

            self._updateEquation(text, position)
        else:
            self._hideToolsWindow()

        self._prevPositionInsideEquation = insideEquation

    def _showToolsWindow(self):
        """
        Show tools window (with equation preview). The window will be created
        if _toolsPane is None.
        """
        if self._toolsPane is None:
            self._toolsPane = ToolsPane(
                self._application.mainWindow,
                self._application.mainWindow.auiManager,
                self._application,
            )
            self._application.mainWindow.UpdateAuiManager()

        if not self._toolsPane.isShown():
            self._toolsPane.show()
            self._application.mainWindow.UpdateAuiManager()

    def _hideToolsWindow(self):
        if self._toolsPane is not None and self._toolsPane.isShown():
            self._toolsPane.hide()
            self._application.mainWindow.UpdateAuiManager()

    def _updateEquation(self, text, position):
        equation, blockMode = self.extractEquation(text, position)
        assert self._toolsPane is not None

        self._toolsPane.setEquation(equation, blockMode)
        self._application.mainWindow.Raise()

    @staticmethod
    def extractEquation(text: str, position: int) -> Tuple[str, bool]:
        left_token = InlineTexToken.texStart
        right_token = InlineTexToken.texEnd
        left_pos = text.rfind(left_token, 0, position)
        right_pos = text.find(right_token, position)

        blockMode = False
        if left_pos == -1 or right_pos == -1:
            return ("", blockMode)

        equation = text[left_pos + len(left_token) : right_pos]
        if equation.startswith("$") and equation.endswith("$"):
            equation = equation[1:-1]
            blockMode = True

        return (equation, blockMode)

    def _onPaneClose(self, event):
        paneName = event.GetPane().name
        if paneName == TOOLS_PANE_NAME:
            self._toolsPane.saveParams()

        event.Skip()
