# -*- coding: utf-8 -*-
"""Accent selection using Kodi's persistent skin colour themes."""
import json
import os

import xbmc
import xbmcaddon
import xbmcgui
import xbmcvfs
from wcs.skin import family

# Keep the background colours in defaults.xml; Kodi's own themes bring theirs.
PALETTE = (
    ('SKINDEFAULT', 'C49A45', 32538),
    ('milionar-kodi-blue.xml', '12B2E7', 32539),
    ('midnight.xml', '2866A4', 32540),
    ('teal.xml', '009688', 32541),
    ('green.xml', '24CA7A', 32542),
    ('orange.xml', 'FF9800', 32543),
    ('maroon.xml', 'C40300', 32545),
    ('pink.xml', 'E91E63', 32546),
    ('violet.xml', 'C050FF', 32547),
)


def _theme_id(name):
    name = name.lower()
    return name[:-4] if name.endswith('.xml') else name


def _png(color, size=128, margin=8, radius=28):
    """Rounded colour square as a PNG, written with the standard library only (no PIL: old builds lack features)."""
    import struct
    import zlib
    red, green, blue = int(color[0:2], 16), int(color[2:4], 16), int(color[4:6], 16)
    low, high = margin, size - margin
    rows = []
    for y in range(size):
        row = bytearray([0])
        for x in range(size):
            dx = max(low + radius - x - 0.5, x + 0.5 - (high - radius), 0)
            dy = max(low + radius - y - 0.5, y + 0.5 - (high - radius), 0)
            inside = low <= x < high and low <= y < high
            alpha = max(0.0, min(1.0, radius + 0.5 - (dx * dx + dy * dy) ** 0.5)) if inside else 0.0
            row += bytes((red, green, blue, int(alpha * 255)))
        rows.append(bytes(row))

    def chunk(kind, data):
        body = kind + data
        return struct.pack('>I', len(data)) + body + struct.pack('>I', zlib.crc32(body) & 0xffffffff)

    return (b'\x89PNG\r\n\x1a\n' + chunk(b'IHDR', struct.pack('>IIBBBBB', size, size, 8, 6, 0, 0, 0)) +
            chunk(b'IDAT', zlib.compress(b''.join(rows), 9)) + chunk(b'IEND', b''))


def _swatch(addon, color):
    """Row icon for a colour (generated once, cached in the addon data folder)."""
    try:
        folder = os.path.join(xbmcvfs.translatePath(addon.getAddonInfo('profile')), 'accent_swatches')
        os.makedirs(folder, exist_ok=True)
        path = os.path.join(folder, color + '.png')
        if not os.path.exists(path):
            with open(path, 'wb') as handle:
                handle.write(_png(color))
        return path
    except Exception as exc:
        xbmc.log('[Milionar] accent swatch failed: %s' % exc, xbmc.LOGWARNING)
        return ''


def select_accent():
    if not family.active():
        return
    addon = xbmcaddon.Addon()
    current = _theme_id(xbmc.getInfoLabel('Skin.CurrentColourTheme'))
    selected = next((i for i, row in enumerate(PALETTE) if _theme_id(row[0]) == current), 0)
    entries = []
    for _, color, label in PALETTE:
        item = xbmcgui.ListItem(addon.getLocalizedString(label), '#' + color)
        item.setArt({'icon': _swatch(addon, color), 'thumb': _swatch(addon, color)})
        entries.append(item)
    choice = xbmcgui.Dialog().select(addon.getLocalizedString(32537), entries,
                                     preselect=selected, useDetails=True)
    if choice < 0 or choice == selected:
        return
    response = json.loads(xbmc.executeJSONRPC(json.dumps({
        'jsonrpc': '2.0', 'id': 1, 'method': 'Settings.SetSettingValue',
        'params': {'setting': 'lookandfeel.skincolors', 'value': PALETTE[choice][0]},
    })))
    if response.get('result') is not True:
        xbmcgui.Dialog().notification('Milionář', addon.getLocalizedString(32544), xbmcgui.NOTIFICATION_ERROR)
