import numpy as np
import random
from bokeh.client import push_session
from bokeh.plotting import curdoc
from tornado.ioloop import IOLoop
from bokeh.application import Application
from bokeh.server.server import Server
from bokeh.layouts import row, widgetbox, column, gridplot
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import TextInput
from bokeh.plotting import figure

class Temp():
    def __init__(self, doc):
        self.doc = doc
        self.source = ColumnDataSource(data=dict(x=[], y=[]))
        self.is_start = False

        self.N = 200

        # Set up plot
        self.plot = figure(plot_height=400, plot_width=400, title="my sine wave",
                      tools="crosshair,pan,reset,save,wheel_zoom")

        self.plot.line('x', 'y', source=self.source, line_width=1, line_alpha=1)

        # Set up widgets
        self.text = TextInput(title="title", value='my sine wave')
        self.text.on_change('value', self.update_title)

        self.doc.add_periodic_callback(self.update, 100)

        # Set up layouts and add to document
        inputs = widgetbox(self.text)
        self.doc.add_root(column(inputs, self.plot, width=800))

    def update(self):
        if self.is_start:
            x = random.sample(xrange(1000),self.N)
            y = random.sample(xrange(1000),self.N)
            new_dict = dict(x=x, y=y)
            self.source.stream(new_dict, rollover=self.N)

    def update_title(self,attrname, old, new):
        self.plot.title.text = text.value

    def start(self):
        self.is_start = True

    def stop(self):
        self.is_start = False

def main():
    # Define tornado loop
    loop = IOLoop()

    # Define a blank application
    app = Application()
    # Starting server at port 5006
    srv = Server({'/':app},io_loop=loop)
    # Start server process
    srv.start()
    # Define the document instance
    doc = curdoc()
    session = push_session(doc, session_id="test", io_loop=loop, url='http://localhost:5006/')

    # Create Top Block instance
    tb = Temp(doc)

    # Start simulations as soon as the server starts
    loop.add_callback(tb.start)
    loop.add_callback(srv.show,'/?bokeh-session-id='+str(session.id))
    try:
        loop.start()
    except KeyboardInterrupt:
        print "Exiting the simulation. Stopping Bokeh Server"
    except Exception as e:
        print str(e)
    finally:
        # Stop the simulations when there is a key interrupt
        tb.stop()

main()
