# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
""" The default perspective menu for a workbench window. """


from pyface.action.api import Group, MenuManager
from traits.api import Instance, List, on_trait_change


from .delete_user_perspective_action import DeleteUserPerspectiveAction
from .new_user_perspective_action import NewUserPerspectiveAction
from .rename_user_perspective_action import RenameUserPerspectiveAction
from .reset_all_perspectives_action import ResetAllPerspectivesAction
from .reset_active_perspective_action import ResetActivePerspectiveAction
from .save_as_user_perspective_action import SaveAsUserPerspectiveAction
from .set_active_perspective_action import SetActivePerspectiveAction


class PerspectiveMenuManager(MenuManager):
    """ The default perspective menu for a workbench window. """

    # 'ActionManager' interface --------------------------------------------

    # All of the groups in the manager.
    groups = List(Group)

    # The manager's unique identifier.
    id = "PerspectivesMenu"

    # 'MenuManager' interface ---------------------------------------------#

    # The menu manager's name.
    name = "Perspectives"

    # 'PerspectiveMenuManager' interface -----------------------------------

    # The workbench window that the manager is part of.
    window = Instance("pyface.workbench.api.WorkbenchWindow")

    # ------------------------------------------------------------------------
    # 'ActionManager' interface.
    # ------------------------------------------------------------------------

    def _groups_default(self):
        """ Trait initializer. """

        groups = [
            # Create a group containing the actions that switch to specific
            # perspectives.
            self._create_perspective_group(self.window),
            # Create a group containing the user perspective create/save/rename
            # /delete actions.
            self._create_user_perspective_group(self.window),
            # Create a group containing the reset actions.
            self._create_reset_perspective_group(self.window),
        ]

        return groups

    # ------------------------------------------------------------------------
    # 'PerspectiveMenuManager' interface.
    # ------------------------------------------------------------------------

    @on_trait_change("window.perspectives")
    @on_trait_change("window.perspectives_items")
    def rebuild(self):
        """ Rebuild the menu.

        This is called when user perspectives have been added or removed.

        """

        # Clear out the old menu. This gives any actions that have trait
        # listeners (i.e. the rename and delete actions!) a chance to unhook
        # them.
        self.destroy()

        # Resetting the trait allows the initializer to run again (which will
        # happen just as soon as we fire the 'changed' event).
        self.reset_traits(["groups"])

        # Let the associated menu know that we have changed.
        self.changed = True

        return

    # ------------------------------------------------------------------------
    # Private interface.
    # ------------------------------------------------------------------------

    def _create_perspective_group(self, window):
        """ Create the actions that switch to specific perspectives. """

        # fixme: Not sure if alphabetic sorting is appropriate in all cases,
        # but it will do for now!
        perspectives = window.perspectives[:]
        perspectives.sort(key=lambda x: x.name)

        # For each perspective, create an action that sets the active
        # perspective to it.
        group = Group()
        for perspective in perspectives:
            group.append(
                SetActivePerspectiveAction(
                    perspective=perspective, window=window
                )
            )

        return group

    def _create_user_perspective_group(self, window):
        """ Create the user perspective create/save/rename/delete actions. """

        group = Group(
            NewUserPerspectiveAction(window=window),
            SaveAsUserPerspectiveAction(window=window),
            RenameUserPerspectiveAction(window=window),
            DeleteUserPerspectiveAction(window=window),
        )

        return group

    def _create_reset_perspective_group(self, window):
        """ Create the reset perspective actions. """

        group = Group(
            ResetActivePerspectiveAction(window=window),
            ResetAllPerspectivesAction(window=window),
        )

        return group
