# -*- coding: utf-8 -*-
# vim:fileencoding=utf-8 ai ts=4 sts=4 et sw=4
# Copyright 2008 Neil Muller <drnlmuller+sutekh@gmail.com>
# GPL - see COPYING for details

"""Manage the icons from the WW site"""

from sutekh.base.core.BaseTables import CardType
from sutekh.base.core.BaseAdapters import ICardType
from sutekh.base.core.BaseGroupings import CardTypeGrouping, MultiTypeGrouping
from sutekh.base.io.BaseIconManager import BaseIconManager

from sutekh.core.SutekhTables import Clan, Creed, DisciplinePair, Virtue, Path
from sutekh.core.SutekhAdapters import IDisciplinePair, IVirtue, ICreed, IClan, IPath
from sutekh.core.Groupings import ClanGrouping, DisciplineGrouping


# Utilty functions - convert object to a filename
def _get_clan_filename(oClan):
    """Get the icon filename for the clan"""
    sClanName = oClan.name.lower().replace(' ', '')
    # Handle special cases
    if sClanName == 'harbingerofskulls':
        sClanName = 'harbingersofskulls'
    elif sClanName == 'ahrimane':
        sClanName = 'ahrimanes'
    elif sClanName == 'daughterofcacophony':
        sClanName = 'daughtersofcacophony'
    elif sClanName == 'gargoyle':
        sClanName = 'gargoyles'
    elif sClanName == 'abomination':
        sClanName = 'abominations'
    sFileName = 'clan/%s.png' % sClanName
    return sFileName


def _get_card_type_filename(oType):
    """Get the filename for the card type"""
    if oType.name == 'Action Modifier':
        sFileName = 'icon/modifier.png'
    elif oType.name == 'Political Action':
        sFileName = 'icon/political.png'
    elif oType.name in ('Master', 'Vampire', 'Imbued'):
        # These types have no icon
        sFileName = None
    else:
        sFileName = 'icon/%s.png' % oType.name.lower()
    return sFileName


def _get_creed_filename(oCreed):
    """Get the filename for the creed"""
    sFileName = 'clan/%s.png' % oCreed.name.lower()
    return sFileName


def _get_path_filename(oPath):
    """Get the filename for the path"""
    sPath = oPath.name.lower()
    if sPath == 'power and the inner voice':
        sPath = 'power'
    elif sPath == 'death and the soul':
        sPath = 'death'
    sFileName = 'path/%s.png' % sPath
    return sFileName


def _get_discipline_filename(oDiscipline):
    """Get the filename for the discipline."""
    if oDiscipline.discipline.fullname == 'Flight':
        sFileName = 'disc/inf/flight.png'
    elif oDiscipline.level == 'inferior':
        sFileName = ('disc/inf/%s.png' %
                     oDiscipline.discipline.name.lower())
    else:
        sFileName = ('disc/sup/%s.png' %
                     oDiscipline.discipline.name.lower())
    return sFileName


def _get_virtue_filename(oVirtue):
    """Get the filename for the virtue"""
    # KRCG uses its own abbrevation convention
    if oVirtue.name == 'jud':
        sFileName = 'disc/inf/jus.png'
    elif oVirtue.name == 'viz':
        sFileName = 'disc/inf/vin.png'
    else:
        sFileName = 'disc/inf/%s.png' % oVirtue.name.lower()
    return sFileName


class IconManager(BaseIconManager):
    """Manager for the VTES Icons.

       Given the text and the tag name, look up the suitable matching icon
       filename for it. Return none if no suitable icon is found.
       Also provide an option to download the icons form the krcg
       site.
       """

    sBaseUrl = "https://static.krcg.org/png/"

    def _get_clan_icons(self, aValues):
        """Get the icons for the clans"""
        dIcons = {}
        for oClan in aValues:
            sFileName = _get_clan_filename(oClan)
            dIcons[oClan.name] = self._get_icon(sFileName)
        return dIcons

    def _get_card_type_icons(self, aValues):
        """Get the icons for the card types"""
        dIcons = {}
        for oType in aValues:
            sFileName = _get_card_type_filename(oType)
            dIcons[oType.name] = self._get_icon(sFileName)
        return dIcons

    def _get_creed_icons(self, aValues):
        """Get the icons for the creeds."""
        dIcons = {}
        for oCreed in aValues:
            sFileName = _get_creed_filename(oCreed)
            dIcons[oCreed.name] = self._get_icon(sFileName)
        return dIcons

    def _get_path_icons(self, aValues):
        """Get the icons for the paths."""
        dIcons = {}
        for oPath in aValues:
            sFileName = _get_path_filename(oPath)
            dIcons[oPath.name] = self._get_icon(sFileName)
        return dIcons

    def _get_discipline_icons(self, aValues):
        """Get the icons for the disciplines."""
        dIcons = {}
        for oDiscipline in aValues:
            sFileName = _get_discipline_filename(oDiscipline)
            if oDiscipline.level == 'superior':
                oIcon = self._get_icon(sFileName, 14)
            else:
                oIcon = self._get_icon(sFileName)
            dIcons[oDiscipline.discipline.name] = oIcon
        return dIcons

    def _get_virtue_icons(self, aValues):
        """Get the icons for the Virtues."""
        dIcons = {}
        for oVirtue in aValues:
            sFileName = _get_virtue_filename(oVirtue)
            dIcons[oVirtue.name] = self._get_icon(sFileName)
        return dIcons

    def get_icon_by_name(self, sName):
        """Lookup an icon that's a card property"""
        if sName == 'burn option':
            sFileName = 'icon/burn.png'
        elif sName == 'advanced':
            sFileName = 'icon/adv.png'
        elif sName == 'merged':
            sFileName = 'icon/merged.png'
        else:
            return None
        return self._get_icon(sFileName)

    def get_info(self, sText, cGrouping):
        """Given the text and the grouping for a card list/set view,
           return the appropriate text array and icons for display."""
        if not sText:
            return [], []
        aText = []
        aIcons = []
        if cGrouping is CardTypeGrouping:
            aText = [sText]
            dIcons = self._get_card_type_icons([ICardType(x) for x in aText])
            # Only 1 icon
            aIcons = list(dIcons.values())
        elif cGrouping is MultiTypeGrouping:
            aText = sText.split(' / ')
            dIcons = self._get_card_type_icons([ICardType(x) for x in aText])
            # Do this since we need to have the same order as aText
            aIcons = [dIcons[x] for x in aText]
            aText = " /|".join(aText).split("|")
        elif cGrouping is DisciplineGrouping:
            aText = [sText]
            try:
                oDisVirt = IDisciplinePair((sText, 'superior'))
                dIcons = self._get_discipline_icons([oDisVirt])
                # We know there's only 1 icon, so this is OK
                aIcons = list(dIcons.values())
            except KeyError:
                try:
                    oDisVirt = IVirtue(sText)
                    dIcons = self._get_virtue_icons([oDisVirt])
                    aIcons = list(dIcons.values())
                except KeyError:
                    aIcons = [None]
        elif cGrouping is ClanGrouping:
            aText = [sText]
            try:
                oClanCreed = IClan(sText)
                dIcons = self._get_clan_icons([oClanCreed])
                # We know there's only 1 icon, so this is OK
                aIcons = list(dIcons.values())
            except KeyError:
                try:
                    oClanCreed = ICreed(sText)
                    dIcons = self._get_creed_icons([oClanCreed])
                    aIcons = list(dIcons.values())
                except KeyError:
                    aIcons = [None]
        return aText, aIcons

    def get_icon_list(self, aValues):
        """Get a dictionary of appropriate (value, icon) pairs for the
           given values"""
        if not aValues:
            return None
        dIcons = None
        if isinstance(aValues[0], CardType):
            dIcons = self._get_card_type_icons(aValues)
        elif isinstance(aValues[0], DisciplinePair):
            dIcons = self._get_discipline_icons(aValues)
        elif isinstance(aValues[0], Virtue):
            dIcons = self._get_virtue_icons(aValues)
        elif isinstance(aValues[0], Clan):
            dIcons = self._get_clan_icons(aValues)
        elif isinstance(aValues[0], Creed):
            dIcons = self._get_creed_icons(aValues)
        elif isinstance(aValues[0], Path):
            dIcons = self._get_path_icons(aValues)
        return dIcons

    def get_icon_total(self):
        """Total number of icons we must download"""
        # +3 for burn, adv & merged
        return (Creed.select().count() + DisciplinePair.select().count() +
                Clan.select().count() + Virtue.select().count() +
                CardType.select().count() + 3)

    def download_icons(self, oLogHandler=None):
        """Download the icons from the WW site"""
        # We use the names as from the WW site - this is not
        # ideal, but simpler than maintaining multiple names for each
        # icon.
        oLogger = self._make_logger(oLogHandler)
        for oCreed in Creed.select():
            self._download(_get_creed_filename(oCreed), oLogger)
        for oDiscipline in DisciplinePair.select():
            self._download(_get_discipline_filename(oDiscipline), oLogger)
        for oClan in Clan.select():
            self._download(_get_clan_filename(oClan), oLogger)
        for oVirtue in Virtue.select():
            self._download(_get_virtue_filename(oVirtue), oLogger)
        for oType in CardType.select():
            self._download(_get_card_type_filename(oType), oLogger)
        for oPath in Path.select():
            self._download(_get_path_filename(oPath), oLogger)
        # download the special cases
        self._download('icon/burn.png', oLogger)
        self._download('icon/adv.png', oLogger)
        self._download('icon/merged.png', oLogger)
