from jinja2 import Environment, FileSystemLoader

from random import random

from tornado.web import RequestHandler
from bokeh.embed import server_document, server_session
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Slider
from bokeh.plotting import figure
from bokeh.server.server import Server
from bokeh.themes import Theme

from bokeh.sampledata.sea_surface_temperature import sea_surface_temperature

env = Environment(loader=FileSystemLoader('templates'))

#class IndexHandler(RequestHandler):
#    def get(self):
#        template = env.get_template('index.html')
#        script = server_document('http://localhost:5006/bkapp')
#        self.write(template.render(script=script,script22=script, template="Tornado"))

def modify_doc(doc):
    df = sea_surface_temperature.copy()
    source = ColumnDataSource(data=df)

    plot = figure(x_axis_type='datetime', y_range=(0, 25), y_axis_label='Temperature (Celsius)',
                  title="Sea Surface Temperature at 43.18, -70.43")
    plot.line('time', 'temperature', source=source)

    def callback(attr, old, new):
        if new == 0:
            data = df
        else:
            data = df.rolling('{0}D'.format(new)).mean()
        source.data = ColumnDataSource(data=data).data

    slider = Slider(start=0, end=30, value=0, step=1, title="Smoothing by N Days")
    slider.on_change('value', callback)
   
    doc.add_root(column(slider, plot))
    doc.roots[0]._id = 'root0'
    source2 = ColumnDataSource(data=dict(x=[0],y=[0]))

    def update():
        source2.stream(dict(x=[random()],y=[random()]))

    p = figure(x_range=[0,1],y_range=[0,1])
    l = p.circle(x='x',y='y', source=source2)
    doc.add_periodic_callback(update,100)
    doc.add_root(p)
    doc.roots[1]._id = 'root1'
    
    doc.theme = Theme(filename="theme.yaml")

class IndexHandler(RequestHandler):
    def get(self):
        template = env.get_template('index.html')
        root0_script = server_document('http://localhost:5006/bkapp',model_id='root0')
        root1_script = server_document('http://localhost:5006/bkapp',model_id='root1')
        self.write(template.render(script0=root0_script,script1=root1_script, template="Tornado"))

# Setting num_procs here means we can't touch the IOLoop before now, we must
# let Server handle that. If you need to explicitly handle IOLoops then you
# will need to use the lower level BaseServer class.
server = Server({'/bkapp': modify_doc}, extra_patterns=[('/', IndexHandler)])
server.start()

if __name__ == '__main__':
    from bokeh.util.browser import view

    print('Opening Tornado app with embedded Bokeh application on http://localhost:5006/')
    server.io_loop.add_callback(view, "http://localhost:5006/")
    server.io_loop.start()
