#!/ef/efabless/opengalaxy/venv/bin/python3
#
#--------------------------------------------------------------------
# Characterization Report Window for the Open Galaxy project manager
#
#--------------------------------------------------------------------
# Written by Tim Edwards
# efabless, inc.
# September 12, 2016
# Version 0.1
#----------------------------------------------------------

import os
import base64
import subprocess

import tkinter
from tkinter import ttk

import tooltip
import cace_makeplot

class FailReport(tkinter.Toplevel):
    """Open Galaxy failure report window."""

    def __init__(self, parent=None, fontsize=11, *args, **kwargs):
        '''See the __init__ for Tkinter.Toplevel.'''
        tkinter.Toplevel.__init__(self, parent, *args, **kwargs)

        s = ttk.Style()
        s.configure('bg.TFrame', background='gray40')
        s.configure('italic.TLabel', font=('Helvetica', fontsize, 'italic'), anchor = 'west')
        s.configure('title.TLabel', font=('Helvetica', fontsize, 'bold italic'),
                        foreground = 'brown', anchor = 'center')
        s.configure('normal.TLabel', font=('Helvetica', fontsize))
        s.configure('red.TLabel', font=('Helvetica', fontsize), foreground = 'red')
        s.configure('green.TLabel', font=('Helvetica', fontsize), foreground = 'green4')
        s.configure('blue.TLabel', font=('Helvetica', fontsize), foreground = 'blue')
        s.configure('brown.TLabel', font=('Helvetica', fontsize, 'italic'),
			foreground = 'brown', anchor = 'center')
        s.configure('normal.TButton', font=('Helvetica', fontsize), border = 3,
			relief = 'raised')
        s.configure('red.TButton', font=('Helvetica', fontsize), foreground = 'red',
			border = 3, relief = 'raised')
        s.configure('green.TButton', font=('Helvetica', fontsize), foreground = 'green4',
			border = 3, relief = 'raised')
        s.configure('title.TButton', font=('Helvetica', fontsize, 'bold italic'),
                        foreground = 'brown', border = 0, relief = 'groove')

        self.withdraw()
        self.title('Open Galaxy Local Characterization Report')
        self.root = parent.root
        self.rowconfigure(0, weight = 1)
        self.columnconfigure(0, weight = 1)

        # Scrolled frame:  Need frame, then canvas and scrollbars;  finally, the
        # actual grid of results gets placed in the canvas.
        self.failframe = ttk.Frame(self)
        self.failframe.grid(column = 0, row = 0, sticky = 'nsew')
        self.mainarea = tkinter.Canvas(self.failframe)
        self.mainarea.grid(row = 0, column = 0, sticky = 'nsew')

        self.mainarea.faildisplay = ttk.Frame(self.mainarea)
        self.mainarea.create_window((0,0), window=self.mainarea.faildisplay,
			anchor="nw", tags="self.frame")

        # Create a frame for displaying plots, but don't put it in the grid.
        # Make it resizeable.
        self.plotframe = ttk.Frame(self)
        self.plotframe.rowconfigure(0, weight = 1)
        self.plotframe.columnconfigure(0, weight = 1)

        # Main window resizes, not the scrollbars
        self.failframe.rowconfigure(0, weight = 1)
        self.failframe.columnconfigure(0, weight = 1)
        # Add scrollbars
        xscrollbar = ttk.Scrollbar(self.failframe, orient = 'horizontal')
        xscrollbar.grid(row = 1, column = 0, sticky = 'nsew')
        yscrollbar = ttk.Scrollbar(self.failframe, orient = 'vertical')
        yscrollbar.grid(row = 0, column = 1, sticky = 'nsew')
        # Attach viewing area to scrollbars
        self.mainarea.config(xscrollcommand = xscrollbar.set)
        xscrollbar.config(command = self.mainarea.xview)
        self.mainarea.config(yscrollcommand = yscrollbar.set)
        yscrollbar.config(command = self.mainarea.yview)
        # Set up configure callback
        self.mainarea.faildisplay.bind("<Configure>", self.frame_configure)

        self.bbar = ttk.Frame(self)
        self.bbar.grid(column = 0, row = 1, sticky = "news")
        self.bbar.close_button = ttk.Button(self.bbar, text='Close',
		command=self.close, style = 'normal.TButton')
        self.bbar.close_button.grid(column=0, row=0, padx = 5)
        # Table button returns to table view but is only displayed for plots.
        self.bbar.table_button = ttk.Button(self.bbar, text='Table', style = 'normal.TButton')

        self.protocol("WM_DELETE_WINDOW", self.close)
        tooltip.ToolTip(self.bbar.close_button,
			text='Close detail view of conditions and results')

        self.sortdir = False
        self.data = []

    def grid_configure(self, padx, pady):
        pass

    def frame_configure(self, event):
        self.update_idletasks()
        self.mainarea.configure(scrollregion=self.mainarea.bbox("all"))

    def check_failure(self, record, calc, value):
        if not 'target' in record:
            return None
        else:
            target = record['target']

        if calc == 'min':
            targval = float(target)
            if value < targval:
                return True
        elif calc == 'max':
            targval = float(target)
            if value > targval:
                return True
        else:
            return None

    # Given an electrical parameter 'param' and a condition name 'condname', find
    # the units of that condition.  If the condition isn't found in the local
    # parameters, then it is searched for in 'globcond'.

    def findunit(self, condname, param, globcond):
        unit = ''
        try:
            loccond = next(item for item in param['conditions'] if item['condition'] == condname)
        except StopIteration:
            try:
                globitem = next(item for item in globcond if item['condition'] == condname)
            except (TypeError, StopIteration):
                unit = ''	# No units
            else:
                if 'unit' in globitem:
                    unit = globitem['unit']
                else:
                    unit = ''	# No units
        else:
            if 'unit' in loccond:
                unit = loccond['unit']
            else:
                unit = ''	# No units
        return unit

    def size_plotreport(self):
        self.update_idletasks()
        width = self.plotframe.winfo_width()
        height = self.plotframe.winfo_height()
        if width < 3 * height:
            self.plotframe.configure(width=height * 3)

    def size_failreport(self):
        # Attempt to set the datasheet viewer width to the interior width
        # but do not set it larger than the available desktop.

        self.update_idletasks()
        width = self.mainarea.faildisplay.winfo_width()
        screen_width = self.root.winfo_screenwidth()
        if width > screen_width - 20:
            self.mainarea.configure(width=screen_width - 20)
        else:
            self.mainarea.configure(width=width)

        # Likewise for the height, up to the desktop height.  Note that this
        # needs to account for both the button bar at the bottom of the GUI
        # window plus the bar at the bottom of the desktop.
        height = self.mainarea.faildisplay.winfo_height()
        screen_height = self.root.winfo_screenheight()
        if height > screen_height - 120:
            self.mainarea.configure(height=screen_height - 120)
        else:
            self.mainarea.configure(height=height)

    def table_to_histogram(self, globcond, filename):
        # Switch from a table view to a histogram plot view, using the
        # result as the X axis variable and count for the Y axis.

        # Destroy existing contents.
        for widget in self.plotframe.winfo_children():
            widget.destroy()

        param = self.data
        plotrec = {}
        plotrec['xaxis'] = param['method']
        plotrec['xlabel'] = param['method']
        plotrec['ylabel'] = 'COUNT'
        plotrec['type'] = 'histogram'
        if 'unit' in param:
            plotrec['xlabel'] += ' (' + param['unit'] + ')'

        results = param['results']

        if 'variables' in param:
            variables = param['variables']
        else:
            variables = []
        # faild = self.mainarea.faildisplay	# definition for convenience
        self.failframe.grid_forget()
        self.plotframe.grid(row = 0, column = 0, sticky = 'nsew')
        canvas = cace_makeplot.makeplot(plotrec, results, variables, parent = self.plotframe)
        if 'display' in param:
            ttk.Label(self.plotframe, text=param['display'], style='title.TLabel').grid(row=1, column=0)
        canvas.show()
        canvas.get_tk_widget().grid(row=0, column=0, sticky = 'nsew')
        # Finally, open the window if it was not already open.
        self.open()

    def table_to_plot(self, condition, globcond, filename):
        # Switch from a table view to a plot view, using the condname as
        # the X axis variable.

        # Destroy existing contents.
        for widget in self.plotframe.winfo_children():
            widget.destroy()

        param = self.data
        plotrec = {}
        plotrec['xaxis'] = condition
        plotrec['xlabel'] = condition
        # Note: cace_makeplot adds text for units, if available
        plotrec['ylabel'] = param['method']
        plotrec['type'] = 'xyplot'

        results = param['results']

        if 'variables' in param:
            variables = param['variables']
        else:
            variables = []

        # faild = self.mainarea.faildisplay	# definition for convenience
        self.failframe.grid_forget()
        self.plotframe.grid(row = 0, column = 0, sticky = 'nsew')
        canvas = cace_makeplot.makeplot(plotrec, results, variables, parent = self.plotframe)
        if 'display' in param:
            ttk.Label(self.plotframe, text=param['display'], style='title.TLabel').grid(row=1, column=0)
        canvas.show()
        canvas.get_tk_widget().grid(row=0, column=0, sticky = 'nsew')
        # Display the button to return to the table view
        # except for transient and Monte Carlo simulations which are too large to tabulate.
        if not condition == 'TIME':
            self.bbar.table_button.grid(column=1, row=0, padx = 5)
            self.bbar.table_button.configure(command=lambda param=param, globcond=globcond,
			filename=filename: self.display(param, globcond, filename))

        # Finally, open the window if it was not already open.
        self.open()

    def display(self, param=None, globcond=None, filename=None):
        # (Diagnostic)
        # print('failure report:  passed parameter ' + str(param))

        # Destroy existing contents.
        for widget in self.mainarea.faildisplay.winfo_children():
            widget.destroy()

        if not param:
            param = self.data

        # 'param' is a dictionary pulled in from the annotate datasheet.
        # If the failure display was called, then 'param' should contain
        # record called 'results'.  If the parameter has no results, then
        # there is nothing to do.

        if filename and 'plot' in param:
            simfiles = os.path.split(filename)[0] + '/ngspice/char/simulation_files/'
            self.failframe.grid_forget()
            self.plotframe.grid(row = 0, column = 0, sticky = 'nsew')

            # Clear the plotframe and remake
            for widget in self.plotframe.winfo_children():
                widget.destroy()

            plotrec = param['plot']
            results = param['results']
            if 'variables' in param:
                variables = param['variables']
            else:
                variables = []
            canvas = cace_makeplot.makeplot(plotrec, results, variables, parent = self.plotframe)
            if 'display' in param:
                ttk.Label(self.plotframe, text=param['display'],
				style='title.TLabel').grid(row=1, column=0)
            canvas.show()
            canvas.get_tk_widget().grid(row=0, column=0, sticky = 'nsew')
            self.data = param
            # Display the button to return to the table view
            self.bbar.table_button.grid(column=1, row=0, padx = 5)
            self.bbar.table_button.configure(command=lambda param=param, globcond=globcond,
			filename=filename: self.display(param, globcond, filename))

        elif not 'results' in param:
            print("No results to build a report with.")
            return

        else:
            self.data = param
            self.plotframe.grid_forget()
            self.failframe.grid(column = 0, row = 0, sticky = 'nsew')
            faild = self.mainarea.faildisplay	# definition for convenience
            results = param['results']
            names = results[0]
            units = results[1]
            results = results[2:]

            # Check for transient simulation
            if 'TIME' in names:
                # Transient data are (usually) too numerous to tabulate, so go straight to plot
                self.table_to_plot('TIME', globcond, filename)
                return

            # Check for Monte Carlo simulation
            if 'ITERATIONS' in names:
                # Monte Carlo data are too numerous to tabulate, so go straight to plot
                self.table_to_histogram(globcond, filename)
                return

            # Numerically sort by result (to be done:  sort according to up/down
            # criteria, which will be retained per header entry)
            results.sort(key = lambda row: float(row[0]), reverse = self.sortdir)

            # To get ranges, transpose the results matrix, then make unique
            ranges = list(map(list, zip(*results)))
            for r, vrange in enumerate(ranges):
                try:
                    vmin = min(float(v) for v in vrange)
                    vmax = max(float(v) for v in vrange)
                    if vmin == vmax:
                        ranges[r] = [str(vmin)]
                    else:
                        ranges[r] = [str(vmin), str(vmax)]
                except ValueError:
                    ranges[r] = list(set(vrange))
                    pass

            faild.titlebar = ttk.Frame(faild)
            faild.titlebar.grid(row = 0, column = 0, sticky = 'ewns')

            faild.titlebar.label1 = ttk.Label(faild.titlebar, text = 'Electrical Parameter: ',
			style = 'italic.TLabel')
            faild.titlebar.label1.pack(side = 'left', padx = 6, ipadx = 3)
            if 'display' in param:
                faild.titlebar.label2 = ttk.Label(faild.titlebar, text = param['display'],
			style = 'normal.TLabel')
                faild.titlebar.label2.pack(side = 'left', padx = 6, ipadx = 3)
                faild.titlebar.label3 = ttk.Label(faild.titlebar, text = '  Method: ',
			style = 'italic.TLabel')
                faild.titlebar.label3.pack(side = 'left', padx = 6, ipadx = 3)
            faild.titlebar.label4 = ttk.Label(faild.titlebar, text = param['method'],
			style = 'normal.TLabel')
            faild.titlebar.label4.pack(side = 'left', padx = 6, ipadx = 3)

            if 'min' in param:
                if 'target' in param['min']:
                    faild.titlebar.label7 = ttk.Label(faild.titlebar, text = '  Min Limit: ',
			style = 'italic.TLabel')
                    faild.titlebar.label7.pack(side = 'left', padx = 3, ipadx = 3)
                    faild.titlebar.label8 = ttk.Label(faild.titlebar, text = param['min']['target'],
    			style = 'normal.TLabel')
                    faild.titlebar.label8.pack(side = 'left', padx = 6, ipadx = 3)
                    if 'unit' in param:
                        faild.titlebar.label9 = ttk.Label(faild.titlebar, text = param['unit'],
				style = 'italic.TLabel')
                        faild.titlebar.label9.pack(side = 'left', padx = 3, ipadx = 3)
            if 'max' in param:
                if 'target' in param['max']:
                    faild.titlebar.label10 = ttk.Label(faild.titlebar, text = '  Max Limit: ',
			style = 'italic.TLabel')
                    faild.titlebar.label10.pack(side = 'left', padx = 6, ipadx = 3)
                    faild.titlebar.label11 = ttk.Label(faild.titlebar, text = param['max']['target'],
    			style = 'normal.TLabel')
                    faild.titlebar.label11.pack(side = 'left', padx = 6, ipadx = 3)
                    if 'unit' in param:
                        faild.titlebar.label12 = ttk.Label(faild.titlebar, text = param['unit'],
	    			style = 'italic.TLabel')
                        faild.titlebar.label12.pack(side = 'left', padx = 3, ipadx = 3)

            # Simplify view by removing constant values from the table and just listing them
            # on the second line.

            faild.constants = ttk.Frame(faild)
            faild.constants.grid(row = 1, column = 0, sticky = 'ewns')
            faild.constants.title = ttk.Label(faild.constants, text = 'Constant Conditions: ',
			style = 'italic.TLabel')
            faild.constants.title.grid(row = 0, column = 0, padx = 6, ipadx = 3)
            j = 0
            for condname, unit, range in zip(names, units, ranges):
                if len(range) == 1:
                    labtext = condname
                    # unit = self.findunit(condname, param, globcond)
                    labtext += ' = ' + range[0] + ' ' + unit + ' '
                    row = int(j / 3)
                    col = 1 + (j % 3)
                    ttk.Label(faild.constants, text = labtext,
				style = 'blue.TLabel').grid(row = row,
				column = col, padx = 6, sticky = 'nsew')
                    j += 1

            body = ttk.Frame(faild, style = 'bg.TFrame')
            body.grid(row = 2, column = 0, sticky = 'ewns')

            # Print out names
            j = 0
            for condname, unit, range in zip(names, units, ranges):
                # Now find the range for each entry from the global and local conditions.
                # Use local conditions if specified, otherwise default to global condition.
                # Each result is a list of three numbers for min, typ, and max.  List
                # entries may be left unfilled.

                if len(range) == 1:
                    continue
    
                labtext = condname
                plottext = condname
                if j == 0:
                    # Add unicode arrow up/down depending on sort direction
                    labtext += ' \u21e9' if self.sortdir else ' \u21e7'
                    header = ttk.Button(body, text=labtext, style = 'title.TButton',
				command = self.changesort)
                    tooltip.ToolTip(header, text='Reverse order of results')
                else:
                    header = ttk.Button(body, text=labtext, style = 'title.TLabel',
				command = lambda plottext=plottext, globcond=globcond,
				filename=filename: self.table_to_plot(plottext, globcond, filename))
                    tooltip.ToolTip(header, text='Plot results with this condition on the X axis')
                header.grid(row = 0, column = j, sticky = 'ewns')

                # Second row is the measurement unit
                # if j == 0:
                #     # Measurement unit of result in first column
                #     if 'unit' in param:
                #         unit = param['unit']
                #     else:
                #         unit = ''    # No units
                # else:
                #     # Measurement unit of condition in other columns
                #     # Find condition in local conditions else global conditions
                #     unit = self.findunit(condname, param, globcond)

                unitlabel = ttk.Label(body, text=unit, style = 'brown.TLabel')
                unitlabel.grid(row = 1, column = j, sticky = 'ewns')

                # (Pick up limits when all entries have been processed---see below)
                j += 1

            # Now list entries for each failure record.  These should all be in the
            # same order.
            m = 2
            for result in results:
                m += 1
                j = 0
                condition = result[0]
                lstyle = 'normal.TLabel'
                value = float(condition)
                if 'min' in param:
                    minrec = param['min']
                    if 'calc' in minrec:
                        calc = minrec['calc']
                    else:
                        calc = 'min'
                    if self.check_failure(minrec, calc, value):
                        lstyle = 'red.TLabel'
                if 'max' in param:
                    maxrec = param['max']
                    if 'calc' in maxrec:
                        calc = maxrec['calc']
                    else:
                        calc = 'max'
                    if self.check_failure(maxrec, calc, value):
                        lstyle = 'red.TLabel'

                for condition, range in zip(result, ranges):
                    if len(range) > 1:
                        pname = ttk.Label(body, text=condition, style = lstyle)
                        pname.grid(row = m, column = j, sticky = 'ewns')
                        j += 1

            # Row 2 contains the ranges of each column
            j = 1
            k = 1
            for vrange in ranges[1:]:
                if len(vrange) > 1:

                    condlimits = '( '
                
                    # This is a bit of a hack;  results are assumed floating-point
                    # unless they can't be resolved as a number.  So numerical values
                    # that should be treated as integers or strings must be handled
                    # here according to the condition type.
                    if names[k].split(':')[0] == 'DIGITAL':
                        for l in vrange:
                            condlimits += str(int(float(l))) + ' '
                    else:
                        for l in vrange:
                            condlimits += l + ' '
                    condlimits += ')'
                    header = ttk.Label(body, text=condlimits, style = 'blue.TLabel')
                    header.grid(row = 2, column = j, sticky = 'ewns')
                    j += 1
                k += 1

            # Add padding around widgets in the body of the failure report, so that
            # the frame background comes through, making a grid.
            for child in body.winfo_children():
                child.grid_configure(ipadx = 5, ipady = 1, padx = 2, pady = 2)

            # Resize the window to fit in the display, if necessary.
            self.size_failreport()

        # Don't put the button at the bottom to return to table view.
        self.bbar.table_button.grid_forget()
        # Finally, open the window if it was not already open.
        self.open()

    def changesort(self):
        self.sortdir = False if self.sortdir == True else True
        self.display(param=None)

    def close(self):
        # pop down failure report window
        self.withdraw()

    def open(self):
        # pop up failure report window
        self.deiconify()
        self.lift()
