# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/results.ipynb (unless otherwise specified).

__all__ = ['rpy2', 'logger', 'ResultsModel', 'ResultsView', 'Results']

# Cell
import pandas as pd
import numpy as np
from traitlets import List, HasTraits

# Cell
from .widget_containers import VBox
from .widgets import Output, Select
from ipywidgets import HBox, Layout
from IPython.core.display import display, clear_output, HTML
from .config import CONFIG, APP_DIR
from .log import HANDLERS
from .rpy import RFunction, R_CONSOLE
rpy2 = R_CONSOLE.rpy2
logger = HANDLERS.getLogger(__name__)

# Cell
class ResultsModel(HasTraits):

    data = List([])

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def addResult(self, result):
        self.data += [dict(result)] #because results is a UserDict


# Cell
# View
class ResultsView(VBox):

    HEADER  = ['ID             ','Name           ','Date                  ','Runtime   ','Input                                    ']

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        header = self.columnize(self.HEADER,[self.HEADER])
        header = Select(options=header,disabled=True,value=None,layout=Layout(height='2em',width='99%'))
        header.add_class('selmono') # See custom CSS

        # Fixed width results selection widet
        self.select = Select(rows=10,options=[],value=None,layout={'width':'99%'})
        self.select.add_class('selmono') # See custom CSS

        self.output = Output()

        #self.style  = HTML('<style> .selmono { font-family: "Lucida Console", Monaco, monospace !important;} </style>')
        #self.children += (self.style, header,self.select,self.output, )
        self.children += (header,self.select,self.output, )

    def columnize(self,guide,data,sep=' '):
        '''Pad or truncate columns in text lines based on guide'''
        rows = []

        for r in range(len(data)):
            row = ''

            for c in range(len(data[r])): # guide)):
                text      = data[r][c]
                col_width = len(guide[c])
                diff      = col_width - len(data[r][c])

                if diff < 0:
                    row += text[:diff]         + sep
                else:
                    row += text + (' ' * diff) + sep

            rows.append(row)

        return rows

# Cell
# Controller
class Results(ResultsView):

    VALUE = 'value' # for observe calls

    def __init__(self, model, **kwargs):
        super().__init__(**kwargs)

        self.model = model
        self.select.observe(self.onSelect,self.VALUE)

    def addResult(self, result):
        self.model.addResult(result)

        # Add to select widget: temporarily suspend callback, update result select w/new data
        self.select.unobserve(self.onSelect,self.VALUE)
        item = [str(result['id']),result['name'],result['date'],
                str(result['runtime']),str(result['kwargs'])]
        item = self.columnize(self.HEADER,[item])[0]  # TODO adjust columnize() to do one-at-a-time
        newOptions = list(self.select.options)
        newOptions.append(tuple([item,result]))
        self.select.options = newOptions
        self.select.value = None
        self.select.observe(self.onSelect,self.VALUE)

    def onSelect(self,change):
        with self.output:
            clear_output(wait=True)
            display(change['owner'].value['df'])
