#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2020 Félix Chénier

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Provide simple GUI functions.

Warning
-------
This module is private and should be considered only as helper functions
for Kinetics Toolkit's own use.
"""
from __future__ import annotations


__author__ = "Félix Chénier"
__copyright__ = "Copyright (C) 2020 Félix Chénier"
__email__ = "chenier.felix@uqam.ca"
__license__ = "Apache 2.0"

import kineticstoolkit.config as config
import limitedinteraction as li
import matplotlib as mpl
from typing import Any


def message(message: str = "", **kwargs) -> None:
    """
    Show a message window.

    Parameters
    ----------
    message
        The message to show. Use '' to close every message window.
    """
    li.message(
        message,
        icon=[
            config.root_folder + "/kineticstoolkit/logo.png",
            config.root_folder + "/kineticstoolkit/logo_hires.png",
        ],
        **kwargs,
    )


def button_dialog(
    message: str = "Please select an option.",
    choices: list[str] = ["Cancel", "OK"],
    **kwargs,
) -> int:
    """
    Create a blocking dialog message window with a selection of buttons.

    Parameters
    ----------
    message
        Message that is presented to the user.
    choices
        list of button text.

    Returns
    -------
    int
        The button number (0 = First button, 1 = Second button, etc.) If the
        user closes the window instead of clicking a button, a value of -1 is
        returned.
    """
    return li.button_dialog(
        message,
        choices,
        icon=[
            config.root_folder + "/kineticstoolkit/logo.png",
            config.root_folder + "/kineticstoolkit/logo_hires.png",
        ],
        **kwargs,
    )


def set_color_order(setting: str | list[Any]) -> None:
    """
    Define the standard color order for matplotlib.

    Parameters
    ----------
    setting
        Either a string or a list of colors.

        - If a string, it can be either:
            - 'default': Default v2.0 matplotlib colors.
            - 'classic': Default classic Matlab colors (bgrcmyk).
            - 'xyz': Same as classic but begins with rgb instead of bgr to
               be consistent with most 3d visualization softwares.

        - If a list, it can be either a list of chars from [bgrcmyk], a list of
          hexadecimal color values, or any list supported by matplotlib's
          axes.prop_cycle rcParam.

    """
    if isinstance(setting, str):
        if setting == "default":
            thelist = [
                "#1f77b4",
                "#ff7f0e",
                "#2ca02c",
                "#d62728",
                "#9467bd",
                "#8c564b",
                "#e377c2",
                "#7f7f7f",
                "#bcbd22",
                "#17becf",
            ]
        elif setting == "classic":
            thelist = ["b", "g", "r", "c", "m", "y", "k"]
        elif setting == "xyz":
            thelist = ["r", "g", "b", "c", "m", "y", "k", "tab:orange"]
        else:
            raise (ValueError("This setting is not recognized."))
    elif isinstance(setting, list):
        thelist = setting
    else:
        raise (ValueError("This setting is not recognized."))

    mpl.rcParams["axes.prop_cycle"] = mpl.cycler(color=thelist)


def get_credentials() -> tuple[str, str]:
    """
    Ask the user's username and password.

    Returns
    -------
    tuple[str]
        A tuple of two strings containing the username and password,
        respectively, or an empty tuple if the user closed the window.

    """
    return li.input_dialog(
        "Please enter your credentials",
        descriptions=["Username:", "Password:"],
        masked=[False, True],
        icon="lock",
    )


def get_folder(initial_folder: str = ".") -> str:
    """
    Get folder interactively using a file dialog window.

    Parameters
    ----------
    initial_folder
        Optional. The initial folder of the file dialog.

    Returns
    -------
    str
        The full path of the selected folder. An empty string is returned if
        the user cancelled.

    """
    return li.get_folder(
        initial_folder,
        icon=[
            config.root_folder + "/kineticstoolkit/logo.png",
            config.root_folder + "/kineticstoolkit/logo_hires.png",
        ],
    )


def get_filename(initial_folder: str = ".") -> str:
    """
    Get file name interactively using a file dialog window.

    Parameters
    ----------
    initial_folder
        Optional. The initial folder of the file dialog.

    Returns
    -------
    str
        The full path of the selected file. An empty string is returned if the
        user cancelled.
    """
    return li.get_filename(
        initial_folder,
        icon=[
            config.root_folder + "/kineticstoolkit/logo.png",
            config.root_folder + "/kineticstoolkit/logo_hires.png",
        ],
    )
