#!/usr/bin/env python

import math, random
import gobject
import gtk, v_sim

def delete_event(widget, event, data=None):
    return False

def destroy(widget, data=None):
    gtk.main_quit()

def reset(widget, v_sim, handles):
  stop(widget, handles)
  v_sim.set(None)

def stop(widget, handles):
  if (handles[0] is not None):
    gobject.source_remove(handles[0])
  if (handles[1] is not None):
    gobject.source_remove(handles[1])
  handles[0] = None
  handles[1] = None

def load(widget, v_sim, data, nodes, C, angle, handles):
  if (handles[0] is not None):
    gobject.source_remove(handles[0])
  if (handles[1] is not None):
    gobject.source_remove(handles[1])

  v_sim.set(data)

  handles[0] = gobject.timeout_add(10, turn, angle, v_sim, data, nodes)
  handles[1] = gobject.timeout_add(1000, add, data, angle, C, nodes)
  

def turn(angle, v_sim, data, nodes):
  angle[1] = math.pi * 2 / 3 + 0.5 * math.sin(angle[0] * 2)
  nodes[0].set(coord=(1.2 * math.sin(angle[1]) * (math.cos(angle[0])) + 2.5, \
                      1.2 * math.sin(angle[1]) * (math.sin(angle[0])) + 2.5, \
                      1.2 * math.cos(angle[1]) + 2))
  nodes[1].set(coord=(1.2 * math.sin(angle[1]) * (math.cos(angle[0] + math.pi)) + 2.5, \
                      1.2 * math.sin(angle[1]) * (math.sin(angle[0] + math.pi)) + 2.5, \
                      1.2 * math.cos(angle[1]) + 2), emit = True)
  if (nodes[2].isValid()):
    nodes[2].set(coord=(2.5, 2.5, 4 + math.sin(angle[1] + math.pi/4)))
  data.createAllNodes()
  v_sim.redraw()
  angle[0] += math.pi / 100
  if (angle[0] > 2 * math.pi):
    angle[0] = 0
  print data.getPopulation()
  return True

def add(data, angle, C, nodes):
  if (nodes[2].isValid()):
    data.delNodes(nodes[2])
  else:
    nodes[2] = data.addNode(C, (2.5, 2.5, 4. + math.sin(angle[1] + math.pi/4)), emit = True)
  return True

def start(window, handles):
    render = v_sim.main(width=400)
    window.get_data("hbox").pack_start(render, False, False, 0)

    angle = [0., math.pi * 2 / 3]
    O = v_sim.element("O", rgba=(1., 0.2, 0., 1.))
    #O.set(rendered = False)
    H = v_sim.element("H", rgba=(0.2, 0.4, 0.5, 0.3))
    C = v_sim.element("C", rgba=(0.1, 0.1, 0.1, 1.))

    data = v_sim.data()
    data.setPopulation({O:1, H:2, C:1})
    data.addNode(O, (2.5, 2.5, 2))
    nodes = []
    nodes.append(data.addNode(H, (1.5, 2.5, 1)))
    nodes.append(data.addNode(H, (3.5, 2.5, 1)))
    nodes.append(v_sim.node(data, 3))
    data.setBox((5., 0., 5., 0., 0., 5.), True)

    plane = v_sim.plane(normal = (1,0,0), distance = 3, rgba = (1,0.5,0.5,1))
    data.setPlanes((plane,))

    window.get_data("play").connect("clicked", load, v_sim, data, nodes, C, angle, handles)
    window.get_data("stop").connect("clicked", stop, handles)
    window.get_data("reset").connect("clicked", reset, v_sim, handles)

    return False

bouncing = """
O = v_sim.element("O", rgba=(1., 0.2, 0., 1.))
#O.set(rendered = False)
H = v_sim.element("H", rgba=(0.2, 0.4, 0.5, 0.3))
C = v_sim.element("C", rgba=(0.1, 0.1, 0.1, 1.))

data = v_sim.data()
data.setPopulation({O:1, H:2, C:1})
data.addNode(O, (2.5, 2.5, 2))
data.addNode(H, (1.5, 2.5, 1))
data.addNode(H, (3.5, 2.5, 1))
data.setBox((5., 0., 5., 0., 0., 5.), True)
"""

handles = [None, None]

# Set the GTK interface.
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.connect("delete_event", delete_event)
window.connect("destroy", destroy)
hbox = gtk.HBox()
window.add(hbox)
vbox = gtk.VBox()
vbox.set_border_width(7)
hbox.pack_start(vbox, True, True, 0)

wd = gtk.Label("<span size=\"large\"><b>Demonstrate Python bindings for V_Sim:</b></span>")
wd.set_use_markup(True)
wd.set_padding(10, 0)
vbox.pack_start(wd, False, False, 20)

scroll = gtk.ScrolledWindow()
scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
scroll.set_shadow_type(gtk.SHADOW_ETCHED_OUT)
vbox.pack_start(scroll, True, True, 0)
buf = gtk.TextBuffer()
buf.set_text(bouncing)
wd = gtk.TextView(buf)
wd.set_size_request(300, -1)
wd.set_editable(False)
scroll.add(wd)

com = gtk.HBox()
vbox.pack_end(com, False, False, 5)
wd = gtk.Button(stock = gtk.STOCK_MEDIA_PLAY)
window.set_data("play", wd)
com.pack_end(wd, False, False, 0)
wd = gtk.Button(stock = gtk.STOCK_MEDIA_STOP)
window.set_data("stop", wd)
com.pack_end(wd, False, False, 0)
wd = gtk.Button(stock = gtk.STOCK_REMOVE)
com.pack_start(wd, False, False, 0)
window.set_data("reset", wd)

window.set_data("hbox", hbox)

window.show_all()

gobject.idle_add(start, window, handles)

gtk.main()

