# Source code for ui

    '''
    Miscellaneous user interface utilities for

        - getting the screen size
        - selecting files or directories.
          If nothing or a non-existing file/direcoty is selected, the return is "0".
          Otherwise the file/directory is returned.
        - Selection from a list.
        - waitbar
        - listbox

    '''

    '''
    ThH, April 2016
    Ver 5.6
    '''

    import matplotlib.pyplot as plt
    import os
    import sys

    if sys.version_info.major == 3:
        # Python 3.x
        import tkinter as tk
        import tkinter.filedialog as tkf
    else:
        # Python 2.x
        import Tkinter as tk
        import tkFileDialog as tkf

    def get_screensize():
        '''
        Get the height and width of the screen.

        Parameters
        ----------
            None

        Returns
        -------
        width :  int
            width of the current screen
        height:  int
            height of the current screen

        Examples
        --------
        >>> (width, height) = thLib.ui.get_screensize()
        '''

        try:
            # Use the methods form PyQt first, since tk gave me some strange error messages sometimes
            from PyQt4 import QtGui
            import sys

            MyApp = QtGui.QApplication(sys.argv)
            V = MyApp.desktop().screenGeometry()
            screen_h = V.height()
            screen_w = V.width()

        except ImportError:
            # If PyQt4 is not available
            root = tk.Tk()
            (screen_w, screen_h) = (root.winfo_screenwidth(), root.winfo_screenheight())
            root.destroy()

        return (screen_w, screen_h)

    def getfile(FilterSpec='*', DialogTitle='Select File: ', DefaultName=''):
        '''
        Selecting an existing file.

        Parameters
        ----------
        FilterSpec : query-string
            File filters
        DialogTitle : string
            Window title
        DefaultName : string
            Can be a directory AND filename

        Returns
        -------
        filename :  string
            selected existing file, or empty string if nothing is selected
        pathname:   string
            selected path, or empty string if nothing is selected

        Examples
        --------
        >>> (myFile, myPath) = thLib.ui.getfile('*.py', 'Testing file-selection', 'c:\\temp\\test.py')

        '''

        root = tk.Tk()
        root.withdraw()
        fullInFile = tkf.askopenfilename(initialfile=DefaultName,
                title=DialogTitle, filetypes=[('Select', FilterSpec),
                                              ('all files','*')])

        # Close the Tk-window manager again
        root.destroy()

        if not os.path.exists(fullInFile):
            return (0, 0)
        else:
            print('Selection: ' + fullInFile)
            dirName = os.path.dirname(fullInFile)
            fileName = os.path.basename(fullInFile)
            return (fileName, dirName)

    def savefile(FilterSpec='*',DialogTitle='Save File: ', DefaultName=''):
        '''
        Selecting an existing or new file:

        Parameters
        ----------
        FilterSpec : string
            File filters.
        DialogTitle : string
            Window title.
        DefaultName : string
            Can be a directory AND filename.

        Returns
        -------
        filename : string
            Selected file.
        pathname : string
            Selecte path.

        Examples
        --------
        >>> (myFile, myPath) = thLib.ui.savefile('*.py', 'Testing file-selection', 'c:\\temp\\test.py')

        '''

        root = tk.Tk()
        root.withdraw()
        outFile = tkf.asksaveasfile(mode='w', title=DialogTitle, initialfile=DefaultName, filetypes=[('Save as', FilterSpec)])

        # Close the Tk-window manager again
        root.destroy()

        if outFile == None:
            (fileName, dirName) = ('','')
        else:
            fullOutFile = outFile.name
            print('Selection: ' + fullOutFile)
            dirName = os.path.dirname(fullOutFile)
            fileName = os.path.basename(fullOutFile)

        return (fileName, dirName)

    def getdir(DialogTitle='Select Directory', DefaultName='.'):
        ''' Select a directory

        Parameters
        ----------
        DialogTitle : string
            Window title
        DefaultName : string
            Can be a directory AND filename

        Returns
        -------
        directory : string
            Selected directory, or empty string if nothing is selected.

        Examples
        --------
        >>> myDir = thLib.ui.getdir('c:\\temp', 'Pick your directory')

        '''

        root = tk.Tk()
        root.withdraw()
        fullDir = tkf.askdirectory(initialdir=DefaultName, title=DialogTitle)

        # Close the Tk-window manager again
        root.destroy()

        if not os.path.exists(fullDir):
            return ''
        else:
            print('Selection: ' + fullDir)
            return fullDir

    def progressbar(it, prefix = "", size = 60):
        '''
        Shows a progress-bar on the commandline.
        This has the advantage that you don't need to bother with windows
        managers. Nifty coding!

        Parameters
        ----------
        it : integer array
            index variable
        prefix : string
            Text preceding the progress-bar
        size : integer
            Length of progress-bar

        Examples
        --------
        >>> import time
        >>> for ii in progressbar(range(50), 'Computing ', 25):
        >>>    #print(ii)
        >>>    time.sleep(0.05)

        '''

        count = len(it)
        def _show(_i):
            # Helper function to print the desired information line.

            x = int(size*_i/count)
            sys.stdout.write("%s[%s%s] %i/%i\r" % (prefix, "#"*x, "."*(size-x), _i, count))
    #        sys.stdout.flush()

        _show(0)
        for i, item in enumerate(it):
            yield item
            _show(i+1)
        sys.stdout.write("\n")
        sys.stdout.flush()

    def listbox(items):
        '''GUI for a listbox selection

        Parameters
        ----------
        items : list
            Items for selection.
        frame : tkinter Frame
            If provided, the list is put in the given frame. Otherwise, a new frame is created.

        Returns
        -------
        selected : string
            Selected item.
            If no selection is made, and empty string ('') is returned.

        Examples
        --------
        >>> selData = thLib.ui.listbox(['Peter', 'Paul', 'Mary'])

        '''

        class Variables():
            """Class for the GUI-display of the items provided"""

            def __init__(self, master, items):
                self.master = master
                self.frame = tk.Frame(master)
                #tk.Frame.__init__(self, frame)
                self.frame.grid()
                self.createWidgets(items)

            def selectAndQuit(self):
                '''Grab the selected item, and close the GUI'''
                try:
                    self.selected = self.items[int(self.listbox.curselection()[0])]
                except IndexError:
                    # No selection made
                    self.selected = ''
                self.master.destroy()

            def quitFun(self):
                self.selected = ''
                self.master.destroy()

            def createWidgets(self, items):
                '''Create the List, and the Quit-button'''

                self.listbox = tk.Listbox(self.frame, name='varSelection', font=('times',13))

                # Populate the list with the items provided
                self.items = items
                for item in items:
                    self.listbox.insert(tk.END,item)

                # Place it on the grid
                self.listbox.grid(row=0, columnspan=2)

                # Create and place the Quit-button
                self.quitButton = tk.Button(self.frame, text='Select', command=self.selectAndQuit)
                self.quitButton.grid(row=1, column=0)
                self.quitButton = tk.Button(self.frame, text='Quit', command=self.quitFun)
                self.quitButton.grid(row=1, column=1)

        # Run the GUI:
        root = tk.Tk()
        app = Variables(root, items)
        root.mainloop()

        # Grab the selected value
        returnVal = app.selected

        return returnVal

    if __name__ == "__main__":
        # Test functions

        width, height = get_screensize()
        print('Your screen is {0} x {1} pixels.'.format(width, height))

        '''
        import time
        for ii in progressbar(range(50), 'Computing ', 25):
            #print(ii)
            time.sleep(0.05)

        (myFile, myPath) = getfile('*.eps', 'Testing file-selection', r'c:\temp\test.eps')
        if myFile == 0:
            print(0)
        else:
            print('File: %s, Path: %s' % (myFile, myPath))
        (myFile, myPath) = savefile('*.txt', 'Testing saving-selection', r'c:\temp\test.txt')

        myDir = getdir()
        print(myDir)

        items = ['Peter', 'Paul', 'Mary']
        selected = listbox(items*4)
        if selected == '':
            print('No selection made.')
        else:
            print('You have selected {0}'.format(selected))

        import numpy as np
        import pandas as pd
        x = np.arange(5)
        y = np.random.randn(5,3)
        s = pd.Series(x)
        df = pd.DataFrame(y)
        z = 'abc'

        selVal, selName = selectPlotVar(sys._getframe())
        #selected = selectPlotVar()
        curFrame = sys._getframe()
        varList = curFrame.f_locals.keys()
        ndList = [var for var in varList if type(curFrame.f_locals[var])==np.ndarray]
        dfList = [var for var in varList if type(curFrame.f_locals[var])==pd.core.frame.DataFrame]
        seriesList = [var for var in varList if type(curFrame.f_locals[var])==pd.core.series.Series]
        fullList = ndList+dfList+seriesList

        selected = listbox(fullList)

        print(selName)
        print(selVal)

        root = tk.Tk()
        app = Demo1(root, sys._getframe())
        root.mainloop()

        '''