# 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

"""A registry of interesting kinds and their icons."""

from cgi import escape
from PyQt4 import QtCore, QtGui

from bzrlib.plugins.explorer.lib.i18n import gettext, N_


# Kinds of locations
BRANCH_KIND = "branch"
BOUND_BRANCH_KIND = "bound-branch"
CHECKOUT_KIND = "checkout"
REPOSITORY_KIND = "repository"
VIRTUAL_REPO_KIND = "virtual-repository"
ALL_KIND = "all"

# Other kinds of pages
WELCOME_PAGE = "welcome"

# General icons
INFORMATION = "information"
ENABLED = "enabled"
DISABLED = "disabled"

# Kinds of overall status
ERROR_STATUS = "error"
WARNING_STATUS = "warning"
GOOD_STATUS = INFORMATION

# Kinds of tools
LINK_TOOL = "link"
BZR_TOOL = "bzr"
BZREXEC_TOOL = "bzr-exec"
APPLICATION_TOOL = "application"
SHELL_TOOL = "shell"

# Kinds of preferences
APPEARANCE_PREFS = "appearance-prefs"
BEHAVIOUR_PREFS = "behaviour-prefs"
APPLICATION_PREFS = "application-prefs"

# Kinds of logos
SMALL_LOGO = "small"
MEDIUM_LOGO = "medium"
LARGE_LOGO = "large"

# Kinds of actions
ADD_ACTION = "add"
BRANCH_ACTION = BRANCH_KIND
CANCEL_ACTION = "cancel"
COLLAPSE_ALL_ACTION = "collapse-all"
COMMIT_ACTION = "commit"
CONFIGURATION_ACTION = "configuration"
CONFLICTS_ACTION = "conflicts"
DELETE_ACTION = "delete"
DIFF_ACTION = "diff"
DOWNLOAD_ACTION = "download"
EDIT_ACTION = "edit"
EXPAND_ALL_ACTION = "expand-all"
INITIALIZE_ACTION = "initialize"
LOG_ACTION = "log"
OPEN_ACTION = "open"
NEW_FILE_ACTION = "new-file"
NEW_FOLDER_ACTION = "new-folder"
OPEN_LOCATION_ACTION = "open-location"
OPEN_FOLDER_ACTION = "open-folder"
OPEN_HOSTED_ACTION = "open-hosted"
PREFERENCES_ACTION = "preferences"
REFRESH_ACTION = "refresh"
SEND_ACTION = "send"
START_ACTION = "start"
IGNORE_ACTION = "ignore"

# Kinds of view
# (Note: some explicitly aliased to 'matching' commands)
GENERIC_VIEW = "generic-view"
STATUS_VIEW = COMMIT_ACTION
SUBMIT_VIEW = SEND_ACTION

# Kinds of accessories
CLOTHES_ACCESSORY = "clothes"
BAG_ACCESSORY = "bag"
WALLET_ACCESSORY = "wallet"
HAT_ACCESSORY = "hat"

# Kinds of extension types
BOOKMARKS_EXT = "bookmarks"
EDITORS_EXT = "editors"
LOGOS_EXT = "logos"
TOOLS_EXT = "tools"
TOOLBARS_EXT = "toolbars"


# The list of all icon paths
ALL_ICON_PATHS = [
    "bzr-16",
    "actions/address-book-new",
    "actions/appointment-new",
    "actions/bookmark-new",
    "actions/contact-new",
    "actions/document-new",
    "actions/document-open",
    "actions/document-print",
    "actions/document-print-preview",
    "actions/document-properties",
    "actions/document-save",
    "actions/document-save-as",
    "actions/edit-clear",
    "actions/edit-copy",
    "actions/edit-cut",
    "actions/edit-delete",
    "actions/edit-find",
    "actions/edit-find-replace",
    "actions/edit-paste",
    "actions/edit-redo",
    "actions/edit-select-all",
    "actions/edit-undo",
    "actions/folder-new",
    "actions/format-indent-less",
    "actions/format-indent-more",
    "actions/format-justify-center",
    "actions/format-justify-fill",
    "actions/format-justify-left",
    "actions/format-justify-right",
    "actions/format-text-bold",
    "actions/format-text-italic",
    "actions/format-text-strikethrough",
    "actions/format-text-underline",
    "actions/go-bottom",
    "actions/go-down",
    "actions/go-first",
    "actions/go-home",
    "actions/go-jump",
    "actions/go-last",
    "actions/go-next",
    "actions/go-previous",
    "actions/go-top",
    "actions/go-up",
    "actions/list-add",
    "actions/list-remove",
    "actions/mail-forward",
    "actions/mail-mark-junk",
    "actions/mail-mark-not-junk",
    "actions/mail-message-new",
    "actions/mail-reply-all",
    "actions/mail-reply-sender",
    "actions/mail-send-receive",
    "actions/media-eject",
    "actions/media-playback-pause",
    "actions/media-playback-start",
    "actions/media-playback-stop",
    "actions/media-record",
    "actions/media-seek-backward",
    "actions/media-seek-forward",
    "actions/media-skip-backward",
    "actions/media-skip-forward",
    "actions/process-stop",
    "actions/system-lock-screen",
    "actions/system-log-out",
    "actions/system-search",
    "actions/system-shutdown",
    "actions/tab-new",
    "actions/view-fullscreen",
    "actions/view-refresh",
    "actions/window-new",
    "apps/accessories-calculator",
    "apps/accessories-character-map",
    "apps/accessories-text-editor",
    "apps/help-browser",
    "apps/internet-group-chat",
    "apps/internet-mail",
    "apps/internet-news-reader",
    "apps/internet-web-browser",
    "apps/office-calendar",
    "apps/preferences-desktop-accessibility",
    "apps/preferences-desktop-assistive-technology",
    "apps/preferences-desktop-font",
    "apps/preferences-desktop-keyboard-shortcuts",
    "apps/preferences-desktop-locale",
    "apps/preferences-desktop-multimedia",
    "apps/preferences-desktop-remote-desktop",
    "apps/preferences-desktop-screensaver",
    "apps/preferences-desktop-theme",
    "apps/preferences-desktop-wallpaper",
    "apps/preferences-system-network-proxy",
    "apps/preferences-system-session",
    "apps/preferences-system-windows",
    "apps/system-file-manager",
    "apps/system-installer",
    "apps/system-software-update",
    "apps/system-users",
    "apps/utilities-system-monitor",
    "apps/utilities-terminal",
    "categories/applications-accessories",
    "categories/applications-development",
    "categories/applications-games",
    "categories/applications-graphics",
    "categories/applications-internet",
    "categories/applications-multimedia",
    "categories/applications-office",
    "categories/applications-other",
    "categories/applications-system",
    "categories/preferences-desktop",
    "categories/preferences-desktop-peripherals",
    "categories/preferences-system",
    "devices/audio-card",
    "devices/audio-input-microphone",
    "devices/battery",
    "devices/camera-photo",
    "devices/camera-video",
    "devices/computer",
    "devices/drive-harddisk",
    "devices/drive-optical",
    "devices/drive-removable-media",
    "devices/input-gaming",
    "devices/input-keyboard",
    "devices/input-mouse",
    "devices/media-flash",
    "devices/media-floppy",
    "devices/media-optical",
    "devices/multimedia-player",
    "devices/network-wired",
    "devices/network-wireless",
    "devices/printer",
    "devices/video-display",
    "emblems/emblem-favorite",
    "emblems/emblem-important",
    "emblems/emblem-photos",
    "emblems/emblem-readonly",
    "emblems/emblem-symbolic-link",
    "emblems/emblem-system",
    "emblems/emblem-unreadable",
    "emotes/face-angel",
    "emotes/face-crying",
    "emotes/face-devilish",
    "emotes/face-glasses",
    "emotes/face-grin",
    "emotes/face-kiss",
    "emotes/face-monkey",
    "emotes/face-plain",
    "emotes/face-sad",
    "emotes/face-smile",
    "emotes/face-smile-big",
    "emotes/face-surprise",
    "emotes/face-wink",
    "mimetypes/application-certificate",
    "mimetypes/application-x-executable",
    "mimetypes/audio-x-generic",
    "mimetypes/font-x-generic",
    "mimetypes/image-x-generic",
    "mimetypes/package-x-generic",
    "mimetypes/text-html",
    "mimetypes/text-x-generic",
    "mimetypes/text-x-generic-template",
    "mimetypes/text-x-script",
    "mimetypes/video-x-generic",
    "mimetypes/x-office-address-book",
    "mimetypes/x-office-calendar",
    "mimetypes/x-office-document",
    "mimetypes/x-office-document-template",
    "mimetypes/x-office-drawing",
    "mimetypes/x-office-drawing-template",
    "mimetypes/x-office-presentation",
    "mimetypes/x-office-presentation-template",
    "mimetypes/x-office-spreadsheet",
    "mimetypes/x-office-spreadsheet-template",
    "places/folder",
    "places/folder-remote",
    "places/folder-saved-search",
    "places/network-server",
    "places/network-workgroup",
    "places/start-here",
    "places/user-desktop",
    "places/user-home",
    "places/user-trash",
    "status/audio-volume-high",
    "status/audio-volume-low",
    "status/audio-volume-medium",
    "status/audio-volume-muted",
    "status/battery-caution",
    "status/dialog-error",
    "status/dialog-information",
    "status/dialog-warning",
    "status/folder-drag-accept",
    "status/folder-open",
    "status/folder-visiting",
    "status/image-loading",
    "status/image-missing",
    "status/mail-attachment",
    "status/network-error",
    "status/network-idle",
    "status/network-offline",
    "status/network-receive",
    "status/network-transmit",
    "status/network-transmit-receive",
    "status/network-wireless-encrypted",
    "status/printer-error",
    "status/software-update-available",
    "status/software-update-urgent",
    "status/user-trash-full",
    "status/weather-clear",
    "status/weather-clear-night",
    "status/weather-few-clouds",
    "status/weather-few-clouds-night",
    "status/weather-overcast",
    "status/weather-severe-alert",
    "status/weather-showers",
    "status/weather-showers-scattered",
    "status/weather-snow",
    "status/weather-storm",
#    ":/custom/16x16/sun-glasses.png",
    ]


_RESOURCE_BY_KIND = {
    # Locations
    BRANCH_KIND:       "places/folder",
    BOUND_BRANCH_KIND: "status/network-idle",
    CHECKOUT_KIND:     "actions/media-eject",
    REPOSITORY_KIND:   "mimetypes/package-x-generic",
    VIRTUAL_REPO_KIND: "places/folder-saved-search",
    ALL_KIND:          "mimetypes/text-x-generic",
    # Pages
    WELCOME_PAGE:      "places/start-here",
    # General
    INFORMATION:        "status/dialog-information",
    ENABLED:            "status/weather-clear",
    DISABLED:           "emblems/emblem-unreadable",
    # Status
    ERROR_STATUS:       "status/dialog-error",
    WARNING_STATUS:     "status/dialog-warning",
    # Tools
    LINK_TOOL:          "mimetypes/text-html",
    BZR_TOOL:           "bzr-16",
    BZREXEC_TOOL:       "bzr-16",
    APPLICATION_TOOL:   "mimetypes/application-x-executable",
    SHELL_TOOL:         "mimetypes/application-x-shellscript",
    # Preferences
    APPEARANCE_PREFS:   "apps/preferences-desktop-theme",
    BEHAVIOUR_PREFS:    "categories/applications-multimedia",
    APPLICATION_PREFS:  "mimetypes/application-x-executable",
    # Logos
    SMALL_LOGO:         "bzr-16",
    MEDIUM_LOGO:        "bzr-32",
    LARGE_LOGO:         "bzr-48",
    # Actions
    ADD_ACTION:         "actions/list-add",
    CANCEL_ACTION:      "actions/process-stop",
    COLLAPSE_ALL_ACTION:"actions/media-skip-backward",
    COMMIT_ACTION:      "actions/go-last",
    CONFLICTS_ACTION:   "status/software-update-urgent",
    DELETE_ACTION:      "places/user-trash",
    DIFF_ACTION:        "apps/preferences-system-windows",
    EDIT_ACTION:        "apps/accessories-text-editor",
    EXPAND_ALL_ACTION:  "actions/media-skip-forward",
    LOG_ACTION:         "actions/appointment-new",
    OPEN_ACTION:        "actions/document-open",
    OPEN_LOCATION_ACTION: "apps/internet-web-browser",
    NEW_FILE_ACTION:    "actions/document-new",
    NEW_FOLDER_ACTION:  "actions/folder-new",
    OPEN_FOLDER_ACTION: "apps/system-file-manager",
    OPEN_HOSTED_ACTION: "mimetypes/text-html",
    SEND_ACTION:        "actions/mail-message-new",
    IGNORE_ACTION:      ":/custom/16x16/sun-glasses.png",
    # Actions used on the welcome page not already defined above
    CONFIGURATION_ACTION: "actions/contact-new",
    DOWNLOAD_ACTION:    "actions/go-jump",
    INITIALIZE_ACTION:  "actions/document-new",
    PREFERENCES_ACTION: "categories/preferences-system",
    REFRESH_ACTION:     "actions/view-refresh",
    START_ACTION:       "actions/folder-new",
    # Views
    GENERIC_VIEW:       "mimetypes/text-x-generic",
    # Accessories
    CLOTHES_ACCESSORY:  "apps/preferences-desktop-theme",
    BAG_ACCESSORY:      "categories/applications-system",
    WALLET_ACCESSORY:   "actions/contact-new",
    HAT_ACCESSORY:      "categories/applications-development",
    # Extension types
    BOOKMARKS_EXT:      "actions/bookmark-new",
    EDITORS_EXT:        "apps/accessories-text-editor",
    LOGOS_EXT:          "mimetypes/image-x-generic",
    TOOLS_EXT:          "categories/preferences-system",
    TOOLBARS_EXT:       "categories/applications-multimedia",
    }

# Cache
_icon_by_resource = {}


def icon_for_kind(kind):
    rpath = _RESOURCE_BY_KIND.get(kind, None)
    if rpath is None:
        return None
    return icon_by_resource_path(rpath)


def icon_by_resource_path(rpath, default=None):
    if rpath is None:
        rpath = default
    if rpath in _icon_by_resource:
        return _icon_by_resource[rpath]
    else:
        rpath = normalise_resource_path(rpath)
        try:
            pixmap = QtGui.QPixmap(rpath)
        except TypeError:
            # See bug #524265 - hopefully this handles it
            if rpath is None:
                return None
            else:
                pixmap = QtGui.QPixmap(QtCore.QVariant(rpath))
        icon = QtGui.QIcon()
        icon.addPixmap(pixmap, QtGui.QIcon.Normal, QtGui.QIcon.On)
        _icon_by_resource[rpath] = icon
        return icon


def path_for_icon(kind):
    return normalise_resource_path(_RESOURCE_BY_KIND.get(kind, None))


_resolvers = {}

def register_resolver(category, callable):
    """Register a function that resolves an icon in a category to a path."""
    global _resolvers
    _resolvers[category] = callable


def normalise_resource_path(rpath):
    """Convert category/name into the actual resource path."""
    if rpath is None or rpath[0] == ":" or rpath.endswith(".png"):
        return rpath
    sep = rpath.find('/')
    if sep >= 0:
        category = rpath[:sep]
        try:
            resolver = _resolvers[category]
            name = rpath[sep + 1:]
            return resolver(name)
        except KeyError:
            return ":/tango/16x16/%s.png" % (rpath,)
    else:
        return ":/%s" % (rpath,)


def html_status_message(status_kind, text):
    icon_fmt = '<img src="%s">'
    text_fmt = {
        ERROR_STATUS: '<font color="red">%s</font>',
        WARNING_STATUS: '%s',
        GOOD_STATUS: '%s',
        }[status_kind]
    message_fmt = '%s&nbsp;&nbsp;%s' % (icon_fmt, text_fmt)
    return message_fmt % (
        path_for_icon(status_kind),
        escape(text))


def html_action_links(actions, target=None):
    """Generate action links as html.
    
    :param actions: list of action names. If an action includes a space or (,
      then the first text before that is assumed to be the real action
      name for the purposes of icon and tooltip lookup.
    :param target: target for actions, or None for no target
    """
    action_parts = []
    for action in actions:
        # Note: icon must have same name as action itself.
        # Perhaps we should trap a None result, mutter it and
        # ignore it? Or maybe the hint text is sufficient?
        action_name = action
        for ch in [' ', '(']:
            sep = action.find(ch)
            if sep >= 0:
                action_name = action[:sep]
                break
        action_icon = path_for_icon(action_name)

        # We could use gettext here to lookup localised text but it's
        # probably better to show the command itself, given it can be
        # things like 'diff -rsubmit:..-1'
        action_hint = action

        if target is None:
            action_link = action
        else:
            action_link = "%s %s" % (action, target)
        action_parts.append('<a href="%s"><img src="%s" title="%s"/></a>'
            % (action_link, action_icon, action_hint))
    return ''.join(action_parts)
