# Standard Library
import os
import shutil
from gettext import gettext as _

# Lutris Modules
from lutris.config import LutrisConfig
from lutris.exceptions import MissingBiosError, MissingGameExecutableError
from lutris.runners.runner import Runner
from lutris.util import system


class hatari(Runner):
    human_name = _("Hatari")
    description = _("Atari ST computers emulator")
    platform_dict = Runner.to_platform_dict([_("Atari ST")])
    runnable_alone = True
    flatpak_id = "org.tuxfamily.hatari"
    runner_executable = "hatari/bin/hatari"
    entry_point_option = "disk-a"

    game_options = [
        {
            "option": "disk-a",
            "type": "file",
            "label": _("Floppy Disk A"),
            "help": _(
                "Hatari supports floppy disk images in the following "
                "formats: ST, DIM, MSA, STX, IPF, RAW and CRT. The last "
                "three require the caps library (capslib). ZIP is "
                "supported, you don't need to uncompress the file."
            ),
        },
        {
            "option": "disk-b",
            "type": "file",
            "label": _("Floppy Disk B"),
            "help": _(
                "Hatari supports floppy disk images in the following "
                "formats: ST, DIM, MSA, STX, IPF, RAW and CRT. The last "
                "three require the caps library (capslib). ZIP is "
                "supported, you don't need to uncompress the file."
            ),
        },
    ]

    joystick_choices = [(_("None"), "none"), (_("Keyboard"), "keys"), (_("Joystick"), "real")]

    runner_options = [
        {
            "option": "bios_file",
            "type": "file",
            "label": _("Bios file (TOS)"),
            "help": _(
                "TOS is the operating system of the Atari ST "
                "and is necessary to run applications with the best "
                "fidelity, minimizing risks of issues.\n"
                "TOS 1.02 is recommended for games."
            ),
        },
        {
            "option": "fullscreen",
            "type": "bool",
            "section": _("Graphics"),
            "label": _("Fullscreen"),
            "default": False,
        },
        {
            "option": "zoom",
            "type": "bool",
            "section": _("Graphics"),
            "label": _("Scale up display by 2 (Atari ST/STE)"),
            "default": True,
            "help": _("Double the screen size in windowed mode."),
        },
        {
            "option": "borders",
            "type": "bool",
            "section": _("Graphics"),
            "label": _("Add borders to display"),
            "default": False,
            "help": _(
                "Useful for some games and demos using the overscan "
                "technique. The Atari ST displayed borders around the "
                "screen because it was not powerful enough to display "
                "graphics in fullscreen. But people from the demo scene "
                "were able to remove them and some games made use of "
                "this technique."
            ),
        },
        {
            "option": "status",
            "type": "bool",
            "section": _("Graphics"),
            "label": _("Display status bar"),
            "default": False,
            "help": _(
                "Displays a status bar with some useful information, "
                "like green leds lighting up when the floppy disks are "
                "read."
            ),
        },
        {
            "option": "joy0",
            "type": "choice",
            "section": _("Joysticks"),
            "label": _("Joystick 0"),
            "choices": joystick_choices,
            "default": "none",
        },
        {
            "option": "joy1",
            "type": "choice",
            "section": _("Joysticks"),
            "label": _("Joystick 1"),
            "choices": joystick_choices,
            "default": "real",
        },
    ]

    def install(self, install_ui_delegate, version=None, callback=None):
        def on_runner_installed(*args):
            bios_path = system.create_folder("~/.hatari/bios")

            bios_filename = install_ui_delegate.show_install_file_inquiry(
                question=_("Do you want to select an Atari ST BIOS file?"),
                title=_("Use BIOS file?"),
                message=_("Select a BIOS file"),
            )

            if bios_filename:
                shutil.copy(bios_filename, bios_path)
                bios_path = os.path.join(bios_path, os.path.basename(bios_filename))
                config = LutrisConfig(runner_slug="hatari")
                config.raw_runner_config.update({"bios_file": bios_path})
                config.save()
            if callback:
                callback()

        super().install(install_ui_delegate, version=version, callback=on_runner_installed)

    def play(self):  # pylint: disable=too-many-branches
        params = self.get_command()
        if self.runner_config.get("fullscreen"):
            params.append("--fullscreen")
        else:
            params.append("--window")

        params.append("--zoom")
        if self.runner_config.get("zoom"):
            params.append("2")
        else:
            params.append("1")

        params.append("--borders")
        if self.runner_config.get("borders"):
            params.append("true")
        else:
            params.append("false")

        params.append("--statusbar")
        if self.runner_config.get("status"):
            params.append("true")
        else:
            params.append("false")

        if self.runner_config.get("joy0"):
            params.append("--joy0")
            params.append(self.runner_config["joy0"])

        if self.runner_config.get("joy1"):
            params.append("--joy1")
            params.append(self.runner_config["joy1"])

        if system.path_exists(self.runner_config.get("bios_file", "")):
            params.append("--tos")
            params.append(self.runner_config["bios_file"])
        else:
            raise MissingBiosError()
        diska = self.game_config.get("disk-a")
        if not system.path_exists(diska):
            raise MissingGameExecutableError(filename=diska)
        params.append("--disk-a")
        params.append(diska)

        diskb = self.game_config.get("disk-b")
        if diskb:
            params.append("--disk-b")
            params.append(diskb)

        return {"command": params}
