from __future__ import print_function

from bokeh.core.properties import String
from bokeh.document import Document
from bokeh.embed import file_html
from bokeh.models.callbacks import Callback
from bokeh.models.glyphs import Circle
from bokeh.models import Plot, DataRange1d, LinearAxis, ColumnDataSource, PanTool, WheelZoomTool, TapTool
from bokeh.models.layouts import Row
from bokeh.resources import INLINE
from bokeh.util.browser import view

class Popup(Callback):

    __implementation__ = """
_ = require "underscore"
Util = require "util/util"
Model = require "model"
p = require "core/properties"

class Popup extends Model
  type: "Popup"

  execute: (data_source) ->
    for i in Util.get_indices(data_source)
      message = Util.replace_placeholders(@get("message"), data_source, i)
      window.alert(message)
    null

  @define {
    message: [ p.String, "" ]
  }

module.exports =
  Model: Popup
"""

    message = String("", help="""
    Message to display in a popup window. This can be a template string,
    which will be formatted with data from the data source.
    """)


class MyRow(Row):

    __implementation__ = """
Row = require "models/layouts/row"

class MyRowView extends Row.View
  render: () ->
    super()
    @$el.css({border: "5px solid black"})

class MyRow extends Row.Model
  type: "MyRow"
  default_view: MyRowView

module.exports = {
  Model: MyRow
  View: MyRowView
}
"""

source = ColumnDataSource(
    data = dict(
        x = [1, 2, 3, 4, 4,   5, 5],
        y = [5, 4, 3, 2, 2.1, 1, 1.1],
        color = ["rgb(0, 100, 120)", "green", "blue", "#2c7fb8", "#2c7fb8", "rgba(120, 230, 150, 0.5)", "rgba(120, 230, 150, 0.5)"]
    )
)

xdr = DataRange1d()
ydr = DataRange1d()

plot = Plot(x_range=xdr, y_range=ydr)

circle = Circle(x="x", y="y", radius=0.2, fill_color="color", line_color="black")
circle_renderer = plot.add_glyph(source, circle)

plot.add_layout(LinearAxis(), 'below')
plot.add_layout(LinearAxis(), 'left')

tap = TapTool(renderers=[circle_renderer], callback=Popup(message="Selected color: @color"))
plot.add_tools(PanTool(), WheelZoomTool(), tap)

doc = Document()
doc.add_root(MyRow(children=[plot]))

if __name__ == "__main__":
    doc.validate()
    filename = "custom.html"
    with open(filename, "w") as f:
        f.write(file_html(doc, INLINE, "Demonstration of user-defined models"))
    print("Wrote %s" % filename)
    view(filename)
