"""Game panel"""
from datetime import datetime
from gi.repository import Gtk, Pango, GObject
from lutris import runners
from lutris.gui.widgets.utils import get_pixbuf_for_game, get_link_button
from lutris.util.strings import gtk_safe
from lutris.gui.views.generic_panel import GenericPanel


class GamePanel(GenericPanel):
    """Panel allowing users to interact with a game"""

    __gsignals__ = {
        "panel-closed": (GObject.SIGNAL_RUN_FIRST, None, ()),
    }

    def __init__(self, game_actions):
        self.game_actions = game_actions
        self.game = game_actions.game
        super().__init__()
        self.game.connect("game-start", self.on_game_start)
        self.game.connect("game-started", self.on_game_started)
        self.game.connect("game-stopped", self.on_game_stop)

    def place_content(self):
        self.put(self.get_close_button(), 276, 16)
        self.put(self.get_icon(), 12, 16)
        self.put(self.get_title_label(), 50, 20)
        labels_x = 50
        if self.game.is_installed:
            self.put(self.get_runner_label(), labels_x - 23, 64)
        if self.game.playtime:
            self.put(self.get_playtime_label(), labels_x, 86)
        if self.game.lastplayed:
            self.put(self.get_last_played_label(), labels_x, 108)
        self.buttons = self.get_buttons()
        self.place_buttons(145)

    @property
    def background_id(self):
        return self.game.slug

    def get_close_button(self):
        """Return the close button"""
        button = Gtk.Button.new_from_icon_name("window-close-symbolic", Gtk.IconSize.MENU)
        button.set_tooltip_text("Close")
        button.set_size_request(32, 32)
        button.connect("clicked", self.on_close)
        button.show()
        return button

    def get_icon(self):
        """Return the game icon"""
        icon = Gtk.Image.new_from_pixbuf(get_pixbuf_for_game(self.game.slug, "icon"))
        icon.show()
        return icon

    def get_title_label(self):
        """Return the label with the game's title"""
        title_label = Gtk.Label()
        title_label.set_markup("<span font_desc='16'>%s</span>" % gtk_safe(self.game.name))
        title_label.set_ellipsize(Pango.EllipsizeMode.END)
        title_label.set_size_request(226, -1)
        title_label.set_alignment(0, 0.5)
        title_label.set_justify(Gtk.Justification.LEFT)
        title_label.show()
        return title_label

    def get_runner_label(self):
        """Return the label containing the runner info"""
        runner_icon = Gtk.Image.new_from_icon_name(
            self.game.runner.name.lower().replace(" ", "") + "-symbolic", Gtk.IconSize.MENU
        )
        runner_icon.show()
        runner_label = Gtk.Label()
        runner_label.show()
        runner_label.set_markup("<b>%s</b>" % gtk_safe(self.game.platform))
        runner_box = Gtk.Box(spacing=6)
        runner_box.add(runner_icon)
        runner_box.add(runner_label)
        runner_box.show()
        return runner_box

    def get_playtime_label(self):
        """Return the label containing the playtime info"""
        playtime_label = Gtk.Label()
        playtime_label.show()
        playtime_label.set_markup("Time played: <b>%s</b>" % self.game.formatted_playtime)
        return playtime_label

    def get_last_played_label(self):
        """Return the label containing the last played info"""
        last_played_label = Gtk.Label()
        last_played_label.show()
        lastplayed = datetime.fromtimestamp(self.game.lastplayed)
        last_played_label.set_markup("Last played: <b>%s</b>" % lastplayed.strftime("%x"))
        return last_played_label

    def get_runner_entries(self, game):
        try:
            runner = runners.import_runner(game.runner_name)(game.config)
        except runners.InvalidRunner:
            return None
        return runner.context_menu_entries

    def get_buttons(self):
        displayed = self.game_actions.get_displayed_entries()
        disabled_entries = self.game_actions.get_disabled_entries()
        icon_map = {
            # "stop": "media-playback-stop-symbolic",
            # "play": "media-playback-start-symbolic",
            "configure": "preferences-system-symbolic",
            "browse": "system-file-manager-symbolic",
            "show_logs": "utilities-system-monitor-symbolic",
            "remove": "user-trash-symbolic",
        }
        buttons = {}
        for action in self.game_actions.get_game_actions():
            action_id, label, callback = action
            if action_id in icon_map:
                button = Gtk.Button.new_from_icon_name(
                    icon_map[action_id], Gtk.IconSize.MENU
                )
                button.set_tooltip_text(label)
                button.set_size_request(32, 32)
            else:
                if action_id in ("play", "stop", "install"):
                    button = Gtk.Button(label)
                    button.set_size_request(146, 42)
                else:
                    button = get_link_button(label)
            button.connect("clicked", callback)

            if displayed.get(action_id):
                button.show()
            else:
                button.hide()
            if disabled_entries.get(action_id):
                button.set_sensitive(False)
            buttons[action_id] = button

        if self.game.runner_name and self.game.is_installed:
            for entry in self.get_runner_entries(self.game):
                name, label, callback = entry
                button = get_link_button(label)
                button.show()
                button.connect("clicked", callback)
                buttons[name] = button
        return buttons

    def place_buttons(self, base_height):
        play_x_offset = 87
        icon_offset = 6
        icon_width = 32
        icon_start = 84
        icons_y_offset = 60
        buttons_x_offset = 28
        extra_button_start = 520  # Y position for runner actions
        extra_button_index = 0
        for action_id, button in self.buttons.items():
            position = None
            if action_id in ("play", "stop", "install"):
                position = (play_x_offset,
                            base_height)
            if action_id == "configure":
                position = (icon_start,
                            base_height + icons_y_offset)
            if action_id == "browse":
                position = (icon_start + icon_offset + icon_width,
                            base_height + icons_y_offset)
            if action_id == "show_logs":
                position = (icon_start + icon_offset * 2 + icon_width * 2,
                            base_height + icons_y_offset)
            if action_id == "remove":
                position = (icon_start + icon_offset * 3 + icon_width * 3,
                            base_height + icons_y_offset)
            if action_id == "execute-script":
                position = (50,
                            base_height + 82)

            current_y = base_height + 150
            if action_id in ("add", "install_more"):
                position = (buttons_x_offset, current_y + 40)
            if action_id == "view":
                position = (buttons_x_offset, current_y + 80)
            if action_id in ("desktop-shortcut", "rm-desktop-shortcut"):
                position = (buttons_x_offset, current_y + 120)
            if action_id in ("menu-shortcut", "rm-menu-shortcut"):
                position = (buttons_x_offset, current_y + 160)

            if not position:
                position = (buttons_x_offset, extra_button_start + extra_button_index * 40)
                extra_button_index += 1

            self.put(button, position[0], position[1])

    def on_game_start(self, widget):
        self.buttons["play"].set_label("Launching...")
        self.buttons["play"].set_sensitive(False)

    def on_game_started(self, widget):
        self.buttons["stop"].show()
        self.buttons["play"].hide()
        self.buttons["play"].set_label("Play")
        self.buttons["play"].set_sensitive(True)
        self.buttons["show_logs"].set_sensitive(True)

    def on_game_stop(self, widget, game_id=None):
        for child in self.get_children():
            child.destroy()
        self.place_content()
        self.buttons["show_logs"].set_sensitive(True)

    def on_close(self, _widget):
        self.emit("panel-closed")
