# Copyright 2005 Joe Wreschnig, Michael Urman
#       2021-22 Nick Boultbee
#
# 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 2 of the License, or
# (at your option) any later version.

from typing import Type

from gi.repository import Gtk

from quodlibet import _
from quodlibet import util
from quodlibet.qltk import get_top_parent
from quodlibet.qltk.icons import Icons
from quodlibet.qltk.window import Dialog
from quodlibet.util import escape
from senf import fsn2text, path2fsn


class Message(Gtk.MessageDialog, Dialog):
    """A message dialog that destroys itself after it is run, uses
    markup, and defaults to an 'OK' button."""

    def __init__(self, kind: Type, parent: Gtk.Widget, title: str, description: str,
                 buttons: Gtk.ButtonsType = Gtk.ButtonsType.OK,
                 escape_desc: bool = True):
        parent = get_top_parent(parent)
        markup = (f"<span weight='bold' size='larger'>{escape(title)}</span>\n\n"
                  + escape(description) if escape_desc else description)
        super().__init__(
            transient_for=parent, modal=True, destroy_with_parent=True,
            message_type=kind, buttons=buttons)
        self.set_markup(markup)

    def run(self, destroy=True):
        resp = super().run()
        if destroy:
            self.destroy()
        return resp


class CancelRevertSave(Gtk.MessageDialog, Dialog):
    def __init__(self, parent):
        title = _("Discard tag changes?")
        description = _("Tags have been changed but not saved. Save these "
                        "files, or revert and discard changes?")
        text = ("<span weight='bold' size='larger'>%s</span>\n\n%s"
                % (title, description))
        parent = get_top_parent(parent)
        super().__init__(
            transient_for=parent, flags=0,
            message_type=Gtk.MessageType.WARNING,
            buttons=Gtk.ButtonsType.NONE)

        self.add_icon_button(_("_Save"), Icons.DOCUMENT_SAVE,
                             Gtk.ResponseType.YES)
        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(_("_Revert"), Icons.DOCUMENT_REVERT,
                             Gtk.ResponseType.NO)

        self.set_default_response(Gtk.ResponseType.NO)
        self.set_markup(text)

    def run(self):
        resp = super().run()
        self.destroy()
        return resp


class ErrorMessage(Message):
    """Like Message, but uses an error-indicating picture."""

    def __init__(self, *args, **kwargs):
        super().__init__(
            Gtk.MessageType.ERROR, *args, **kwargs)


class WarningMessage(Message):
    """Like Message, but uses a warning-indicating picture."""

    def __init__(self, *args, **kwargs):
        super().__init__(
            Gtk.MessageType.WARNING, *args, **kwargs)


class ConfirmationPrompt(WarningMessage):
    """Dialog to confirm actions, given a parent, title, description, and
       OK-button text"""

    RESPONSE_INVOKE = Gtk.ResponseType.YES

    def __init__(self, parent, title, description, ok_button_text,
                 ok_button_icon=Icons.SYSTEM_RUN):
        super().__init__(parent, title, description, buttons=Gtk.ButtonsType.NONE)

        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(ok_button_text, ok_button_icon, self.RESPONSE_INVOKE)
        self.set_default_response(Gtk.ResponseType.CANCEL)


class ConfirmFileReplace(WarningMessage):

    RESPONSE_REPLACE = 1

    def __init__(self, parent, path):
        title = _("File exists")
        fn_format = util.bold(fsn2text(path2fsn(path)))
        description = _("Replace %(file-name)s?") % {"file-name": fn_format}

        super().__init__(
            parent, title, description, buttons=Gtk.ButtonsType.NONE)

        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(_("_Replace File"), Icons.DOCUMENT_SAVE,
                             self.RESPONSE_REPLACE)
        self.set_default_response(Gtk.ResponseType.CANCEL)
