# Copyright (C) 2009 Canonical Ltd
#
# 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 2 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, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA

from PyQt4 import QtGui

from bzrlib.plugins.explorer.lib.builders import (
    toolset_builders,
    )
from bzrlib.plugins.explorer.lib import helpers
from bzrlib.plugins.explorer.lib.i18n import gettext, N_


class Toolbox(QtGui.QDockWidget):
    """Panel for selecting tools.

    Tools are organised into tool groups. Each tool group is a 'tab'
    within the toolbox. Within each tool group, tools are provided
    as tool buttons.
    """

    def __init__(self, accessories, tool_runner, action_provider, 
        menu_actions=None, title=None, style='tabs'):
        """An object that builds toolbar objects.
        
        :param accesories: the Accessories manager
        :param tool_runner: callback to open a user-defined tool
        :param actions_provider: maps an action name to an action object
        :param menu_actions: list of action names which are menus
        :param title: title for the toolbox. If not set, "Toolbox" is used.
        :param style: either 'tabs' or 'tree'
        """
        if title is None:
            title = gettext("Toolbox")
        QtGui.QDockWidget.__init__(self, title)
        self.setObjectName("ToolboxDockWidget")
        self._style = style
        if style == 'tree':
            factory = toolset_builders.ToolTreeBuilder
        elif style == 'tabs':
            factory = toolset_builders.ToolBoxBuilder
        elif style == 'tabs-icons-only':
            factory = toolset_builders.IconsOnlyToolBoxBuilder
        else:
            factory = toolset_builders.VerboseToolBoxBuilder
        self._builder = factory(accessories, tool_runner, action_provider,
            menu_actions)
        self._widgets = {}
        self._current_id = None

    def set_location(self, id):
        """Create or switch to the toolbox for a location with a unique id."""
        # Reuse widgets already built for a location, carrying across
        # existing expansions for the current one where we can.
        # If using tabs, there's no expansion data to merge: the
        # tab selected for the widget used if the best choice.
        try:
            current_widget = self._widgets[self._current_id]
            if self._style == 'tree':
                expanded, collapsed = helpers.get_tree_expansion(current_widget)
        except KeyError:
            expanded = []
            collapsed = []
        selected = -1
        try:
            widget = self._widgets[id]
        except KeyError:
            widget = self._build_ui()
            self._widgets[id] = widget
            # Expand the hat folder/tab initially if there's one
            if self._style == 'tree':
                hat_row = self._builder.hat_starting_row()
                if hat_row >= 0:
                    expanded.append([hat_row])
            else:
                selected = widget.count() - 1
        self.setWidget(widget)
        if self._style == 'tree':
            helpers.set_tree_expansion(widget, expanded, collapsed)
        elif selected >= 0:
            widget.setCurrentIndex(selected)
        self._current_id = id

    def _build_ui(self):
        return self._builder.build_ui()

    def rebuild(self):
        """Rebuild the toolbox after changes to tools."""
        self._widgets = {}
        self.set_location(self._current_id)
