'''
Created on 27-jul.-2014

@author: Simon
'''
import time, threading
from Queue import Empty

import Tkinter as tk
from tkinter_widget import TkinterWidget

import particle_interaction_vis
from particle_interaction import *

from python_runtime.statecharts_core import Event
from python_runtime.tkinter_eventloop import *

class Root(tk.Tk):
    def __init__(self, framerate):
        tk.Tk.__init__(self)
        self.framerate = framerate
        
    def set_controller(self, controller):
        self.controller = controller
        self.ui_reply_port = self.controller.addOutputListener('output')
    
    def set_sim(self, sim):
        self.sim = sim
    
    def handle_output_pos(self, msgs):
        for msg_contents in msgs:
            event = None
            if msg_contents[0] == "delete":
                event = Event("delete_particle", "input", [msg_contents[1]])
            elif msg_contents[0] == "created":
                event = Event("create_particle", "input", [msg_contents[1:]])
            else:
                event = Event("move_particle", "input", [msg_contents])
            self.controller.addInput(event)
    
    def handle_output_color(self, msgs):
        for msg_contents in msgs:
            event = Event("color_particle", "input", [msg_contents])
            self.controller.addInput(event)
    
    def handle_output_time(self, msgs):
        for msg_contents in msgs:
            self.controller.addInput(Event("update_time", "input", ["%.2f" % (float(msg_contents) / self.framerate)]))
    
    def check_output(self):
        while True:
            reply_msg = self.ui_reply_port.fetch(0)
            if reply_msg == None:
                break
            event_name = reply_msg.getName()
            parameters = reply_msg.getParameters()
            if event_name == "particle_clicked":
                self.sim.realtime_interrupt("INTERRUPT %i" % parameters[0])
            elif event_name == "delete_selected":
                self.sim.realtime_interrupt("INTERRUPT delete_selected")
        self.after(100, self.check_output)

if __name__ == '__main__':
    try:
        opts, args = getopt.getopt(sys.argv[1:], "w:h:f:s:d:r:", ["width=", "height=", "framerate=", "spawn_chance=", "die_chance=", "random_seed="])
    except getopt.GetoptError, e:
        print e
        sys.exit(2)
    width, height, framerate, spawn_chance, die_chance, random_seed = [None] * 6
    for opt, arg in opts:
        if opt in ("--width", "-w"):
            width = int(arg)
        elif opt in ("--height", "-h"):
            height = int(arg)
        elif opt in ("--framerate", "-f"):
            framerate = int(arg)
        elif opt in ("--spawn_chance", "-s"):
            spawn_chance = float(arg)
        elif opt in ("--die_chance", "-d"):
            die_chance = float(arg)
        elif opt in ("--random_seed", "-r"):
            random_seed = int(arg)
    resolution = (width or 800, height or 600)
    framerate = framerate or 30
    spawn_chance = 0.2 if spawn_chance is None else spawn_chance
    die_chance = 0.01 if die_chance is None else die_chance
    
    root = Root(framerate)
    root.withdraw()
    
    model = Field(Canvas(resolution), framerate, spawn_chance, die_chance)    
    sim = Simulator(model)
    sim.setRealTime(True, 1.0 / framerate)
    sim.setRealTimeInputFile(None)
    sim.setRealTimePorts({'INTERRUPT': model.INTERRUPT})
    sim.setRealTimePlatformTk(root)
    sim.setDSDEVS(True)
    sim.setClassicDEVS(True)
    sim.setTerminationTime(60 * framerate)
    #sim.setVerbose("myOutputFile")
    
    controller = particle_interaction_vis.Controller(root, resolution, TkEventLoop(root))
    TkinterWidget.controller = controller
    root.set_controller(controller)
    root.set_sim(sim)
    sim.setListenPorts(model.POS_OUT, root.handle_output_pos)
    sim.setListenPorts(model.COLOR_OUT, root.handle_output_color)
    sim.setListenPorts(model.TIME_OUT, root.handle_output_time)
    root.check_output()
    
    controller.start()
    sim.simulate()
    root.mainloop()