#!/usr/bin/python3 -Es
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (C) 2008,2012 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@redhat.com>
# Florian Festi <ffesti@redhat.com>

import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk


class ChooserButton:
    def __init__(self, button, default_label=""):
        self.button = button
        self.default_label = default_label

        self.label = None
        self._menu = None
        self._icon = None

        children = self.button.get_children()
        if len(children) == 1 and isinstance(children[0], (Gtk.HBox, Gtk.Box)):
            children = children[0].get_children()
            for child in children:
                if isinstance(child, Gtk.Label):
                    self.label = child
                    break
        else:
            for child in list(button.get_children()):
                button.remove(child)
            hbox = Gtk.HBox()
            self.label = Gtk.Label()
            arrow = Gtk.Arrow(
                arrow_type=Gtk.ArrowType.DOWN, shadow_type=Gtk.ShadowType.IN
            )
            hbox.set_spacing(2)
            hbox.pack_start(self.label, True, True, 0)
            hbox.pack_end(arrow, False, False, 0)
            button.add(hbox)
        if not self.label:
            raise ValueError("%s is not a ChooserButton" % button.get_name())
        self.connect("clicked", self._show_menu)
        self.reset()

    def set_sensitive(self, value):
        self.button.set_sensitive(value)

    def get_sensitive(self):
        return self.button.get_sensitive()

    def is_sensitive(self):
        return self.button.is_sensitive()

    def connect(self, _type, *args):
        return self.button.connect(_type, *args)

    def disconnect(self, *args):
        self.button.disconnect(*args)

    def get_text(self):
        return self.text

    def set_text(self, text):
        if not text or len(text) < 1:
            self.reset()
        self.text = text
        self.label.set_text(self.text)

    def set_stock_icon(self, name, size=Gtk.IconSize.MENU):
        if self._icon is None:
            self._icon = Gtk.Image()
            hbox = self.button.get_child()
            hbox.pack_start(self._icon, True, True, 0)
            hbox.reorder_child(self._icon, 0)

        self._icon.set_from_stock(name, size)

    def reset(self):
        self.text = None
        self.label.set_text(self.default_label)

    def set_menu(self, menu):
        self._menu = menu
        if menu:
            menu.attach_to_widget(self.button, self._detach_menu)

    def get_menu(self):
        return self._menu

    def _detach_menu(self):
        self._menu = None

    def _show_menu(self, *dummy):
        if not self._menu:
            return
        self._menu.popup(None, None, self._menu_position_func, 0, 0, 0)

    def _menu_position_func(self, menu, dummy):
        allocation = self.button.get_allocation()
        req = menu.size_request()
        menu_width = req.width
        menu_height = req.height
        if menu_width != allocation.width:
            menu.set_size_request(-1, -1)
            req = menu.size_request()
            if req.width > allocation.width:
                menu.set_size_request(req.width, req.height)
            else:
                menu.set_size_request(allocation.width, -1)

        (x, y) = self.button.get_parent_window().get_origin()[1:]
        x += allocation.x
        y += allocation.y + allocation.height

        root = self.button.get_root_window()
        (dummy, dummy, dummy, root_height) = root.get_geometry()

        if y + menu_height > root_height:
            y -= menu_height + allocation.height

        return (x, y, True)


class ToolChooserButton:
    def __init__(self, button, default_label=""):
        self.button = button
        self.default_label = default_label

        self._menu = None
        self._icon = None

        self.reset()

        self.set_sensitive = self.button.set_sensitive

    def get_text(self):
        return self.text

    def set_text(self, text):
        if not text or len(text) < 1:
            self.reset()
        self.text = text
        self.button.set_label(text)

    def set_stock_icon(self, name, size=Gtk.IconSize.BUTTON):
        if self._icon is None:
            self._icon = Gtk.Image()
            self.button.set_icon_widget(self._icon)

        self._icon.set_from_stock(name, size)

    def reset(self):
        self.text = None
        self.button.set_label(self.default_label)

    def set_menu(self, menu):
        self._menu = menu
        self.button.set_menu(menu)

    def get_menu(self):
        return self._menu

    def _detach_menu(self):
        self._menu = None
