import numpy as np
from UtilsRPE.Functions import load_vault
# New beggining
# from vaultGenerator import *
#from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.models.widgets import Dropdown, PreText, TextInput

def vault_widget(vault_path):
   
   def var_description(variable):
       description = "ID:\t%20i\nName:\t%20s\nType:\t%20s\nDimensions:\t%10i\n" % \
                     (variable.id, variable.name, variable.type, variable.dimension)
       return description
   
   
   def module_handler(attr, old, new):
       modules.label = new
       module = selected_module()
       set_routine_labels(module)
   
   
   def routine_handler(attr, old, new):
       routines.label = new
       routine = selected_routine()
       set_variable_labels(routine)
   
   
   def variable_handler(attr, old, new):
       variables.label = new
       variable = selected_variable()
       variable_description.text = var_description(variable)
       if variable.type == "rpe_var":
           variable_precision.value = str(variable.precision)
           variable_precision.disabled = False
       else:
           variable_precision.value = "-------"
           variable_precision.disabled = True
   
   
   def text_input_handler(attr, old, new):
       variable = selected_variable()
       if variable is not None:
           try:
               prec = int(new)
               variable.precision = prec
           except ValueError:
               return
   
   
   def id_selector_handler(attr, old, new):
       try:
           var_id = int(new)
       except ValueError:
           return
       variable = v.get_variable_by_id(var_id)
       if variable is not None:
           select_variable(variable)
   
   
   def selected_module():
       try:
           index = [i[0] == modules.value for i in modules.menu].index(True)
       except ValueError:
           return None
       module = v.modules[index]
       return module
   
   
   def selected_routine():
       module = selected_module()
       try:
           routine_index = [i[0] == routines.value for i in routines.menu].index(True)
       except ValueError:
           return None
       routine = module.procedures[routine_index]
       return routine
   
   
   def selected_variable():
       routine = selected_routine()
       try:
           variable_index = [i[0] == variables.value for i in variables.menu].index(True)
       except ValueError:
           return None
       variable = routine.variables[variable_index]
       return variable
   
   
   def select_variable(variable):
       routine = variable.routine
       module = routine.module
       modules.value = module.name
       module_handler(None, None, module.name)
       routines.value = routine.name
       routine_handler(None, None, routine.name)
       variables.value = variable.name
       variable_handler(None, None, variable.name)
   
   
   def set_routine_labels(module):
       routine_labels = [(routine.name, routine.name) for routine in module.procedures]
       routines.menu = routine_labels
   
   
   def set_variable_labels(routine):
       variable_labels = [(variable.name, variable.name) for variable in routine.variables]
       variables.menu = variable_labels
   
   

   v = load_vault(vault_path)
   
   menu = [(module.name, module.name) for module in v.modules]
   modules = Dropdown(label="Modules", menu=menu, button_type="success")
   routines = Dropdown(label="Routines", button_type="success")
   variables = Dropdown(label="Variables", button_type="success")
   variable_description = PreText()
   variable_precision = TextInput(title="Variable precision:")
   id_selector = TextInput(title="Select by id:")
   
   
   modules.on_change("value", module_handler)
   routines.on_change("value", routine_handler)
   variables.on_change("value", variable_handler)
   variable_precision.on_change("value", text_input_handler)
   id_selector.on_change("value", id_selector_handler)
   
   var = v.get_variable_by_id(0)
   select_variable(var)
   
   lay = column(modules, routines, variables, id_selector,variable_description, variable_precision)
   return lay
  #curdoc().add_root(lay)
  #curdoc()
