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

__all__ = ['Node', 'MainView', 'Main']

# Cell
from IPython.display import display, Javascript, HTML
import json
import traitlets
from traitlets import HasTraits, Int, Unicode, observe
import ipywidgets as ipyw
from IPython import get_ipython

# Cell
from .widgets import IntSlider, Button, Dropdown, FloatText, RadioButtons, Output
from .widget_containers import Tab, SelectionVBox, VBox, Box, Accordion
from .views.tabs import LandingTab, EstimatesTab, ResultsTab, SettingsTab
from .models.chisq import *
from .views.chisq import *
from .models.corr import *
from .views.corr import *
from .models.anova import *
from .views.anova import *
from .models.ttest import *
from .views.ttest import *
from .results import ResultsModel, Results
from .settings import SettingsModel, Settings
from superpower_gui import log
from .config import CONFIG

# Cell
class Node:

    decisionWidgets = ipyw.VBox()
    landingWidgets = ipyw.Box()
    view = ipyw.VBox(children = (decisionWidgets, landingWidgets))

    ''' builds a decision tree where all children are either Models or Widgets'''
    def __init__(self, key, label, widget=None, model=None, landing=None, Estimates=None):
        if key == 'head':
            self.decisionWidgets.children = ()
            self.landingWidgets.children = ()
        self.children = {}
        self.selected = None
        self.widget = widget
        if self.widget:
            self.widget.observe(self.observeChange, names='value')
            self.decisionWidgets.children += (self.widget,)
        self.key = key
        self.label = label
        self.model = model
        self.landing = landing
        self.Estimates = Estimates

    def __getattr__(self, attr):
        return self.children[attr]

    def addModel(self, key, label, model, Landing, Estimates):
        if Landing:
            landing = Landing(model)
        else:
            landing = Output() # a "blank" widget
        self.children[key] = Node(key, label, model=model, landing=landing, Estimates=Estimates)
        self.selected = key

    def addWidget(self, key, label, widget):
        self.children[key] = Node(key, label, widget)

    def select(self, key):
        if key in self.children.keys():
            self.selected = key

    def getModel(self):
        child = self.children[self.selected]
        if child.model:
            return child
        else:
            return child.getModel()

    def observeChange(self, change):
        self.selected = change['new']
        self.showWidgets()
        self.landingWidgets.children = (self.getModel().landing, )

    def showWidgets(self):
        for key, child in self.children.items():
            if key == self.selected:
                if child.widget:
                    child.widget.show()
                child.showWidgets()
            else:
                if child.widget:
                    child.widget.hide()
                child.hideWidgets()

    def hideWidgets(self):
        for key, child in self.children.items():
            if child.widget:
                child.widget.hide()
            child.hideWidgets()

    def addOptions(self):
        for key, child in self.children.items():
            if self.widget:
                self.widget.options = [(child.label, key) for key, child in self.children.items()]
            child.addOptions()

    def getWidgetList(self, wlist):
        if self.widget:
            self.widget.options = [(child.label, key) for key, child in self.children.items()]
            wlist += [self.widget]
        for key, child in self.children.items():
            wlist = child.getWidgetList(wlist)
        return wlist

    def init(self):
        self.addOptions()
        self.showWidgets()
        self.landingWidgets.children = (self.getModel().landing, )

# Cell
class MainView(ipyw.Tab):

    TAB_TITLES = ('Landing', 'Estimates', 'Results', 'Settings')

    def __init__(self, **kwargs):
        super().__init__(layout=ipyw.Layout(height='100%'), **kwargs)

        # landing tab
        self.tree = Node('head', 'Model Class', Dropdown(description='Model Class', layout=ipyw.Layout(max_width='300px', description_width='80px')))
        self.tree.addWidget('corr', 'Correlation', Dropdown(description='Coefficient', layout=ipyw.Layout(max_width='350px',description_width='100px')))
        self.tree.addWidget('ttest', 'T-Test', Dropdown(description='Model'))
        self.tree.ttest.addWidget('paired', 'Paired Sample T-Test', RadioButtons())

        self.proceedButton = Button(description='Proceed', button_style='success')
        self.landingTab = ipyw.VBox(children = (self.tree.view, self.proceedButton, ))

        # estimates tab
        self.estimatesBox = ipyw.Box()
        self.calculateButton = Button(description='Calculate', button_style='success')
        self.estimatesTab = ipyw.VBox(children = (self.estimatesBox, self.calculateButton))

        # results tab
        self.results = Results()
        self.repopLandingButton = Button(description='Repopulate Model', layout=ipyw.Layout(width='180px'))
        self.repopEstimatesButton = Button(description='Repopulate Estimates', layout=ipyw.Layout(width='200px'))
        buttonBox = ipyw.HBox(children=(self.repopLandingButton, self.repopEstimatesButton))
        self.resultsTab = ipyw.VBox(children=(self.results, buttonBox))

        # settings tab
        self.settingsTab = Settings()

        # main
        self.children = (self.landingTab, self.estimatesTab, self.resultsTab, self.settingsTab)
        for i, title in enumerate(self.TAB_TITLES):
            self.set_title(i, title)

# Cell
class Main(MainView):

    def __init__(self):
        super().__init__()

        # models
        self.models = {}
        self.models['chisq'] = ChiSqModel()
        self.models['anova'] = ANOVAModel()
        self.models['tetra'] = TetraModel()
        self.models['cramerv'] = CramerVModel()
        self.models['pears'] = PearsonModel()
        self.models['spear'] = SpearmansRhoModel()
        self.models['point'] = PBiModel()
        self.models['single'] = SingleSampleModel()
        self.models['ind'] = IndependentSamplesModel()
        self.models['pair'] = PairedSamplesModel()
        self.models['diff'] = DiffPairedSamplesModel()
        self.models['results'] = ResultsModel()
        self.models['settings'] = SettingsModel()

        # views
        self.tree.addModel('chisq', 'Chi Squared', self.models['chisq'], ChiSqLanding, ChiSq)
        self.tree.addModel('anova', 'Analysis of Variance', self.models['anova'], ANOVALanding, ANOVAEstimates)
        self.tree.corr.addModel('tetra', 'Tetrachoric', self.models['tetra'], TetraLanding, Tetra)
        self.tree.corr.addModel('cramerv', "Cramer's V", self.models['cramerv'], CramerVLanding, CramerV)
        self.tree.corr.addModel('pears', "Pearson's Correlation Coefficient", self.models['pears'], PearsonLanding, Pearson)
        self.tree.corr.addModel('spear', "Spearman's Rho", self.models['spear'], SpearmansRhoLanding, SpearmansRho)
        self.tree.corr.addModel('point', "Point Biserial", self.models['point'], PBiLanding, PBi)
        self.tree.ttest.addModel('single', 'One Sample T-Test', self.models['single'], None , SingleSample)
        self.tree.ttest.addModel('ind', 'Independent Samples T-Test', self.models['ind'], TTestLanding, IndependentSamples)
        self.tree.ttest.paired.addModel('diff', 'From Mean difference and SD of difference', self.models['diff'], None, DiffPairedSamples)
        self.tree.ttest.paired.addModel('pair', 'From Means and Standard Deviations', self.models['pair'], None, PairedSamples)
        self.tree.init()

        self.results.introModel(self.models['results'])
        self.settingsTab.introModel(self.models['settings'])

        # observe
        self.proceedButton.on_click(self.proceed)
        self.calculateButton.on_click(self.calculate)
        self.repopLandingButton.on_click(self.repopulateLanding)
        self.repopEstimatesButton.on_click(self.repopulateEstimates)

    def proceed(self, button):
        self.model = self.tree.getModel()
        self.model.model.setEstimates()
        self.estimatesBox.children = (self.model.Estimates(self.model.model), )
        self.selected_index = 1

    def calculate(self, button):
        self.updateModelWithSettings()
        result = self.model.model.run()
        if result:
            self.results.addResult(result)
            self.selected_index = 2

    def updateModelWithSettings(self):
        if self.model.key in ('chisq','tetra', 'cramerv'):
            self.model.model.pVal = self.models['settings'].alpha
            self.model.model.tail = self.models['settings'].tail
        else:
            self.model.model.setTraits(**self.models['settings'].getTraits())

    def repopulateLanding(self, button):
        self.selected_index = 0

    def repopulateEstimates(self, button):
        self.selected_index = 1