# -*- coding: utf-8 -*-
"""
SymbolBrowserPanel
"""
import logging
from pyqode.core.api import Panel, TextHelper
from pyqode.qt import QtGui, QtCore, QtWidgets
from pyqode.core.share import Definition


def _logger():
    return logging.getLogger(__name__)


class SymbolBrowserPanel(Panel):
    """ Shows a combo box with the definitions found in the document.

    Allow quick navigation in the file and sync with the cursor
    position.
    """

    def __init__(self):
        super(SymbolBrowserPanel, self).__init__()
        self._prevLine = -1
        self._definitions = []
        layout = QtWidgets.QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.combo_box = QtWidgets.QComboBox()
        self.combo_box.setSizeAdjustPolicy(
            self.combo_box.AdjustToMinimumContentsLength)
        self.combo_box.activated.connect(self._on_definition_activated)
        layout.addWidget(self.combo_box)
        self.setLayout(layout)
        self.combo_box.addItem("Loading symbols...")

    def on_state_changed(self, state):
        super(SymbolBrowserPanel, self).on_state_changed(state)
        if state:
            self.editor.cursorPositionChanged.connect(
                self._on_cursor_pos_changed)
            try:
                self.editor.modes.get(
                    'OutlineMode').document_changed.connect(
                        self._on_document_changed)
            except KeyError:
                _logger().warning("No OutlineMode found, install it "
                                  "before SymbolBrowserPanel!")
        else:
            self.editor.cursorPositionChanged.disconnect(
                self._on_cursor_pos_changed)
            try:
                self.editor.modes.get(
                    'OutlineMode').document_changed.disconnect(
                        self._on_document_changed)
            except KeyError:
                pass

    def _on_document_changed(self):
        def flatten(results):
            """
            Flattens the document structure tree as a simple sequential list.
            """
            ret_val = []
            for de in results:
                ret_val.append(de)
                for sub_d in de.children:
                    nd = Definition(
                        sub_d.name, sub_d.line, sub_d.column, sub_d.icon)
                    nd.name = "    " + nd.name
                    ret_val.append(nd)
            return ret_val

        if not self or not self.editor:
            return
        mode = self.editor.modes.get('OutlineMode')
        definitions = flatten(mode.definitions)
        self.combo_box.clear()
        if definitions:
            self.combo_box.addItem(" < Select a symbol >")
        else:
            self.combo_box.addItem("No symbols")
        for d in definitions:
            try:
                self.combo_box.addItem(QtGui.QIcon(d.icon), d.name, d)
            except TypeError:
                self.combo_box.addItem(QtGui.QIcon.fromTheme(
                    d.icon[0], QtGui.QIcon(d.icon[1])), d.name, d)
        self._definitions = definitions
        self._sync_combo_box(TextHelper(self.editor).current_line_nbr())

    @QtCore.Slot(int)
    def _on_definition_activated(self, index):
        definition = self.combo_box.itemData(index)
        if definition:
            TextHelper(self.editor).goto_line(
                definition.line, column=definition.column)
            self.editor.setFocus()

    def _sync_combo_box(self, line):
        i = -1
        for i, d in enumerate(reversed(self._definitions)):
            if d.line <= line:
                break
        if i >= 0:
            index = len(self._definitions) - i
            self.combo_box.setCurrentIndex(index)

    def _on_cursor_pos_changed(self):
        line = TextHelper(self.editor).current_line_nbr()
        if self._prevLine != line:
            self._sync_combo_box(line)
        self._prevLine = line
