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

Date:   Sun Dec 13 19:39:13 2015

Model author: Sadaf Mustafiz and Bruno Barroca and Claudio Gomes
Model name:   Woven_CBD_FSA_Simulator_Automatic
Model description:
Automatically woven CBD and FSA simulators with the CBD being the dominant.
"""

from python_runtime.statecharts_core import *
from python_runtime.libs.ui import *
from python_runtime.libs.utils import *
from CBD_Controller import CBDController
from cbd_tfsa_woven_classes import FSABlock
from cbd_tfsa_woven_classes import FSA_SemanticAdaptation
from fsaclasses import Events

# package "Woven_CBD_FSA_Simulator_Automatic"

class Woven_CBD_TFSA_Simulator(RuntimeClassBase):
	def __init__(self, controller, cbd_options, amodel, plotter):
		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
		
		# User defined attributes
		self.fsa_currentState = None
		self.cbd_delta = None
		self.woven_processing_fsa = None
		self.fsa_eventList = None
		self.cbd_strongComponentList = None
		self.cbd_clock = None
		self.cbd_iteration = None
		self.fsa_elapsed = None
		self.plotter = None
		self.cbd_depGraph = None
		self.cbd_currentCompIdx = None
		self.woven_ended_fsa = None
		self.fsa_timestep = None
		self.fsa_logicalTime = None
		self.cbd_model = None
		self.woven_logical_time_fsas = None
		self.woven_step_executed = None
		self.woven_current_state_fsas = None
		self.cbd_controller = None
		self.fsa_selectedTransition = None
		self.fsa_model = None
		self.fsa_currentEvent = None
		self.woven_delta = None
		self.woven_elapsed_fsas = None
		self.cbd_options = None
		
		# Call user defined constructor
		Woven_CBD_TFSA_Simulator.user_defined_constructor(self, cbd_options, amodel, plotter)
	
	def user_defined_constructor(self, cbd_options, amodel, plotter):
		self.cbd_options = cbd_options
		self.cbd_delta = self.cbd_options.getDeltaT()
		self.cbd_model = amodel
		self.plotter = plotter
		self.woven_processing_fsa = dict()
		self.woven_step_executed = dict()
		self.woven_ended_fsa = dict()
		self.woven_logical_time_fsas = dict()
		self.woven_elapsed_fsas = dict()
		self.woven_current_state_fsas = dict()
		self.fsa_timestep = 1.0
	
	def user_defined_destructor(self):
		pass
	
	
	# User defined method
	def woven_updateEventsTriggeredByZeroCrossing(self, time, fsaBlock, fsaState):
		self.fsa_eventList = Events(FSA_SemanticAdaptation.getEventsTriggeredByZeroCrossing(time, fsaBlock, fsaState))
	
	
	# User defined method
	def cbd_maxIterationsReached(self):
		return self.cbd_iteration >= self.cbd_options.getMaxIterations()
	
	
	# User defined method
	def woven_updateOutputFSA(self, iteration, time, fsaBlock, fsaState):
		FSA_SemanticAdaptation.updateOutputFSA(iteration, time, fsaBlock, fsaState)
	
	
	# User defined method
	def fsa_getInputEventAt(self, time):
		return self.fsa_eventList.getInputAt(time)
	
	
	# User defined method
	def fsa_processEvent(self, event):
		if (event != None):
			self.fsa_eventList.popEvent(event)
			event.processed = True
	
	
	# User defined method
	def cbd_computeBlock(self):
		if self.cbd_currentComponentIsCycle():
			self.cbd_controller.computeNextAlgebraicLoop(self.cbd_strongComponentList[self.cbd_currentCompIdx], self.cbd_iteration)
		else:
			self.cbd_controller.computeNextBlock(self.cbd_strongComponentList[self.cbd_currentCompIdx], self.cbd_iteration)
	
	
	# User defined method
	def cbd_currentComponentIsCycle(self):
		return self.cbd_controller.componentIsCycle(self.cbd_strongComponentList[self.cbd_currentCompIdx], self.cbd_depGraph)
	
	
	# User defined method
	def cbd_hasNextStrongComponent(self):
		return self.cbd_currentCompIdx < len(self.cbd_strongComponentList)
	
	def initializeStatechart(self):
		self.current_state[self.Root] = []
		self.current_state[self.Root_FSA] = []
		self.current_state[self.Root_CBD] = []
		
		# Enter default state
		self.enterDefault_Root_CBD()
	
	# Unique IDs for all statechart nodes
	Root = 0
	Root_FSA = 1
	Root_CBD = 2
	Root_ChildInitialized = 3
	Root_ChildNotInitialized = 4
	Root_ChildProcessed = 5
	Root_ChildDetected = 6
	Root_ChildPaused = 7
	Root_HybridTerminated = 8
	Root_ChildNotDetected = 9
	Root_FSA_Started = 10
	Root_FSA_Terminated = 11
	Root_FSA_Initialized = 12
	Root_FSA_MacroStepProcessed = 13
	Root_FSA_MicroStepProcessed = 14
	Root_FSA_MacroStepPrepared = 15
	Root_FSA_MicroStepPrepared = 16
	Root_ParentPaused = 17
	Root_CBD_Terminated = 18
	Root_CBD_MacroStepPrepared = 19
	Root_CBD_Started = 20
	Root_CBD_Initialized = 21
	Root_CBD_MacroStepProcessed = 22
	Root_CBD_MicroStepPrepared = 23
	Root_CBD_MicroStepProcessed = 24
	
	# Statechart enter/exit action method(s)
	
	def enter_Root_FSA(self):
		self.current_state[self.Root].append(self.Root_FSA)
	
	def exit_Root_FSA(self):
		if self.Root_FSA_Started in self.current_state[self.Root_FSA]:
			self.exit_Root_FSA_Started()
		if self.Root_FSA_Terminated in self.current_state[self.Root_FSA]:
			self.exit_Root_FSA_Terminated()
		if self.Root_FSA_Initialized in self.current_state[self.Root_FSA]:
			self.exit_Root_FSA_Initialized()
		if self.Root_FSA_MacroStepProcessed in self.current_state[self.Root_FSA]:
			self.exit_Root_FSA_MacroStepProcessed()
		if self.Root_FSA_MicroStepProcessed in self.current_state[self.Root_FSA]:
			self.exit_Root_FSA_MicroStepProcessed()
		if self.Root_FSA_MacroStepPrepared in self.current_state[self.Root_FSA]:
			self.exit_Root_FSA_MacroStepPrepared()
		if self.Root_FSA_MicroStepPrepared in self.current_state[self.Root_FSA]:
			self.exit_Root_FSA_MicroStepPrepared()
		self.current_state[self.Root] = []
	
	def enter_Root_CBD(self):
		self.current_state[self.Root].append(self.Root_CBD)
	
	def exit_Root_CBD(self):
		if self.Root_CBD_Terminated in self.current_state[self.Root_CBD]:
			self.exit_Root_CBD_Terminated()
		if self.Root_CBD_MacroStepPrepared in self.current_state[self.Root_CBD]:
			self.exit_Root_CBD_MacroStepPrepared()
		if self.Root_CBD_Started in self.current_state[self.Root_CBD]:
			self.exit_Root_CBD_Started()
		if self.Root_CBD_Initialized in self.current_state[self.Root_CBD]:
			self.exit_Root_CBD_Initialized()
		if self.Root_CBD_MacroStepProcessed in self.current_state[self.Root_CBD]:
			self.exit_Root_CBD_MacroStepProcessed()
		if self.Root_CBD_MicroStepPrepared in self.current_state[self.Root_CBD]:
			self.exit_Root_CBD_MicroStepPrepared()
		if self.Root_CBD_MicroStepProcessed in self.current_state[self.Root_CBD]:
			self.exit_Root_CBD_MicroStepProcessed()
		self.current_state[self.Root] = []
	
	def enter_Root_ChildInitialized(self):
		self.current_state[self.Root].append(self.Root_ChildInitialized)
	
	def exit_Root_ChildInitialized(self):
		self.current_state[self.Root] = []
	
	def enter_Root_ChildNotInitialized(self):
		self.current_state[self.Root].append(self.Root_ChildNotInitialized)
	
	def exit_Root_ChildNotInitialized(self):
		self.current_state[self.Root] = []
	
	def enter_Root_ChildProcessed(self):
		self.current_state[self.Root].append(self.Root_ChildProcessed)
	
	def exit_Root_ChildProcessed(self):
		self.current_state[self.Root] = []
	
	def enter_Root_ChildDetected(self):
		self.current_state[self.Root].append(self.Root_ChildDetected)
	
	def exit_Root_ChildDetected(self):
		self.current_state[self.Root] = []
	
	def enter_Root_ChildPaused(self):
		self.current_state[self.Root].append(self.Root_ChildPaused)
	
	def exit_Root_ChildPaused(self):
		self.current_state[self.Root] = []
	
	def enter_Root_HybridTerminated(self):
		self.current_state[self.Root].append(self.Root_HybridTerminated)
	
	def exit_Root_HybridTerminated(self):
		self.current_state[self.Root] = []
	
	def enter_Root_ChildNotDetected(self):
		self.current_state[self.Root].append(self.Root_ChildNotDetected)
	
	def exit_Root_ChildNotDetected(self):
		self.current_state[self.Root] = []
	
	def enter_Root_FSA_Started(self):
		self.current_state[self.Root_FSA].append(self.Root_FSA_Started)
	
	def exit_Root_FSA_Started(self):
		self.current_state[self.Root_FSA] = []
	
	def enter_Root_FSA_Terminated(self):
		self.current_state[self.Root_FSA].append(self.Root_FSA_Terminated)
	
	def exit_Root_FSA_Terminated(self):
		self.current_state[self.Root_FSA] = []
	
	def enter_Root_FSA_Initialized(self):
		self.current_state[self.Root_FSA].append(self.Root_FSA_Initialized)
	
	def exit_Root_FSA_Initialized(self):
		self.current_state[self.Root_FSA] = []
	
	def enter_Root_FSA_MacroStepProcessed(self):
		self.current_state[self.Root_FSA].append(self.Root_FSA_MacroStepProcessed)
	
	def exit_Root_FSA_MacroStepProcessed(self):
		self.current_state[self.Root_FSA] = []
	
	def enter_Root_FSA_MicroStepProcessed(self):
		self.current_state[self.Root_FSA].append(self.Root_FSA_MicroStepProcessed)
	
	def exit_Root_FSA_MicroStepProcessed(self):
		self.current_state[self.Root_FSA] = []
	
	def enter_Root_FSA_MacroStepPrepared(self):
		self.current_state[self.Root_FSA].append(self.Root_FSA_MacroStepPrepared)
	
	def exit_Root_FSA_MacroStepPrepared(self):
		self.current_state[self.Root_FSA] = []
	
	def enter_Root_FSA_MicroStepPrepared(self):
		self.current_state[self.Root_FSA].append(self.Root_FSA_MicroStepPrepared)
	
	def exit_Root_FSA_MicroStepPrepared(self):
		self.current_state[self.Root_FSA] = []
	
	def enter_Root_ParentPaused(self):
		self.current_state[self.Root].append(self.Root_ParentPaused)
	
	def exit_Root_ParentPaused(self):
		self.current_state[self.Root] = []
	
	def enter_Root_CBD_Terminated(self):
		self.current_state[self.Root_CBD].append(self.Root_CBD_Terminated)
	
	def exit_Root_CBD_Terminated(self):
		self.current_state[self.Root_CBD] = []
	
	def enter_Root_CBD_MacroStepPrepared(self):
		self.current_state[self.Root_CBD].append(self.Root_CBD_MacroStepPrepared)
	
	def exit_Root_CBD_MacroStepPrepared(self):
		self.current_state[self.Root_CBD] = []
	
	def enter_Root_CBD_Started(self):
		self.current_state[self.Root_CBD].append(self.Root_CBD_Started)
	
	def exit_Root_CBD_Started(self):
		self.current_state[self.Root_CBD] = []
	
	def enter_Root_CBD_Initialized(self):
		self.current_state[self.Root_CBD].append(self.Root_CBD_Initialized)
	
	def exit_Root_CBD_Initialized(self):
		self.current_state[self.Root_CBD] = []
	
	def enter_Root_CBD_MacroStepProcessed(self):
		self.current_state[self.Root_CBD].append(self.Root_CBD_MacroStepProcessed)
	
	def exit_Root_CBD_MacroStepProcessed(self):
		self.current_state[self.Root_CBD] = []
	
	def enter_Root_CBD_MicroStepPrepared(self):
		self.current_state[self.Root_CBD].append(self.Root_CBD_MicroStepPrepared)
	
	def exit_Root_CBD_MicroStepPrepared(self):
		self.current_state[self.Root_CBD] = []
	
	def enter_Root_CBD_MicroStepProcessed(self):
		self.current_state[self.Root_CBD].append(self.Root_CBD_MicroStepProcessed)
	
	def exit_Root_CBD_MicroStepProcessed(self):
		self.current_state[self.Root_CBD] = []
	
	# Statechart enter/exit default method(s)
	
	def enterDefault_Root_FSA(self):
		self.enter_Root_FSA()
		self.enter_Root_FSA_Started()
	
	def enterDefault_Root_CBD(self):
		self.enter_Root_CBD()
		self.enter_Root_CBD_Started()
	
	# Statechart transitions
	
	def generateCandidatesChildren_Root(self):
		if self.current_state[self.Root][0] == self.Root_ChildInitialized:
			return self.generateCandidates_Root_ChildInitialized()
		elif self.current_state[self.Root][0] == self.Root_ChildNotInitialized:
			return self.generateCandidates_Root_ChildNotInitialized()
		elif self.current_state[self.Root][0] == self.Root_ChildProcessed:
			return self.generateCandidates_Root_ChildProcessed()
		elif self.current_state[self.Root][0] == self.Root_ChildDetected:
			return self.generateCandidates_Root_ChildDetected()
		elif self.current_state[self.Root][0] == self.Root_ChildPaused:
			return self.generateCandidates_Root_ChildPaused()
		elif self.current_state[self.Root][0] == self.Root_HybridTerminated:
			return self.generateCandidates_Root_HybridTerminated()
		elif self.current_state[self.Root][0] == self.Root_ChildNotDetected:
			return self.generateCandidates_Root_ChildNotDetected()
		elif self.current_state[self.Root][0] == self.Root_FSA:
			return self.generateCandidates_Root_FSA()
		elif self.current_state[self.Root][0] == self.Root_ParentPaused:
			return self.generateCandidates_Root_ParentPaused()
		elif self.current_state[self.Root][0] == self.Root_CBD:
			return self.generateCandidates_Root_CBD()
		return False
	
	def generateCandidates_Root(self):
		if not self.combo_step.isArenaChanged(self.Root):
			return self.generateCandidatesChildren_Root()
		else:
			return True
	
	def generateCandidatesCurrent_Root_ChildInitialized(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_ChildInitialized_1, [])
		return True
		return False
	
	def generateCandidates_Root_ChildInitialized(self):
		if not self.combo_step.isArenaChanged(self.Root_ChildInitialized):
			return self.generateCandidatesCurrent_Root_ChildInitialized()
		else:
			return True
	
	def transition_Root_ChildInitialized_1(self, parameters):
		self.exit_Root_ChildInitialized()
		print('From ChildInitialized to CBD/MacroStepProcessed... ')
		comp = self.cbd_strongComponentList[self.cbd_currentCompIdx][0]
		self.fsa_logicalTime = self.woven_logical_time_fsas[comp.getBlockName()]
		self.fsa_elapsed = self.woven_elapsed_fsas[comp.getBlockName()]
		self.fsa_currentState = self.woven_current_state_fsas[comp.getBlockName()]
		self.fsa_model = comp.fsa
		self.fsa_logicalTime = self.fsa_logicalTime + self.fsa_timestep
		self.fsa_elapsed = self.fsa_elapsed + self.fsa_timestep
		self.woven_updateEventsTriggeredByZeroCrossing(self.fsa_logicalTime, comp, self.fsa_currentState)
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_FSA()
		self.enter_Root_FSA_MacroStepProcessed()
	
	def generateCandidatesCurrent_Root_ChildNotInitialized(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_ChildNotInitialized_1, [])
		return True
		return False
	
	def generateCandidates_Root_ChildNotInitialized(self):
		if not self.combo_step.isArenaChanged(self.Root_ChildNotInitialized):
			return self.generateCandidatesCurrent_Root_ChildNotInitialized()
		else:
			return True
	
	def transition_Root_ChildNotInitialized_1(self, parameters):
		self.exit_Root_ChildNotInitialized()
		print('From ChildNotInitialized to CBD/Started... ')
		comp = self.cbd_strongComponentList[self.cbd_currentCompIdx][0]
		self.fsa_model = comp.fsa
		self.woven_updateEventsTriggeredByZeroCrossing(self.cbd_clock, comp, comp.fsa.initialState)
		self.woven_processing_fsa[comp.getBlockName()] = True
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_FSA()
		self.enter_Root_FSA_Started()
	
	def generateCandidatesCurrent_Root_ChildProcessed(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_ChildProcessed_1, [])
		return True
		return False
	
	def generateCandidates_Root_ChildProcessed(self):
		if not self.combo_step.isArenaChanged(self.Root_ChildProcessed):
			return self.generateCandidatesCurrent_Root_ChildProcessed()
		else:
			return True
	
	def transition_Root_ChildProcessed_1(self, parameters):
		self.exit_Root_ChildProcessed()
		print('From ChildProcessed to CBD/MicroStepProcessed and incrementing cbd_currentCompIdx...')
		self.cbd_currentCompIdx = self.cbd_currentCompIdx + 1
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_CBD()
		self.enter_Root_CBD_MicroStepProcessed()
	
	def generateCandidatesCurrent_Root_ChildDetected(self):
		enabled_events = self.getEnabledEvents()
		if not self.woven_processing_fsa.has_key(self.cbd_strongComponentList[self.cbd_currentCompIdx][0].getBlockName()) or not self.woven_processing_fsa[self.cbd_strongComponentList[self.cbd_currentCompIdx][0].getBlockName()]:
			self.small_step.addCandidate(self.transition_Root_ChildDetected_1, [])
			return True
		enabled_events = self.getEnabledEvents()
		if self.woven_processing_fsa.has_key(self.cbd_strongComponentList[self.cbd_currentCompIdx][0].getBlockName()) and self.woven_processing_fsa[self.cbd_strongComponentList[self.cbd_currentCompIdx][0].getBlockName()]:
			self.small_step.addCandidate(self.transition_Root_ChildDetected_2, [])
			return True
		return False
	
	def generateCandidates_Root_ChildDetected(self):
		if not self.combo_step.isArenaChanged(self.Root_ChildDetected):
			return self.generateCandidatesCurrent_Root_ChildDetected()
		else:
			return True
	
	def transition_Root_ChildDetected_1(self, parameters):
		self.exit_Root_ChildDetected()
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_ChildNotInitialized()
	
	def transition_Root_ChildDetected_2(self, parameters):
		self.exit_Root_ChildDetected()
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_ChildInitialized()
	
	def generateCandidatesCurrent_Root_ChildPaused(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_ChildPaused_1, [])
		return True
		return False
	
	def generateCandidates_Root_ChildPaused(self):
		if not self.combo_step.isArenaChanged(self.Root_ChildPaused):
			return self.generateCandidatesCurrent_Root_ChildPaused()
		else:
			return True
	
	def transition_Root_ChildPaused_1(self, parameters):
		self.exit_Root_ChildPaused()
		print('From ChildPaused to ChildProcessed...')
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_ChildProcessed()
	
	def generateCandidates_Root_HybridTerminated(self):
		return False
	
	def generateCandidatesCurrent_Root_ChildNotDetected(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_ChildNotDetected_1, [])
		return True
		return False
	
	def generateCandidates_Root_ChildNotDetected(self):
		if not self.combo_step.isArenaChanged(self.Root_ChildNotDetected):
			return self.generateCandidatesCurrent_Root_ChildNotDetected()
		else:
			return True
	
	def transition_Root_ChildNotDetected_1(self, parameters):
		self.exit_Root_ChildNotDetected()
		print('From ChildProcessed to CBD/MicroStepPrepared...')
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_CBD()
		self.enter_Root_CBD_MicroStepPrepared()
	
	def generateCandidatesChildren_Root_FSA(self):
		if self.current_state[self.Root_FSA][0] == self.Root_FSA_Started:
			return self.generateCandidates_Root_FSA_Started()
		elif self.current_state[self.Root_FSA][0] == self.Root_FSA_Terminated:
			return self.generateCandidates_Root_FSA_Terminated()
		elif self.current_state[self.Root_FSA][0] == self.Root_FSA_Initialized:
			return self.generateCandidates_Root_FSA_Initialized()
		elif self.current_state[self.Root_FSA][0] == self.Root_FSA_MacroStepProcessed:
			return self.generateCandidates_Root_FSA_MacroStepProcessed()
		elif self.current_state[self.Root_FSA][0] == self.Root_FSA_MicroStepProcessed:
			return self.generateCandidates_Root_FSA_MicroStepProcessed()
		elif self.current_state[self.Root_FSA][0] == self.Root_FSA_MacroStepPrepared:
			return self.generateCandidates_Root_FSA_MacroStepPrepared()
		elif self.current_state[self.Root_FSA][0] == self.Root_FSA_MicroStepPrepared:
			return self.generateCandidates_Root_FSA_MicroStepPrepared()
		return False
	
	def generateCandidates_Root_FSA(self):
		if not self.combo_step.isArenaChanged(self.Root_FSA):
			return self.generateCandidatesChildren_Root_FSA()
		else:
			return True
	
	def generateCandidatesCurrent_Root_FSA_Started(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_FSA_Started_1, [])
		return True
		return False
	
	def generateCandidates_Root_FSA_Started(self):
		if not self.combo_step.isArenaChanged(self.Root_FSA_Started):
			return self.generateCandidatesCurrent_Root_FSA_Started()
		else:
			return True
	
	def transition_Root_FSA_Started_1(self, parameters):
		self.exit_Root_FSA_Started()
		print('From FSA/Started to Initialized... ')
		self.weaved_delta = min(self.fsa_timestep, self.cbd_delta)
		self.fsa_logicalTime = 0.0
		self.fsa_elapsed = 0
		self.fsa_timestep = self.weaved_delta
		self.fsa_currentState = self.fsa_model.initialState
		self.combo_step.setArenaChanged(self.Root_FSA)
		self.enter_Root_FSA_Initialized()
	
	def generateCandidatesCurrent_Root_FSA_Terminated(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_FSA_Terminated_1, [])
		return True
		return False
	
	def generateCandidates_Root_FSA_Terminated(self):
		if not self.combo_step.isArenaChanged(self.Root_FSA_Terminated):
			return self.generateCandidatesCurrent_Root_FSA_Terminated()
		else:
			return True
	
	def transition_Root_FSA_Terminated_1(self, parameters):
		self.exit_Root_FSA()
		print('From FSA/Terminated to HybridTerminated... ')
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_HybridTerminated()
	
	def generateCandidatesCurrent_Root_FSA_Initialized(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_FSA_Initialized_1, [])
		return True
		return False
	
	def generateCandidates_Root_FSA_Initialized(self):
		if not self.combo_step.isArenaChanged(self.Root_FSA_Initialized):
			return self.generateCandidatesCurrent_Root_FSA_Initialized()
		else:
			return True
	
	def transition_Root_FSA_Initialized_1(self, parameters):
		self.exit_Root_FSA_Initialized()
		print('From FSA/Initialized to MacroStepProcessed... ')
		self.combo_step.setArenaChanged(self.Root_FSA)
		self.enter_Root_FSA_MacroStepProcessed()
	
	def generateCandidatesCurrent_Root_FSA_MacroStepProcessed(self):
		enabled_events = self.getEnabledEvents()
		if self.fsa_currentState.final:
			self.small_step.addCandidate(self.transition_Root_FSA_MacroStepProcessed_1, [])
			return True
		enabled_events = self.getEnabledEvents()
		if not self.fsa_currentState.final:
			self.small_step.addCandidate(self.transition_Root_FSA_MacroStepProcessed_2, [])
			return True
		return False
	
	def generateCandidates_Root_FSA_MacroStepProcessed(self):
		if not self.combo_step.isArenaChanged(self.Root_FSA_MacroStepProcessed):
			return self.generateCandidatesCurrent_Root_FSA_MacroStepProcessed()
		else:
			return True
	
	def transition_Root_FSA_MacroStepProcessed_1(self, parameters):
		self.exit_Root_FSA_MacroStepProcessed()
		print('From FSA/MacroStepProcessed to Terminated... ')
		self.combo_step.setArenaChanged(self.Root_FSA)
		self.enter_Root_FSA_Terminated()
	
	def transition_Root_FSA_MacroStepProcessed_2(self, parameters):
		self.exit_Root_FSA_MacroStepProcessed()
		print('From FSA/MacroStepProcessed to MacroStepPrepared and reading events... ')
		self.fsa_currentEvent = self.fsa_getInputEventAt(self.fsa_logicalTime)
		self.fsa_selectedTransition = self.fsa_model.getTransitionFrom(self.fsa_currentState, self.fsa_currentEvent, self.fsa_elapsed)
		print(self.fsa_currentEvent)
		print(self.fsa_selectedTransition)
		self.combo_step.setArenaChanged(self.Root_FSA)
		self.enter_Root_FSA_MacroStepPrepared()
	
	def generateCandidatesCurrent_Root_FSA_MicroStepProcessed(self):
		enabled_events = self.getEnabledEvents()
		if self.fsa_selectedTransition == None and False:
			self.small_step.addCandidate(self.transition_Root_FSA_MicroStepProcessed_1, [])
			return True
		enabled_events = self.getEnabledEvents()
		if self.fsa_selectedTransition == None:
			self.small_step.addCandidate(self.transition_Root_FSA_MicroStepProcessed_2, [])
			return True
		enabled_events = self.getEnabledEvents()
		if self.fsa_selectedTransition != None:
			self.small_step.addCandidate(self.transition_Root_FSA_MicroStepProcessed_3, [])
			return True
		return False
	
	def generateCandidates_Root_FSA_MicroStepProcessed(self):
		if not self.combo_step.isArenaChanged(self.Root_FSA_MicroStepProcessed):
			return self.generateCandidatesCurrent_Root_FSA_MicroStepProcessed()
		else:
			return True
	
	def transition_Root_FSA_MicroStepProcessed_1(self, parameters):
		self.exit_Root_FSA_MicroStepProcessed()
		print('From FSA/MicroStepProcessed to MacroStepProcessed and advancing time... ')
		self.fsa_logicalTime = self.fsa_logicalTime + self.fsa_timestep
		self.fsa_elapsed = self.fsa_elapsed + self.fsa_timestep
		print(self.fsa_logicalTime)
		print(self.fsa_elapsed)
		self.combo_step.setArenaChanged(self.Root_FSA)
		self.enter_Root_FSA_MacroStepProcessed()
	
	def transition_Root_FSA_MicroStepProcessed_2(self, parameters):
		self.exit_Root_FSA()
		print('From FSA/MicroStepProcessed to ChildPaused and saving outputs... ')
		comp = self.cbd_strongComponentList[self.cbd_currentCompIdx][0]
		self.woven_logical_time_fsas[comp.getBlockName()] = self.fsa_logicalTime
		self.woven_elapsed_fsas[comp.getBlockName()] = self.fsa_elapsed
		self.woven_current_state_fsas[comp.getBlockName()] = self.fsa_currentState
		self.woven_updateOutputFSA(self.cbd_iteration, self.fsa_logicalTime, comp, self.fsa_currentState)
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_ChildPaused()
	
	def transition_Root_FSA_MicroStepProcessed_3(self, parameters):
		self.exit_Root_FSA_MicroStepProcessed()
		print('From FSA/MicroStepProcessed to MicroStepPrepared... ')
		self.combo_step.setArenaChanged(self.Root_FSA)
		self.enter_Root_FSA_MicroStepPrepared()
	
	def generateCandidatesCurrent_Root_FSA_MacroStepPrepared(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_FSA_MacroStepPrepared_1, [])
		return True
		return False
	
	def generateCandidates_Root_FSA_MacroStepPrepared(self):
		if not self.combo_step.isArenaChanged(self.Root_FSA_MacroStepPrepared):
			return self.generateCandidatesCurrent_Root_FSA_MacroStepPrepared()
		else:
			return True
	
	def transition_Root_FSA_MacroStepPrepared_1(self, parameters):
		self.exit_Root_FSA_MacroStepPrepared()
		print('From FSA/MacroStepPrepared to MicroStepProcessed... ')
		self.combo_step.setArenaChanged(self.Root_FSA)
		self.enter_Root_FSA_MicroStepProcessed()
	
	def generateCandidatesCurrent_Root_FSA_MicroStepPrepared(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_FSA_MicroStepPrepared_1, [])
		return True
		return False
	
	def generateCandidates_Root_FSA_MicroStepPrepared(self):
		if not self.combo_step.isArenaChanged(self.Root_FSA_MicroStepPrepared):
			return self.generateCandidatesCurrent_Root_FSA_MicroStepPrepared()
		else:
			return True
	
	def transition_Root_FSA_MicroStepPrepared_1(self, parameters):
		self.exit_Root_FSA_MicroStepPrepared()
		print('From FSA/MicroStepPrepared to MicroStepProcessed and attempting to take transition... ')
		print('Transition to be taken: ' + str(self.fsa_selectedTransition))
		self.fsa_currentState = self.fsa_selectedTransition.target
		self.fsa_elapsed = 0
		self.fsa_processEvent(self.fsa_currentEvent)
		print('New state: ' + str(self.fsa_currentState))
		self.plotter.storeDiscreteEvent(self.cbd_strongComponentList[self.cbd_currentCompIdx][0], self.fsa_logicalTime, self.fsa_currentState, self.fsa_selectedTransition)
		print('Reading events:')
		self.fsa_currentEvent = self.fsa_getInputEventAt(self.fsa_logicalTime)
		self.fsa_selectedTransition = self.fsa_model.getTransitionFrom(self.fsa_currentState, self.fsa_currentEvent, self.fsa_elapsed)
		print(self.fsa_currentEvent)
		print(self.fsa_selectedTransition)
		self.combo_step.setArenaChanged(self.Root_FSA)
		self.enter_Root_FSA_MicroStepProcessed()
	
	def generateCandidatesCurrent_Root_ParentPaused(self):
		enabled_events = self.getEnabledEvents()
		if not isinstance(self.cbd_strongComponentList[self.cbd_currentCompIdx][0], FSABlock):
			self.small_step.addCandidate(self.transition_Root_ParentPaused_1, [])
			return True
		enabled_events = self.getEnabledEvents()
		if isinstance(self.cbd_strongComponentList[self.cbd_currentCompIdx][0], FSABlock):
			self.small_step.addCandidate(self.transition_Root_ParentPaused_2, [])
			return True
		return False
	
	def generateCandidates_Root_ParentPaused(self):
		if not self.combo_step.isArenaChanged(self.Root_ParentPaused):
			return self.generateCandidatesCurrent_Root_ParentPaused()
		else:
			return True
	
	def transition_Root_ParentPaused_1(self, parameters):
		self.exit_Root_ParentPaused()
		print('From ParentPaused to ChildNotDetected...')
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_ChildNotDetected()
	
	def transition_Root_ParentPaused_2(self, parameters):
		self.exit_Root_ParentPaused()
		print('From ParentPaused to ChildDetected...')
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_ChildDetected()
	
	def generateCandidatesChildren_Root_CBD(self):
		if self.current_state[self.Root_CBD][0] == self.Root_CBD_Terminated:
			return self.generateCandidates_Root_CBD_Terminated()
		elif self.current_state[self.Root_CBD][0] == self.Root_CBD_MacroStepPrepared:
			return self.generateCandidates_Root_CBD_MacroStepPrepared()
		elif self.current_state[self.Root_CBD][0] == self.Root_CBD_Started:
			return self.generateCandidates_Root_CBD_Started()
		elif self.current_state[self.Root_CBD][0] == self.Root_CBD_Initialized:
			return self.generateCandidates_Root_CBD_Initialized()
		elif self.current_state[self.Root_CBD][0] == self.Root_CBD_MacroStepProcessed:
			return self.generateCandidates_Root_CBD_MacroStepProcessed()
		elif self.current_state[self.Root_CBD][0] == self.Root_CBD_MicroStepPrepared:
			return self.generateCandidates_Root_CBD_MicroStepPrepared()
		elif self.current_state[self.Root_CBD][0] == self.Root_CBD_MicroStepProcessed:
			return self.generateCandidates_Root_CBD_MicroStepProcessed()
		return False
	
	def generateCandidates_Root_CBD(self):
		if not self.combo_step.isArenaChanged(self.Root_CBD):
			return self.generateCandidatesChildren_Root_CBD()
		else:
			return True
	
	def generateCandidatesCurrent_Root_CBD_Terminated(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_CBD_Terminated_1, [])
		return True
		return False
	
	def generateCandidates_Root_CBD_Terminated(self):
		if not self.combo_step.isArenaChanged(self.Root_CBD_Terminated):
			return self.generateCandidatesCurrent_Root_CBD_Terminated()
		else:
			return True
	
	def transition_Root_CBD_Terminated_1(self, parameters):
		self.exit_Root_CBD()
		print('From CBD/Terminated to HybridTerminated... ')
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_HybridTerminated()
	
	def generateCandidatesCurrent_Root_CBD_MacroStepPrepared(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_CBD_MacroStepPrepared_1, [])
		return True
		return False
	
	def generateCandidates_Root_CBD_MacroStepPrepared(self):
		if not self.combo_step.isArenaChanged(self.Root_CBD_MacroStepPrepared):
			return self.generateCandidatesCurrent_Root_CBD_MacroStepPrepared()
		else:
			return True
	
	def transition_Root_CBD_MacroStepPrepared_1(self, parameters):
		self.exit_Root_CBD_MacroStepPrepared()
		print('From CBD/MacroStepPrepared to MicroStepProcessed... ')
		self.combo_step.setArenaChanged(self.Root_CBD)
		self.enter_Root_CBD_MicroStepProcessed()
	
	def generateCandidatesCurrent_Root_CBD_Started(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_CBD_Started_1, [])
		return True
		return False
	
	def generateCandidates_Root_CBD_Started(self):
		if not self.combo_step.isArenaChanged(self.Root_CBD_Started):
			return self.generateCandidatesCurrent_Root_CBD_Started()
		else:
			return True
	
	def transition_Root_CBD_Started_1(self, parameters):
		self.exit_Root_CBD_Started()
		print('From CBD/Started to Initialized... ')
		self.cbd_iteration = 0
		self.cbd_clock = 0.0
		self.cbd_controller = CBDController(self.cbd_model, self.cbd_delta)
		self.cbd_controller.initSimulation()
		print('CBD clock: ' + str(self.cbd_clock))
		print('CBD iteration: ' + str(self.cbd_iteration))
		self.combo_step.setArenaChanged(self.Root_CBD)
		self.enter_Root_CBD_Initialized()
	
	def generateCandidatesCurrent_Root_CBD_Initialized(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_CBD_Initialized_1, [])
		return True
		return False
	
	def generateCandidates_Root_CBD_Initialized(self):
		if not self.combo_step.isArenaChanged(self.Root_CBD_Initialized):
			return self.generateCandidatesCurrent_Root_CBD_Initialized()
		else:
			return True
	
	def transition_Root_CBD_Initialized_1(self, parameters):
		self.exit_Root_CBD_Initialized()
		print('From CBD/Initialized to MacroStepProcessed... ')
		self.combo_step.setArenaChanged(self.Root_CBD)
		self.enter_Root_CBD_MacroStepProcessed()
	
	def generateCandidatesCurrent_Root_CBD_MacroStepProcessed(self):
		enabled_events = self.getEnabledEvents()
		if self.cbd_maxIterationsReached():
			self.small_step.addCandidate(self.transition_Root_CBD_MacroStepProcessed_1, [])
			return True
		enabled_events = self.getEnabledEvents()
		if not self.cbd_maxIterationsReached():
			self.small_step.addCandidate(self.transition_Root_CBD_MacroStepProcessed_2, [])
			return True
		return False
	
	def generateCandidates_Root_CBD_MacroStepProcessed(self):
		if not self.combo_step.isArenaChanged(self.Root_CBD_MacroStepProcessed):
			return self.generateCandidatesCurrent_Root_CBD_MacroStepProcessed()
		else:
			return True
	
	def transition_Root_CBD_MacroStepProcessed_1(self, parameters):
		self.exit_Root_CBD_MacroStepProcessed()
		print('From CBD/MacroStepProcessed to Terminated... ')
		self.combo_step.setArenaChanged(self.Root_CBD)
		self.enter_Root_CBD_Terminated()
	
	def transition_Root_CBD_MacroStepProcessed_2(self, parameters):
		self.exit_Root_CBD_MacroStepProcessed()
		print('From CBD/MacroStepProcessed to MacroStepPrepared... ')
		self.cbd_currentCompIdx = 0
		self.cbd_depGraph = self.cbd_controller.createDepGraph(self.cbd_iteration)
		self.cbd_strongComponentList = self.cbd_controller.createStrongComponents(self.cbd_depGraph, self.cbd_iteration)
		self.combo_step.setArenaChanged(self.Root_CBD)
		self.enter_Root_CBD_MacroStepPrepared()
	
	def generateCandidatesCurrent_Root_CBD_MicroStepPrepared(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_CBD_MicroStepPrepared_1, [])
		return True
		return False
	
	def generateCandidates_Root_CBD_MicroStepPrepared(self):
		if not self.combo_step.isArenaChanged(self.Root_CBD_MicroStepPrepared):
			return self.generateCandidatesCurrent_Root_CBD_MicroStepPrepared()
		else:
			return True
	
	def transition_Root_CBD_MicroStepPrepared_1(self, parameters):
		self.exit_Root_CBD_MicroStepPrepared()
		print('From CBD/MicroStepPrepared to MicroStepProcessed...')
		self.cbd_computeBlock()
		print('After compute block')
		self.cbd_currentCompIdx = self.cbd_currentCompIdx + 1
		print('After cbd_currentCompIdx')
		print('Has next:' + str(self.cbd_hasNextStrongComponent()))
		self.combo_step.setArenaChanged(self.Root_CBD)
		self.enter_Root_CBD_MicroStepProcessed()
	
	def generateCandidatesCurrent_Root_CBD_MicroStepProcessed(self):
		enabled_events = self.getEnabledEvents()
		if self.cbd_hasNextStrongComponent():
			self.small_step.addCandidate(self.transition_Root_CBD_MicroStepProcessed_1, [])
			return True
		enabled_events = self.getEnabledEvents()
		if self.cbd_hasNextStrongComponent() and False:
			self.small_step.addCandidate(self.transition_Root_CBD_MicroStepProcessed_2, [])
			return True
		enabled_events = self.getEnabledEvents()
		if not self.cbd_hasNextStrongComponent():
			self.small_step.addCandidate(self.transition_Root_CBD_MicroStepProcessed_3, [])
			return True
		return False
	
	def generateCandidates_Root_CBD_MicroStepProcessed(self):
		if not self.combo_step.isArenaChanged(self.Root_CBD_MicroStepProcessed):
			return self.generateCandidatesCurrent_Root_CBD_MicroStepProcessed()
		else:
			return True
	
	def transition_Root_CBD_MicroStepProcessed_1(self, parameters):
		self.exit_Root_CBD()
		print('From CBD/MicroStepProcessed to ParentPaused')
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_ParentPaused()
	
	def transition_Root_CBD_MicroStepProcessed_2(self, parameters):
		self.exit_Root_CBD_MicroStepProcessed()
		print('From CBD/MicroStepProcessed to MicroStepPrepared')
		self.combo_step.setArenaChanged(self.Root_CBD)
		self.enter_Root_CBD_MicroStepPrepared()
	
	def transition_Root_CBD_MicroStepProcessed_3(self, parameters):
		self.exit_Root_CBD_MicroStepProcessed()
		print('From CBD/MicroStepProcessed to MacroStepProcessed and advancing time... ')
		self.plotter.store(self.cbd_iteration, self.cbd_clock, self.woven_current_state_fsas)
		self.cbd_iteration = self.cbd_iteration + 1
		self.cbd_clock = self.cbd_clock + self.cbd_delta
		self.cbd_controller.advanceTimeStep()
		print(self.cbd_clock)
		print(self.cbd_iteration)
		self.combo_step.setArenaChanged(self.Root_CBD)
		self.enter_Root_CBD_MacroStepProcessed()
	
	# 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 == "Woven_CBD_TFSA_Simulator":
			instance = Woven_CBD_TFSA_Simulator(self.controller, construct_params[0], construct_params[1], construct_params[2])
			instance.associations = {}
		return instance

class Controller(ThreadsControllerBase):
	def __init__(self, cbd_options, amodel, plotter, keep_running = None):
		if keep_running == None: keep_running = True
		ThreadsControllerBase.__init__(self, ObjectManager(self), keep_running)
		self.object_manager.createInstance("Woven_CBD_TFSA_Simulator", [cbd_options, amodel, plotter])