from Products.CMFActionIcons.ActionIconsTool import ActionIconsTool as BaseTool
from Products.CMFActionIcons.permissions import View
from Products.CMFCore.utils import getToolByName
from AccessControl import ClassSecurityInfo
from App.class_init import InitializeClass
from Products.CMFPlone.PloneBaseTool import PloneBaseTool
from Products.CMFPlone.PloneTool import _icons as iconcache
from Products.CMFPlone.log import log_deprecated


WHITELISTED_AI = set([
    'controlpanel/ImagingSettings',
    'controlpanel/tinymce',
    'controlpanel/versioning',
])


def removeAICacheEntry(category, id):
    if (category, id) in iconcache.keys():
        del iconcache[(category, id)]


class ActionIconsTool(PloneBaseTool, BaseTool):

    meta_type = 'Plone Action Icons Tool'
    security = ClassSecurityInfo()
    toolicon = 'skins/plone_images/confirm_icon.png'

    security.declareProtected(View, 'renderActionIcon')
    def renderActionIcon( self,
                          category,
                          action_id,
                          default=None,
                          context=None ):
        """ Returns the actual object for the icon.  If you
            pass in a path elements in default it will attempt
            to traverse to that path.  Otherwise it will return
            None
        """
        icon = self.queryActionIcon( category,
                                     action_id,
                                     default=default,
                                     context=context )
        if icon is not None:
            portal=getToolByName(self, 'portal_url').getPortalObject()
            return portal.restrictedTraverse(icon)

        return default

    def getActionIcon( self, category, action_id, context=None ):
        ai = BaseTool.getActionIcon(self, category, action_id,
                                    context=context)
        if ai:
            log_deprecated("The icon for the '%s/%s' action was obtained from "
                           "the action icons tool. The action icons tool has "
                           "been deprecated and will be removed in Plone 5. "
                           "You should register action icons directly on the "
                           "action now, using the 'icon_expr' "
                           "setting." % (category, action_id))
            return ai
        return None

    def queryActionIcon( self, category, action_id
                       , default=None, context=None ):
        ai = BaseTool.queryActionIcon(self, category, action_id,
                                      default=default, context=context)
        if ai:
            log_deprecated("The icon for the '%s/%s' action was obtained from "
                           "the action icons tool. The action icons tool has "
                           "been deprecated and will be removed in Plone 5. "
                           "You should register action icons directly on the "
                           "action now, using the 'icon_expr' "
                           "setting." % (category, action_id))
            return ai
        return None

    def addActionIcon(self, category, action_id, icon_expr, title=None,
                      priority=0):
        combination = '%s/%s' % (category, action_id)
        if combination not in WHITELISTED_AI:
            log_deprecated("An icon for the '%s' action is being added to "
                           "the action icons tool. The action icons tool has "
                           "been deprecated and will be removed in Plone 5. "
                           "You should register action icons directly on the "
                           "action now, using the 'icon_expr' "
                           "setting." % combination)
        return BaseTool.addActionIcon(self, category, action_id, icon_expr,
                                      title, priority)

    #Below we need to invalidate the cache for icons.  We have to
    #hardocde the module dict because we do not have events, yet.
    def updateActionIcon( self
                        , category
                        , action_id
                        , icon_expr
                        , title=None
                        , priority=0
                        ):
        """ update ActionIcons and remove cache entry """
        log_deprecated("The icon for the '%s/%s' action is being updated on "
                       "the action icons tool. The action icons tool has "
                       "been deprecated and will be removed in Plone 5. "
                       "You should register action icons directly on the "
                       "action now, using the 'icon_expr' "
                       "setting." % (category, action_id))
        BaseTool.updateActionIcon(self, category, action_id, icon_expr,
                                  title, priority)
        removeAICacheEntry(category, action_id)

    def removeActionIcon( self, category, action_id ):
        """ remove ActionIcon and remove cache entry """
        BaseTool.removeActionIcon(self, category, action_id)
        removeAICacheEntry(category, action_id)

    def clearActionIcons( self ):
        """ clear ActionIcons and cache entries """
        BaseTool.clearActionIcons(self)
        iconcache.clear()

    def manage_updateActionIcon( self
                               , category
                               , action_id
                               , icon_expr
                               , title
                               , priority
                               , REQUEST
                               ):
        """ update ActionIcons from ZMI and remove cache entry """
        BaseTool.manage_updateActionIcon( self, category, action_id, icon_expr,
                                          title, priority, REQUEST )
        removeAICacheEntry(category, action_id)

    def manage_removeActionIcon( self, category, action_id, REQUEST ):
        """ remove ActionIcons from ZMI and remove cache entry """
        BaseTool.manage_removeActionIcon(self, category, action_id, REQUEST)
        removeAICacheEntry(category, action_id)

ActionIconsTool.__doc__ = BaseTool.__doc__

InitializeClass(ActionIconsTool)
