# Copyright (c) 2017-2018 Cedric Bellegarde <cedric.bellegarde@adishatz.org>
# 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 3 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, see <http://www.gnu.org/licenses/>.

from gi.repository import Gtk, Gdk

import cairo
from math import pi

from passbook.define import SCHEMAS, LABELS, App, Type
from passbook.logger import Logger


class CollectionRow(Gtk.ListBoxRow):
    """
        An image and a label
    """

    __ICON_SIZE = 32

    def app_for_label(label):
        """
            Return (app, icon) as (str, str)
        """
        try:
            app = icons = None
            for sub in LABELS.keys():
                if sub in label:
                    (app, icons) = LABELS[sub]
                    break
            if app is not None:
                for icon in icons:
                    if App().icon_theme.lookup_icon(
                             icon,
                             Gtk.IconSize.DND,
                             Gtk.IconLookupFlags.GENERIC_FALLBACK) is not None:
                        return (app, icon)
                return (app, None)
        except:
            Logger.debug("Unknown label: %s" % label)
        return (None, None)

    def app_for_schema(schema):
        """
            Return (app, icon) as (str, str)
        """
        try:
            (app, icons) = SCHEMAS[schema]
            for icon in icons:
                if App().icon_theme.lookup_icon(
                             icon,
                             Gtk.IconSize.DND,
                             Gtk.IconLookupFlags.GENERIC_FALLBACK) is not None:
                    return (app, icon)
            return (app, None)
        except:
            Logger.debug("Unknown schema: %s" % schema)
        return (None, None)

    def __init__(self, app_name, icon_name, collection, collection_type):
        """
            Init row
            @param app_name as str
            @param icon_name as str
            @param collection as Secret.Collection
            @param collection_type as Type
        """
        # Fix broken apps with huge icons
        def get_icon_surface(icon_name):
            surface = App().icon_theme.load_surface(
                icon_name, self.__ICON_SIZE,
                self.get_scale_factor(), self.get_window(),
                Gtk.IconLookupFlags.FORCE_SIZE
            )
            return surface
        Gtk.ListBoxRow.__init__(self)
        self.__rgba = Gdk.RGBA()
        self.__icon_name = icon_name
        self.__name = app_name
        self.__collection = collection
        self.__collection_type = collection_type
        self.get_style_context().add_class("activatable")
        self.get_style_context().add_class("sidebar-row")
        self.get_style_context().add_class("sidebar-revealer")
        grid = Gtk.Grid()
        grid.set_column_spacing(5)
        try:
            surface = get_icon_surface(icon_name)
        except:
            surface = self.__get_rounded_icon()
        self.__image = Gtk.Image.new_from_surface(surface)
        if icon_name is None:
            self.__image.get_style_context().add_class("rounded-shadow")
        self.__label = Gtk.Label.new(app_name)
        grid.add(self.__image)
        grid.add(self.__label)
        self.add(grid)
        self.show_all()

    def set_collection(self, collection):
        """
            Update collection
            @param collection as Secret.Collection
        """
        self.__collection = collection

    def set_rgba_color(self, color):
        """
            Set rgba color
            @param color as str
        """
        if self.__icon_name is None:
            self.__rgba.parse(color)
            surface = self.__get_rounded_icon()
            self.__image.set_from_surface(surface)

    @property
    def collection(self):
        """
            Get collection
            @return Secret.Collection
        """
        return self.__collection

    @property
    def collection_type(self):
        """
            Get collection type
            @return Type
        """
        return self.__collection_type

    @property
    def name(self):
        """
            Get name based on type
            @return str
        """
        if self.__collection_type == Type.KEYRING:
            return self.collection.get_label()
        else:
            return self.__name

    @property
    def uid(self):
        """
            Get uid based on type
            @return str
        """
        if self.__collection_type == Type.KEYRING:
            return self.collection.get_object_path()
        else:
            return self.__name

#######################
# PRIVATE             #
#######################
    def __get_rounded_icon(self):
        """
            Get a rounded icon for app
            @return cairo.Surface
        """
        cover = cairo.ImageSurface(cairo.FORMAT_ARGB32,
                                   self.__ICON_SIZE,
                                   self.__ICON_SIZE)
        ctx = cairo.Context(cover)
        ctx.new_sub_path()
        radius = self.__ICON_SIZE / 2
        ctx.arc(self.__ICON_SIZE / 2, self.__ICON_SIZE / 2, radius, 0, 2 * pi)
        ctx.set_source_rgba(
            self.__rgba.red, self.__rgba.green, self.__rgba.blue)
        ctx.fill_preserve()
        ctx.scale(0.5, 0.5)
        ctx.clip()
        return cover
