
from numpy import random
from bokeh.plotting import figure, curdoc
from bokeh.layouts import row, column, widgetbox
from bokeh.models.widgets import Button
from bokeh.models import Spacer


from bokeh.models import BoxAnnotation

# In[0]:
# plot / layout helper functions.

def draw_blank(figure_width=500,figure_height=250):
    f= figure(tools="save", background_fill_color="#EFE8E2", 
                          title="", width=figure_width, height=figure_height)
    return f

# In[0]:
# Data Handler
def remove(figure_width=500,figure_height=250):
    layout_c = external_data['layout_c']
    if len(layout_c.children) > 0:
    
        print(layout_c)
        print(layout_c.height)
        layout_c.children.pop()
    else:
        print("no children to pop")

# goes into our layout_c container and removes all the children
def clear_column():
    layout_c = external_data['layout_c']
    while len(layout_c.children)>0:
        remove()
    
    print('================================= plots removed')

    
# In[0]:
        
    
# Make some data sources and dump them in a global variable called 
# external_data['data_sources']
def get_data():
    print(">>> create_data_sources")
    x_ = [0,1,2,3]
    y_ = [-10,220,40,90]
    datasource0 = ColumnDataSource(data=dict(x=x_, y=y_))
    datasource1 = ColumnDataSource(data=dict(x=x_, y=y_))
    data_sources = [datasource0,datasource1]
            
    external_data['data_sources'] = data_sources
    
    print(len(external_data['data_sources']))
    print("<<< create_data_sources")


    

def plot_data(figure_width=500,figure_height=250):
    layout_c = external_data['layout_c']
    print("layout_c.children count: "+str(len(layout_c.children)))

    data_sources = external_data['data_sources'] 

    #==========================================================================
    # setup the x-range to be none... we will tie the x-axes together.
    x_range = None
    #==========================================================================
    
    # make a plot for each datasource
    for i,data_source in enumerate(data_sources):
        print(len(data_sources))
        f = draw_plot3(data_source,x_range)
        
        # used to tie the x-axes together
        if x_range == None:
            x_range = f.x_range
        
        # put the figure in a row... semed to work better this way with
        # adding / deleting plots.  may no longer be necessary.
        r = row(f)
        layout_c.children.append(r)

def add_box_annotations(f,box_times,fill_alpha=0.1,fill_color='red'):
    print(">>>figure type")
    print(type(f))
    print(str(f.toolbar.logo))
    print(str(f.toolbar_location))
    print(len(f.toolbar.tools))
    print("<<<figure type")
    
    
    box_annotation_list = []
    print(">>>hide box annotations")
    for i,r in enumerate(f.renderers):
        if r.name == 'my_box_annotation':
            box_annotation_list.append(r)
            r.visible = False
            print("   building my_box_annotation list")
    print("<<<hide box annotations")
    
    print(">>>add_box_annotations")

    # i is the index
    # r is the row
    print(box_times)
    print("   1")
    i = -1
    for r in box_times:
        i = i+1
        print("   2")
        print(r)
        left = r[0]
        print("   3")
        right = r[1]
        print("   4")

        if i < len(box_annotation_list):
            # we already have this many box annotations, just update i'th one
            box_annotation_list[i].left = left
            box_annotation_list[i].right = right
            box_annotation_list[i].visible = True
            print("         updated box annotation visible")
        else:
            # not enough box annotations, add one more
            box = BoxAnnotation(name='my_box_annotation',left=left,right=right, fill_alpha=fill_alpha, fill_color=fill_color)
            
            f.add_layout(box)    
            box_annotation_list.append(box)
            print("         created new box annotation")

    for i,r in enumerate(f.renderers):
        if r.name == 'my_box_annotation':
            print("   found my_box_annotation after adding annotations")
    print("<<<add_box_annotations")

    print(">>>figure type")
    print(type(f))
    print("f.toolbar.logo: " + str(f.toolbar.logo))
    print("f.toolbar_location: " + str(f.toolbar_location))
    print("len(f.toolbar.tools): "+ str(len(f.toolbar.tools)))


    print(len(f.toolbar.tools))
    print("<<<figure type")

    return f
                
        
def r_():
    return random.randint(0,5)/10.

def add_box_annotations_handler():
    print(">>>add_box_annotations_handler")
    c = external_data['layout_c']
    
    for i in range(len(c.children)):
        if i == 1:
            # define some random box times
            box_times = [[0.1+r_(),0.8+r_()],[1.1+r_(),2.4+r_()]]      
    
            # the first children list is for the column
            # the second children list is for the row inside the column
            p = c.children[i].children[0]
            add_box_annotations(p,box_times)

    print("<<<add_box_annotations_handler")   

    
# callbacks
get_data_button = Button(label='get data', width=150)
get_data_button.on_click(get_data)
clear_column_button = Button(label='clear column', width=150)
clear_column_button.on_click(clear_column)
plot_data_button = Button(label='plot data', width=150)
plot_data_button.on_click(plot_data)

add_box_annotations_button = Button(label='add_box_annotation', width=150)
add_box_annotations_button.on_click(add_box_annotations_handler)
#===========





from bokeh.models import ColumnDataSource
from bokeh.models.widgets import Button

#=====


    
def draw_plot3(source,x_range,figure_type='line',flags=None,figure_width=1000,figure_height=300):
    print(">>> draw_plot3")

    f = figure(height=figure_height, width=figure_width,sizing_mode="fixed",title='some title',
                tools="box_select,pan,reset,save,xwheel_zoom,ywheel_zoom")

    f.line('x', 'y', source=source, line_width=3, line_alpha=0.6)
        
    # tie x-axes together
    if x_range != None:
        f.x_range = x_range

    f.xaxis.axis_label = 'time'
    f.yaxis.axis_label = str('y')
    print("<<< draw_plot3")
    return f    



# In[0]:
#=========================
# global va
external_data = {}

def init():
    wbox = widgetbox([get_data_button,clear_column_button,plot_data_button,add_box_annotations_button], width=300)

    layout_c = column(Spacer(width=250, height=50), width=600)
    
    l = row(wbox, layout_c, width=wbox.width+layout_c.width, height=layout_c.height)

    external_data['layout_c'] = layout_c

    #===============
    c = l
    print("<<< init()")
    
    #================
    # DEBUG
    # Try commenting out these next two lines... 
    # The annotation issue seems to start happening subsequent to 
    # the first time the get_data() and plot_data() are called after the 
    # web page is loaded
    get_data()
    clear_column()
    plot_data()
    get_data()
    clear_column()
    plot_data()
    #================
    return c


    
#========================================================
plot_panel_layout = init()

# create the document
curdoc().add_root(plot_panel_layout)
curdoc().title = "Plotter"

