"""
Generated by Statechart compiler by Glenn De Jonghe and Joeri Exelmans

Date:   Sun Dec 07 18:22:48 2014

Model author: Raphael Mannadiar
Model name:   Traffic_Light
Model description:
PIM Traffic lights.
"""

from python_runtime.statecharts_core import *
from python_runtime.libs.ui import *
from python_runtime.libs.utils import *

# package "Traffic_Light"

class TrafficLight(RuntimeClassBase):
	def __init__(self, controller, canvas):
		RuntimeClassBase.__init__(self, controller)
		
		self.semantics.big_step_maximality = StatechartSemantics.TakeMany
		self.semantics.internal_event_lifeline = StatechartSemantics.Queue
		self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
		self.semantics.priority = StatechartSemantics.SourceParent
		self.semantics.concurrency = StatechartSemantics.Single
		
		# Call user defined constructor
		TrafficLight.user_defined_constructor(self, canvas)
	
	def user_defined_constructor(self, canvas):
		size = 100
		offset = size + 5
		self.RED = 0
		self.YELLOW = 1
		self.GREEN = 2
		self.colors = ['#f00', '#ff0', '#0f0']
		self.lights = [canvas.add_rectangle(size / 2, size / 2, size, size, {'fill':'#000'}), canvas.add_rectangle(size / 2, size / 2 + offset, size, size, {'fill':'#000'}), canvas.add_rectangle(size / 2, size / 2 + 2 * offset, size, size, {'fill':'#000'})]
	
	def user_defined_destructor(self):
		pass
	
	
	# User defined method
	def setYellow(self):
		self.clear()
		self.lights[self.YELLOW].set_color(self.colors[self.YELLOW])
	
	
	# User defined method
	def setGreen(self):
		self.clear()
		self.lights[self.GREEN].set_color(self.colors[self.GREEN])
	
	
	# User defined method
	def clear(self):
		self.lights[self.RED].set_color('#000')
		self.lights[self.YELLOW].set_color('#000')
		self.lights[self.GREEN].set_color('#000')
	
	
	# User defined method
	def setRed(self):
		self.clear()
		self.lights[self.RED].set_color(self.colors[self.RED])
	
	def initializeStatechart(self):
		self.current_state[self.Root] = []
		self.current_state[self.Root_on] = []
		self.current_state[self.Root_on_interrupted] = []
		self.current_state[self.Root_on_normal] = []
		
		self.history_state[self.Root_on_normal] = []
		
		# Enter default state
		self.enterDefault_Root_on()
	
	# Unique IDs for all statechart nodes
	Root = 0
	Root_on = 1
	Root_on_interrupted = 2
	Root_on_normal = 3
	Root_on_interrupted_yellow = 4
	Root_on_interrupted_black = 5
	Root_on_normal_yellow = 6
	Root_on_normal_red = 7
	Root_on_normal_green = 8
	Root_off = 9
	
	# Statechart enter/exit action method(s)
	
	def enter_Root_on(self):
		self.current_state[self.Root].append(self.Root_on)
	
	def exit_Root_on(self):
		if self.Root_on_interrupted in self.current_state[self.Root_on]:
			self.exit_Root_on_interrupted()
		if self.Root_on_normal in self.current_state[self.Root_on]:
			self.exit_Root_on_normal()
		self.current_state[self.Root] = []
	
	def enter_Root_on_interrupted(self):
		self.current_state[self.Root_on].append(self.Root_on_interrupted)
	
	def exit_Root_on_interrupted(self):
		if self.Root_on_interrupted_yellow in self.current_state[self.Root_on_interrupted]:
			self.exit_Root_on_interrupted_yellow()
		if self.Root_on_interrupted_black in self.current_state[self.Root_on_interrupted]:
			self.exit_Root_on_interrupted_black()
		self.current_state[self.Root_on] = []
	
	def enter_Root_on_normal(self):
		self.current_state[self.Root_on].append(self.Root_on_normal)
	
	def exit_Root_on_normal(self):
		self.history_state[self.Root_on_normal] = self.current_state[self.Root_on_normal]
		if self.Root_on_normal_yellow in self.current_state[self.Root_on_normal]:
			self.exit_Root_on_normal_yellow()
		if self.Root_on_normal_red in self.current_state[self.Root_on_normal]:
			self.exit_Root_on_normal_red()
		if self.Root_on_normal_green in self.current_state[self.Root_on_normal]:
			self.exit_Root_on_normal_green()
		self.current_state[self.Root_on] = []
	
	def enter_Root_on_interrupted_yellow(self):
		self.timers[0] = 0.5
		self.setYellow()
		self.current_state[self.Root_on_interrupted].append(self.Root_on_interrupted_yellow)
	
	def exit_Root_on_interrupted_yellow(self):
		self.timers.pop(0, None)
		self.current_state[self.Root_on_interrupted] = []
	
	def enter_Root_on_interrupted_black(self):
		self.timers[1] = 0.5
		self.clear()
		self.current_state[self.Root_on_interrupted].append(self.Root_on_interrupted_black)
	
	def exit_Root_on_interrupted_black(self):
		self.timers.pop(1, None)
		self.current_state[self.Root_on_interrupted] = []
	
	def enter_Root_on_normal_yellow(self):
		self.timers[2] = 1.0
		self.setYellow()
		self.current_state[self.Root_on_normal].append(self.Root_on_normal_yellow)
	
	def exit_Root_on_normal_yellow(self):
		self.timers.pop(2, None)
		self.current_state[self.Root_on_normal] = []
	
	def enter_Root_on_normal_red(self):
		self.timers[3] = 3.0
		self.setRed()
		self.current_state[self.Root_on_normal].append(self.Root_on_normal_red)
	
	def exit_Root_on_normal_red(self):
		self.timers.pop(3, None)
		self.current_state[self.Root_on_normal] = []
	
	def enter_Root_on_normal_green(self):
		self.timers[4] = 2.0
		self.setGreen()
		self.current_state[self.Root_on_normal].append(self.Root_on_normal_green)
	
	def exit_Root_on_normal_green(self):
		self.timers.pop(4, None)
		self.current_state[self.Root_on_normal] = []
	
	def enter_Root_off(self):
		self.clear()
		self.current_state[self.Root].append(self.Root_off)
	
	def exit_Root_off(self):
		self.current_state[self.Root] = []
	
	# Statechart enter/exit default method(s)
	
	def enterDefault_Root_on(self):
		self.enter_Root_on()
		self.enterDefault_Root_on_normal()
	
	def enterDefault_Root_on_interrupted(self):
		self.enter_Root_on_interrupted()
		self.enter_Root_on_interrupted_yellow()
	
	def enterDefault_Root_on_normal(self):
		self.enter_Root_on_normal()
		self.enter_Root_on_normal_red()
	
	# Statechart enter/exit history method(s)
	
	def enterHistoryShallow_Root_on_normal(self):
		if len(self.history_state[self.Root_on_normal]) == 0:
			self.enter_Root_on_normal_red()
		else:
			if self.Root_on_normal_yellow in self.history_state[self.Root_on_normal]:
				self.enter_Root_on_normal_yellow()
			if self.Root_on_normal_red in self.history_state[self.Root_on_normal]:
				self.enter_Root_on_normal_red()
			if self.Root_on_normal_green in self.history_state[self.Root_on_normal]:
				self.enter_Root_on_normal_green()
	
	# Statechart transitions
	
	def generateCandidatesChildren_Root(self):
		if self.current_state[self.Root][0] == self.Root_on:
			return self.generateCandidates_Root_on()
		elif self.current_state[self.Root][0] == self.Root_off:
			return self.generateCandidates_Root_off()
		return False
	
	def generateCandidates_Root(self):
		if not self.combo_step.isArenaChanged(self.Root):
			return self.generateCandidatesChildren_Root()
		return False
	
	def generateCandidatesChildren_Root_on(self):
		if self.current_state[self.Root_on][0] == self.Root_on_interrupted:
			return self.generateCandidates_Root_on_interrupted()
		elif self.current_state[self.Root_on][0] == self.Root_on_normal:
			return self.generateCandidates_Root_on_normal()
		return False
	
	def generateCandidatesCurrent_Root_on(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "stop_clicked") and (e.port == "ui"):
				self.small_step.addCandidate(self.transition_Root_on_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_on(self):
		branch_done = False
		if not self.combo_step.isArenaChanged(self.Root_on):
			if self.semantics.priority == StatechartSemantics.SourceParent:
				branch_done = self.generateCandidatesCurrent_Root_on()
				if not branch_done:
					branch_done = self.generateCandidatesChildren_Root_on()
			elif self.semantics.priority == StatechartSemantics.SourceChild:
				branch_done = self.generateCandidatesChildren_Root_on()
				if not branch_done:
					branch_done = self.generateCandidatesCurrent_Root_on()
		return branch_done
	
	def transition_Root_on_1(self, parameters):
		self.exit_Root_on()
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_off()
	
	def generateCandidatesChildren_Root_on_interrupted(self):
		if self.current_state[self.Root_on_interrupted][0] == self.Root_on_interrupted_yellow:
			return self.generateCandidates_Root_on_interrupted_yellow()
		elif self.current_state[self.Root_on_interrupted][0] == self.Root_on_interrupted_black:
			return self.generateCandidates_Root_on_interrupted_black()
		return False
	
	def generateCandidatesCurrent_Root_on_interrupted(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "police_interrupt_clicked") and (e.port == "ui"):
				self.small_step.addCandidate(self.transition_Root_on_interrupted_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_on_interrupted(self):
		branch_done = False
		if not self.combo_step.isArenaChanged(self.Root_on_interrupted):
			if self.semantics.priority == StatechartSemantics.SourceParent:
				branch_done = self.generateCandidatesCurrent_Root_on_interrupted()
				if not branch_done:
					branch_done = self.generateCandidatesChildren_Root_on_interrupted()
			elif self.semantics.priority == StatechartSemantics.SourceChild:
				branch_done = self.generateCandidatesChildren_Root_on_interrupted()
				if not branch_done:
					branch_done = self.generateCandidatesCurrent_Root_on_interrupted()
		return branch_done
	
	def transition_Root_on_interrupted_1(self, parameters):
		self.exit_Root_on_interrupted()
		self.combo_step.setArenaChanged(self.Root_on)
		self.enter_Root_on_normal()
		self.enterHistoryShallow_Root_on_normal()
	
	def generateCandidatesCurrent_Root_on_interrupted_yellow(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "_0after":
				self.small_step.addCandidate(self.transition_Root_on_interrupted_yellow_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_on_interrupted_yellow(self):
		if not self.combo_step.isArenaChanged(self.Root_on_interrupted_yellow):
			return self.generateCandidatesCurrent_Root_on_interrupted_yellow()
		return False
	
	def transition_Root_on_interrupted_yellow_1(self, parameters):
		self.exit_Root_on_interrupted_yellow()
		self.combo_step.setArenaChanged(self.Root_on_interrupted)
		self.enter_Root_on_interrupted_black()
	
	def generateCandidatesCurrent_Root_on_interrupted_black(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "_1after":
				self.small_step.addCandidate(self.transition_Root_on_interrupted_black_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_on_interrupted_black(self):
		if not self.combo_step.isArenaChanged(self.Root_on_interrupted_black):
			return self.generateCandidatesCurrent_Root_on_interrupted_black()
		return False
	
	def transition_Root_on_interrupted_black_1(self, parameters):
		self.exit_Root_on_interrupted_black()
		self.combo_step.setArenaChanged(self.Root_on_interrupted)
		self.enter_Root_on_interrupted_yellow()
	
	def generateCandidatesChildren_Root_on_normal(self):
		if self.current_state[self.Root_on_normal][0] == self.Root_on_normal_yellow:
			return self.generateCandidates_Root_on_normal_yellow()
		elif self.current_state[self.Root_on_normal][0] == self.Root_on_normal_red:
			return self.generateCandidates_Root_on_normal_red()
		elif self.current_state[self.Root_on_normal][0] == self.Root_on_normal_green:
			return self.generateCandidates_Root_on_normal_green()
		return False
	
	def generateCandidatesCurrent_Root_on_normal(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "police_interrupt_clicked") and (e.port == "ui"):
				self.small_step.addCandidate(self.transition_Root_on_normal_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_on_normal(self):
		branch_done = False
		if not self.combo_step.isArenaChanged(self.Root_on_normal):
			if self.semantics.priority == StatechartSemantics.SourceParent:
				branch_done = self.generateCandidatesCurrent_Root_on_normal()
				if not branch_done:
					branch_done = self.generateCandidatesChildren_Root_on_normal()
			elif self.semantics.priority == StatechartSemantics.SourceChild:
				branch_done = self.generateCandidatesChildren_Root_on_normal()
				if not branch_done:
					branch_done = self.generateCandidatesCurrent_Root_on_normal()
		return branch_done
	
	def transition_Root_on_normal_1(self, parameters):
		self.exit_Root_on_normal()
		self.combo_step.setArenaChanged(self.Root_on)
		self.enterDefault_Root_on_interrupted()
	
	def generateCandidatesCurrent_Root_on_normal_yellow(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "_2after":
				self.small_step.addCandidate(self.transition_Root_on_normal_yellow_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_on_normal_yellow(self):
		if not self.combo_step.isArenaChanged(self.Root_on_normal_yellow):
			return self.generateCandidatesCurrent_Root_on_normal_yellow()
		return False
	
	def transition_Root_on_normal_yellow_1(self, parameters):
		self.exit_Root_on_normal_yellow()
		self.combo_step.setArenaChanged(self.Root_on_normal)
		self.enter_Root_on_normal_red()
	
	def generateCandidatesCurrent_Root_on_normal_red(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "_3after":
				self.small_step.addCandidate(self.transition_Root_on_normal_red_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_on_normal_red(self):
		if not self.combo_step.isArenaChanged(self.Root_on_normal_red):
			return self.generateCandidatesCurrent_Root_on_normal_red()
		return False
	
	def transition_Root_on_normal_red_1(self, parameters):
		self.exit_Root_on_normal_red()
		self.combo_step.setArenaChanged(self.Root_on_normal)
		self.enter_Root_on_normal_green()
	
	def generateCandidatesCurrent_Root_on_normal_green(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "_4after":
				self.small_step.addCandidate(self.transition_Root_on_normal_green_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_on_normal_green(self):
		if not self.combo_step.isArenaChanged(self.Root_on_normal_green):
			return self.generateCandidatesCurrent_Root_on_normal_green()
		return False
	
	def transition_Root_on_normal_green_1(self, parameters):
		self.exit_Root_on_normal_green()
		self.combo_step.setArenaChanged(self.Root_on_normal)
		self.enter_Root_on_normal_yellow()
	
	def generateCandidates_Root_off(self):
		return False
	
	# Generate transition candidates for current small step
	def generateCandidates(self):
		self.generateCandidates_Root()

class MainApp(RuntimeClassBase):
	def __init__(self, controller):
		RuntimeClassBase.__init__(self, controller)
		
		self.semantics.big_step_maximality = StatechartSemantics.TakeMany
		self.semantics.internal_event_lifeline = StatechartSemantics.Queue
		self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
		self.semantics.priority = StatechartSemantics.SourceParent
		self.semantics.concurrency = StatechartSemantics.Single
		
		# Call user defined constructor
		MainApp.user_defined_constructor(self)
	
	def user_defined_constructor(self):
		self.canvas = ui.append_canvas(ui.window, 100, 310, {'background':'#eee'})
		police_button = ui.append_button(ui.window, 'Police interrupt')
		stop_button = ui.append_button(ui.window, 'Stop')
		ui.bind_event(police_button.element, ui.EVENTS.MOUSE_CLICK, self.controller, 'police_interrupt_clicked')
		ui.bind_event(stop_button.element, ui.EVENTS.MOUSE_CLICK, self.controller, 'stop_clicked')
	
	def user_defined_destructor(self):
		pass
	
	def initializeStatechart(self):
		self.current_state[self.Root] = []
		
		# Enter default state
		self.enter_Root_initializing()
	
	# Unique IDs for all statechart nodes
	Root = 0
	Root_initialized = 1
	Root_initializing = 2
	Root_creating = 3
	
	# Statechart enter/exit action method(s)
	
	def enter_Root_initialized(self):
		self.current_state[self.Root].append(self.Root_initialized)
	
	def exit_Root_initialized(self):
		self.current_state[self.Root] = []
	
	def enter_Root_initializing(self):
		self.current_state[self.Root].append(self.Root_initializing)
	
	def exit_Root_initializing(self):
		self.current_state[self.Root] = []
	
	def enter_Root_creating(self):
		self.current_state[self.Root].append(self.Root_creating)
	
	def exit_Root_creating(self):
		self.current_state[self.Root] = []
	
	# Statechart transitions
	
	def generateCandidatesChildren_Root(self):
		if self.current_state[self.Root][0] == self.Root_initialized:
			return self.generateCandidates_Root_initialized()
		elif self.current_state[self.Root][0] == self.Root_initializing:
			return self.generateCandidates_Root_initializing()
		elif self.current_state[self.Root][0] == self.Root_creating:
			return self.generateCandidates_Root_creating()
		return False
	
	def generateCandidates_Root(self):
		if not self.combo_step.isArenaChanged(self.Root):
			return self.generateCandidatesChildren_Root()
		return False
	
	def generateCandidates_Root_initialized(self):
		return False
	
	def generateCandidatesCurrent_Root_initializing(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_initializing_1, [])
		return True
		return False
	
	def generateCandidates_Root_initializing(self):
		if not self.combo_step.isArenaChanged(self.Root_initializing):
			return self.generateCandidatesCurrent_Root_initializing()
		return False
	
	def transition_Root_initializing_1(self, parameters):
		self.exit_Root_initializing()
		self.big_step.outputEventOM(Event("create_instance", None, [self, 'trafficlight', 'TrafficLight', self.canvas]))
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_creating()
	
	def generateCandidatesCurrent_Root_creating(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "instance_created":
				self.small_step.addCandidate(self.transition_Root_creating_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_creating(self):
		if not self.combo_step.isArenaChanged(self.Root_creating):
			return self.generateCandidatesCurrent_Root_creating()
		return False
	
	def transition_Root_creating_1(self, parameters):
		association_name = parameters[0]
		self.exit_Root_creating()
		self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("set_association_name", None, [association_name])]))
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_initialized()
	
	# Generate transition candidates for current small step
	def generateCandidates(self):
		self.generateCandidates_Root()

class ObjectManager(ObjectManagerBase):
	def __init__(self, controller):
		ObjectManagerBase.__init__(self, controller)
	
	def instantiate(self, class_name, construct_params):
		if class_name == "TrafficLight":
			instance = TrafficLight(self.controller, construct_params[0])
			instance.associations = {}
		elif class_name == "MainApp":
			instance = MainApp(self.controller)
			instance.associations = {}
			instance.associations["trafficlight"] = Association("TrafficLight", 0, -1)
		return instance

class Controller(GameLoopControllerBase):
	def __init__(self):
		GameLoopControllerBase.__init__(self, ObjectManager(self))
		self.addInputPort("ui")
		self.object_manager.createInstance("MainApp", [])