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

__all__ = ['Selection', 'Controller']

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

# Cell
from .widgets import IntSlider, Button, Dropdown, FloatText
from .widget_containers import Tab, SelectionVBox, VBox, Box, Accordion
from .views.tabs import LandingTab, EstimatesTab, ResultsTab, SettingsTab
from .log import HANDLERS
from .models.chisq import *
from .views.chisq import *
from .models.corr import *
from .views.corr import *
from .results import ResultsModel, Results
from .settings import SettingsModel, Settings
from .rpy import R_CONSOLE

# Cell
from collections import namedtuple
Selection = namedtuple('Selection', ['label', 'LandingModel', 'Model', 'Landing', 'Estimates'])

# Cell
class Controller(traitlets.HasTraits):

    modelName = Unicode()
    corrModelName = Unicode()

    def __init__(self):

        ''' log handlers'''
        self.logger = HANDLERS.getLogger(__name__)
        self.logger.info('Autosave off.')
        display(Javascript('Jupyter.notebook.set_autosave_interval(0);'))
        self.handlerWidget = HANDLERS.handlers['widget']
        HANDLERS.loadCSS()

        ''' create views and models '''
        self.create_global_widgets()
        self.define_box_selections()
        self.initialize_mvcs()
        self.view = self.tab_based_view()
        self.add_observations()

        ''' initialize '''
        self.corrDropdown.value = 'cramerv'
        self.dropdown.value = 'chisq'


    def _ipython_display_(self):
        display(self.view)

    def create_global_widgets(self):

        ''' landing '''
        self.corrDropdown = Dropdown(description='Coefficient: ',
            layout=ipyw.Layout(max_width='350px',description_width='100px'))
        self.corrSelection = SelectionVBox()
        self.corrBox = VBox(children=(self.corrDropdown, self.corrSelection))

        self.landingSelection = SelectionVBox()
        self.dropdownOptions = [('Correlation', 'corr')] # populated in self.initialize_view_and_models
        self.dropdown = Dropdown( options=self.dropdownOptions, description='Model Class: ',
                layout=ipyw.Layout(max_width='300px', description_width='80px'))

        self.okayButton = Button(description='Okay', button_style='success')

        ''' estimates '''
        self.estimatesBox = Box()
        self.runButton = Button(description='Run', button_style='success')
        self.restartButton = Button(description='Restart')

        ''' results '''
        self.repopulateLanding = Button(description='Repopulate Model Tab')
        self.repopulateEstimates = Button(description='Repopulate Estimates Tab')

        ''' settings '''
        self.logAccordion = Accordion(children=(self.handlerWidget, ))

    def define_box_selections(self):

        self.options = {}
        self.options['chisq'] = Selection('Chi Squared', ChiSqLandingModel, ChiSqModel, ChiSqLanding, ChiSq)

        self.corrOptions = {}
        self.corrOptions['tetra'] = Selection('Tetrachoric', TetraLandingModel, TetraModel, TetraLanding, Tetra)
        self.corrOptions['cramerv'] = Selection("Cramer's V", CramerVLandingModel, CramerVModel, CramerVLanding, CramerV)
        self.corrOptions['pears'] = Selection("Pearson's Correlation Coefficient", CorrLandingModel, PearsonModel, PearsonLanding, Pearson)
        self.corrOptions['spear'] = Selection("Spearman's Rho", CorrLandingModel, SpearmansRhoModel, SpearmansRhoLanding, SpearmansRho)
        self.corrOptions['point'] = Selection("Point Biserial", CorrLandingModel, PBiModel, PBiLanding, PBi)

    def initialize_single_mvc(self, options, selection, dropdown):
        for name, option in options.items():
            label, LandingModel, Model, Landing, Estimates = option
            landingModel = LandingModel()
            self.landingModels[name] = landingModel
            self.Model[name] = Model
            dropdown.options += ((label, name), )
            selection.add_child(Landing(landingModel), name)
            self.Estimates[name] = Estimates

    def initialize_mvcs(self):

        ''' selectable boxes in landing '''
        self.Model = {}
        self.Estimates = {}
        self.landingModels = {}
        self.initialize_single_mvc(self.options, self.landingSelection, self.dropdown)

        self.corrLandingModels = {}
        self.initialize_single_mvc(self.corrOptions, self.corrSelection, self.corrDropdown)
        self.landingSelection.add_child(self.corrBox, 'corr')

        '''other mvcs'''
        self.resultsModel = ResultsModel()
        self.settingsModel = SettingsModel()

        self.resultsView = Results(self.resultsModel)
        self.settingsView = Settings(self.settingsModel)

    def tab_based_view(self):
        landingTab = LandingTab(self.dropdown, self.landingSelection, self.okayButton, name='Model')
        estimatesTab = EstimatesTab(self.estimatesBox, self.runButton, name='Estimates')
        resultsTab = ResultsTab(self.restartButton, self.repopulateLanding, self.repopulateEstimates, self.resultsView, name='Results')
        settingsTab = SettingsTab(self.settingsView, self.logAccordion, name='Settings')
        return Tab(children=(landingTab, estimatesTab, resultsTab, settingsTab))

    def add_observations(self):
        self.okayButton.on_click(self.on_okayButton_click)
        self.runButton.on_click(self.on_runButton_click)
        self.restartButton.on_click(self.on_restartButton_click)
        self.repopulateLanding.on_click(self.on_repopulateLanding_click)
        self.repopulateEstimates.on_click(self.on_repopulateEstimates_click)

        self.dropdown.observe(self.on_dropdown_change, names='value')
        self.corrDropdown.observe(self.on_corrDropdown_change, names='value')

    def on_dropdown_change(self, change):
        if change['new'] == 'corr':
            self.modelName = self.corrDropdown.value
            self.landingSelection.selected_name = 'corr'
        else:
            self.modelName = change['new']
            self.landingSelection.selected_name = self.modelName

    def on_corrDropdown_change(self, change):
        self.corrSelection.selected_name = change['new']
        self.modelName = change['new']

    ''' on button click'''
    def on_okayButton_click(self, button):
        model = self.Model[self.modelName](**self.landingModels[self.modelName].getTraits())
        model.setEstimates()
        self.estimates = self.Estimates[self.modelName](model, name=self.modelName)
        self.estimatesBox.children = (self.estimates, )
        self.view.selected_name = 'Estimates'

    def on_runButton_click(self, button):
        self.update_model_with_settings()
        result = self.estimates.run()
        if result:
            self.resultsView.addResult(result)
            self.view.selected_name='Results'

    def on_restartButton_click(self, button):
        if self.modelName == 'corr':
            self.corrSelection[self.corrModelName].setLanding()
        else:
            self.landingSelection[self.modelName].setLanding()
        self.view.selected_name= 'Model'

    def on_repopulateLanding_click(self, button):
        self.view.selected_name = 'Model'

    def on_repopulateEstimates_click(self, button):
        self.view.selected_name = 'Estimates'

    def update_model_with_settings(self):
        if self.modelName in ('chisq','tetra', 'cramerv'):
            self.estimates.model.pVal = self.settingsModel.alpha
            self.estimates.model.tail = self.settingsModel.tail
        else:
            self.estimates.model.setTraits(**self.settingsModel.getTraits())