#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author: Niccolò Bonacchi
# @Date: Sunday, February 3rd 2019, 11:59:56 am
import tkinter as tk
from tkinter import simpledialog
from tkinter import messagebox


def popup(title, msg):
    root = tk.Tk()
    root.withdraw()
    messagebox.showinfo(title, msg)
    root.quit()


def numinput(title, prompt, default=None, minval=None, maxval=None,
             nullable=False, askint=False):
    root = tk.Tk()
    root.withdraw()
    ask = simpledialog.askinteger if askint else simpledialog.askfloat
    ans = ask(
        title, prompt, initialvalue=default, minvalue=minval, maxvalue=maxval)
    if ans == 0:
        return ans
    elif not ans and not nullable:
        return numinput(
            title, prompt, default=default, minval=minval, maxval=maxval,
            nullable=nullable, askint=askint)
    return ans


def strinput(title, prompt, default='COM', nullable=False):
    """
    Example:
    >>> strinput("RIG CONFIG", "Insert RE com port:", default="COM")
    """
    import tkinter as tk
    from tkinter import simpledialog
    root = tk.Tk()
    root.withdraw()
    ans = simpledialog.askstring(title, prompt, initialvalue=default)
    if (ans is None or ans == '' or ans == default) and not nullable:
        return strinput(title, prompt, default=default, nullable=nullable)
    else:
        return ans


def login(title='Enter Credentials', default_username=None, default_passwd=None, add_fields=None):
    """
    Dialog box prompting for username and password.

    :param title: Window title
    :param default_username: default field for username
    :param default_passwd:  default field for password
    :param add_fields: list of new fields to be added to the dialog
    :return:
    """
    class Toto:
        def __init__(self, root, default_username=None, default_passwd=None, title=None,
                     add_fields=None):
            self.add_fields = add_fields or []
            self.var1 = tk.StringVar()
            self.root = root
            # self.root.geometry('300x160')
            self.root.title(title)
            # frame for window margin
            self.parent = tk.Frame(self.root, padx=10, pady=10)
            self.parent.pack(fill=tk.BOTH, expand=True)
            # entrys with not shown text
            self.add_entries = []
            for fname in self.add_fields:
                self.add_entries.extend([self.make_entry(self.parent, fname + ":", 42, show="")])

            self.user = self.make_entry(self.parent, "User name:", 42, show='',
                                        default=default_username)
            self.password = self.make_entry(self.parent, "Password:", 42, show="*",
                                            default=default_passwd)
            # button to attempt to login
            self.button = tk.Button(self.parent, borderwidth=4, text="Login", width=42, pady=8,
                                    command=self.get_value)
            self.button.pack(side=tk.BOTTOM)
            self.user.focus_set()
            self.USR = None
            self.MDP = None
            self.root.bind('<Return>', self.push_enter)
            # do not reproduce vim behaviour
            self.root.protocol("WM_DELETE_WINDOW", self.cancel_login)

        def make_entry(self, _, caption, width=None, default='', **options):
            tk.Label(self.parent, text=caption).pack(side=tk.TOP)
            entry = tk.Entry(self.parent, **options)
            if width:
                entry.config(width=width)
            entry.pack(side=tk.TOP, padx=10, fill=tk.BOTH)
            if default:
                entry.insert(0, default)
            return entry

        def push_enter(self, _):
            self.get_value()

        def get_value(self):
            self.USR = self.user.get()
            self.MDP = self.password.get()
            self.ADD = []
            for entry in self.add_entries:
                self.ADD.extend([entry.get()])
            self.root.destroy()
            self.root.quit()

        def cancel_login(self):
            self.USR = None
            self.MDP = None
            self.ADD = []
            for entry in self.add_entries:
                self.ADD.extend([None])
            self.root.destroy()
            self.root.quit()

    root = tk.Tk()
    toto = Toto(root, title=title, default_passwd=default_passwd,
                default_username=default_username, add_fields=add_fields)
    root.mainloop()
    return [toto.USR] + [toto.MDP] + toto.ADD


def multi_input(title='Enter Credentials', add_fields=None, defaults=None):
    class Toto:
        def __init__(self, root, title=None, add_fields=None, defaults=None):
            self.fields_to_add = add_fields or []
            if defaults is None or len(defaults) != len(add_fields):
                self.defaults = [None for x in self.fields_to_add]
            else:
                self.defaults = defaults
            self.var1 = tk.StringVar()
            self.root = root
            # self.root.geometry('300x160')
            self.root.title(title)
            # frame for window margin
            self.parent = tk.Frame(self.root, padx=10, pady=10)
            self.parent.pack(fill=tk.BOTH, expand=True)
            # entrys with not shown text
            self.add_entries = []
            for fname, fdef in zip(self.fields_to_add, self.defaults):
                self.add_entries.extend(
                    [self.make_entry(self.parent, fname + ":", 42, show="", default=fdef)])
            # button to attempt to login
            self.button = tk.Button(self.parent, borderwidth=4, text="Submit", width=42, pady=8,
                                    command=self.get_value)
            self.button.pack(side=tk.BOTTOM)
            self.root.bind('<Return>', self.push_enter)
            # do not reproduce vim behaviour
            self.root.protocol("WM_DELETE_WINDOW", self.cancel_login)

        def make_entry(self, _, caption, width=None, default='', **options):
            tk.Label(self.parent, text=caption).pack(side=tk.TOP)
            entry = tk.Entry(self.parent, **options)
            if width:
                entry.config(width=width)
            entry.pack(side=tk.TOP, padx=10, fill=tk.BOTH)
            if default:
                entry.insert(0, default)
            return entry

        def push_enter(self, _):
            self.get_value()

        def get_value(self):
            self.ADD = []
            for entry in self.add_entries:
                self.ADD.extend([entry.get()])
            self.root.destroy()
            self.root.quit()

        def cancel_login(self):
            self.ADD = []
            for entry in self.add_entries:
                self.ADD.extend([None])
            self.root.destroy()
            self.root.quit()

    root = tk.Tk()
    toto = Toto(root, title=title, add_fields=add_fields, defaults=defaults)
    root.mainloop()
    return toto.ADD

# from ibllib.misc import login
# a, b =login.login(default_passwd='tutu', default_username='turluser')
# a, b =login.login(default_passwd='tutu', default_username='turluser', title='supertitre')
# a, b, add1, add2 =login.login(default_passwd='tutu', default_username='turluser',
#                               title='supertitre', add_fields=['tuasdf', 'adfasdf'])

# title = 'Recording site'
# fields = ['X (float):', 'Y (float):', 'Z (flaot):', 'D (float):',
#     'Angle (10 or 20):', 'Origin (bregma or lambda):']
# defaults = [None, None, None, None, '10', 'bregma']
# types = [float, float, float, float, int, str]
# bla = multi_input(title=title, add_fields=fields, defaults=defaults)
# try:
#     out = [t(x) for x, t in zip(bla, types)]
# except Exception:
#     bla = multi_input(title=title, add_fields=fields, defaults=defaults)
# print(bla)