# Python source code generated by SCC (StateChart Compiler) 0.1, written by Thomas Feng
#   Source: TrafficLightBehaviour.des
#   Date:   March 25, 2004
#   Time:   21:46:34


# Header Section -- definition and module importation used by the following parts
import sys
import copy
import time
import string


class State:

  def __init__(self):

    self.StateID=-1
    self.Next=None


class History:

  def __init__(self):

    self.States=None
    self.Times=None
    self.Submodel=None


class EventList:

  def __init__(self):

    self.Event=None
    self.Next=None

  def Append(self, e):

    if isinstance(e, str):
      el=EventList()
      el.Event=e
      cur=this
      while cur.Next!=None and cur.Event!=e:
        cur=cur.Next;
      if cur.Event!=e:
        cur.Next=el

    elif isinstance(e, EventList):
      el=e
      while el!=None:
        self.Append(el.Event)
        el=el.Next


class StringList:

  def __init__(self, str=""):

    self.str=str
    self.Next=None


class IntList:

  def __init__(self, int=0):

    self.int=int
    self.Next=None


class Hierarchy:

  def __init__(self):

    self.StateName=None
    self.PathName=None
    self.StateNum=-1
    self.Level=-1
    self.Next=None


# Scheduler for timed transitions (used only when --ext is set)
import thread
import time
class Scheduler:

  def __init__(self, model, event, interval, repeat):

    self.Model=model
    self.Event=event
    self.Interval=interval
    self.Repeat=repeat
    self.Lock=thread.allocate_lock()
    self.Stopped=0
    self.Next=None

  def start(self):

    thread.start_new_thread(self.run, ())

  def stop(self):

    self.Lock.acquire()
    self.Stopped=1
    self.Lock.release()

  def clear(self):

    self.stop()
    if self.Next:
      self.Next.clear()

  def run(self):

    stopped=0
    while not stopped:
      time.sleep(self.Interval)
      self.Lock.acquire()
      stopped=self.Stopped
      self.Lock.release()
      if not stopped:
        self.Model.event(self.Event, [], None, 0)
        stopped=not self.Repeat


class StateMachine:

  def eventStr2Int(self, event):

    return -1

  def getCurrentStateList(self):

    return None

  def getCurrentState(self):

    return "[]"

  def getEnabledEvents(self):

    return None

  def initModel(self, run_initializer=1, run_enter_actions=1):

    pass

  def isInState(self, s):

    return 0

  def getParentState(self, state):

    return -1

  def isHistoryState(self, state):

    return 0

  def isLeafState(self, state):

    return 0

  def getHierarchy(self, start_level=0, state_prefix=None):

    return None

  def topLevelHistory(self):

    pass

  def recordAllEnteredStates(self):

    pass

  def runAllEnterActions(self):

    pass

  def runInitializer(self):

    pass

  def runFinalizer(self):

    pass

  def runInteractor(self):

    pass

  def state(self):

    pass

  def handleEvent(self, se, params=[], lock=None, call_submodels=1):

    return 0

  def event(self, e, params=[], lock=None, call_submodels=1):

    pass


def startswith(s, ss):

  return ss==None or (s!=None and len(s)>=len(ss) and s[0:len(ss)]==ss)


# used only when --ext is set
from code import InteractiveInterpreter


# Main Class -- the top level model that is executed from the command line
class TrafficLightBehaviour(StateMachine):

  # Constants for this model
  StateNum=12
  EventNames=["CROSSWALK",
              "ON-OFF",
              "POLICE",
              "QUIT",
              "__INTERNAL_0_TIME_0",
              "__INTERNAL_0_TIME_1",
              "__INTERNAL_0_TIME_2",
              "__INTERNAL_0_TIME_3",
              "__INTERNAL_0_TIME_4",
              "__INTERNAL_0_TIME_5" 
             ]
  StateNames=["DEAD",
              "OFF",
              "ON",
              "ON.FLASHING",
              "ON.FLASHING.YELLOW_OFF",
              "ON.FLASHING.YELLOW_ON",
              "ON.NORMAL",
              "ON.NORMAL.GREEN",
              "ON.NORMAL.RED",
              "ON.NORMAL.RED.GREEN_SOON",
              "ON.NORMAL.RED.RED_WAIT",
              "ON.NORMAL.YELLOW" 
             ]
  ParentTable=[-1,  # DEAD -- parent (None)
               -1,  # OFF -- parent (None)
               -1,  # ON -- parent (None)
               2,  # ON.FLASHING -- parent ON
               3,  # ON.FLASHING.YELLOW_OFF -- parent ON.FLASHING
               3,  # ON.FLASHING.YELLOW_ON -- parent ON.FLASHING
               2,  # ON.NORMAL -- parent ON
               6,  # ON.NORMAL.GREEN -- parent ON.NORMAL
               6,  # ON.NORMAL.RED -- parent ON.NORMAL
               8,  # ON.NORMAL.RED.GREEN_SOON -- parent ON.NORMAL.RED
               8,  # ON.NORMAL.RED.RED_WAIT -- parent ON.NORMAL.RED
               6   # ON.NORMAL.YELLOW -- parent ON.NORMAL
              ]
  HistoryStateTable=[0,
                     0,
                     2,
                     0,
                     0,
                     0,
                     0,
                     0,
                     0,
                     0,
                     0,
                     0 
                    ]
  LeafStateTable=["DEAD",
                  "OFF",
                  None,
                  None,
                  "ON.FLASHING.YELLOW_OFF",
                  "ON.FLASHING.YELLOW_ON",
                  None,
                  "ON.NORMAL.GREEN",
                  None,
                  "ON.NORMAL.RED.GREEN_SOON",
                  "ON.NORMAL.RED.RED_WAIT",
                  "ON.NORMAL.YELLOW" 
                 ]
  OrthogonalInBetween=[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
                      ]
  Hierarchy=[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],  # substates of state DEAD
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],  # substates of state OFF
             [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],  # substates of state ON
             [0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0],  # substates of state ON.FLASHING
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],  # substates of state ON.FLASHING.YELLOW_OFF
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],  # substates of state ON.FLASHING.YELLOW_ON
             [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1],  # substates of state ON.NORMAL
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],  # substates of state ON.NORMAL.GREEN
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],  # substates of state ON.NORMAL.RED
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],  # substates of state ON.NORMAL.RED.GREEN_SOON
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],  # substates of state ON.NORMAL.RED.RED_WAIT
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]   # substates of state ON.NORMAL.YELLOW
            ]
  CommonStateTable=[[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
                    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
                    [-1, -1, -1, 2, 2, 2, 2, 2, 2, 2, 2, 2],
                    [-1, -1, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2],
                    [-1, -1, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2],
                    [-1, -1, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2],
                    [-1, -1, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6],
                    [-1, -1, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6],
                    [-1, -1, 2, 2, 2, 2, 6, 6, 6, 8, 8, 6],
                    [-1, -1, 2, 2, 2, 2, 6, 6, 8, 8, 8, 6],
                    [-1, -1, 2, 2, 2, 2, 6, 6, 8, 8, 8, 6],
                    [-1, -1, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6] 
                   ]
  Description=None

  Lock=thread.allocate_lock()
  CurrentModel=None

  def __init__(self, Interpreter=None):

    # Variables
    self.state=None
    self.Submodels=[]
    for i in range(TrafficLightBehaviour.StateNum):
      self.Submodels.append(None)
    self.history=[]
    for i in range(TrafficLightBehaviour.StateNum):
      self.history.append(None)

    # Constructor
    for i in range(TrafficLightBehaviour.StateNum):
      self.history[i]=History()
      self.history[i].States=[]
      self.history[i].Times=[]
      for j in range(TrafficLightBehaviour.StateNum):
        self.history[i].States.append(-1)
        self.history[i].Times.append(-1)

    self.TimedTransitions=[] # used only when --ext is set
    for i in range(TrafficLightBehaviour.StateNum):
      self.TimedTransitions.append(None)

    self.clearEnteredStates()

    # Interpreter of action code
    if Interpreter:
      self.DefaultInterpreter=Interpreter
    else:
      self.DefaultInterpreter=InteractiveInterpreter()
    self.HasInteractor=0
    self.setupInterpreter()

    self.EventsLock=thread.allocate_lock()
    self.PendingEvents=None
    self.PendingEventsTail=None
    self.HandleEventRunning=0
    self.Started=0

    self.description=TrafficLightBehaviour.Description

  # Methods
  def isParent(self, sp, sc):

    return sc>=0 and (sp<0 or TrafficLightBehaviour.Hierarchy[sp][sc])

  def isInState(self, s):

    if isinstance(s, int):
      st=self.state
      while st!=None:
        if st.StateID==s or self.isParent(s, st.StateID):
          return 1
        else:
          st=st.Next
      return 0

    elif isinstance(s, str):
      for i in range(TrafficLightBehaviour.StateNum):
        if s==TrafficLightBehaviour.StateNames[i]:
          return self.isInState(i)
      for i in range(TrafficLightBehaviour.StateNum):
        if self.Submodels[i]!=None and startsWith(s, TrafficLightBehaviour.StateNames[i]+"."):
          SubmodelState=s[len(TrafficLightBehaviour.StateNames[i])+1:]
          return self.isInState(i) and self.Submodels[i].isInState(SubmodelState)
    return 0

  def main(self, argv):

    model=TrafficLightBehaviour()
    cmd=""
    model.initModel()
    if model.HasInteractor:
      model.runInteractor()
    else:
      if TrafficLightBehaviour.Description:
        sys.__stdout__.write(TrafficLightBehaviour.Description+"\n")
      lock=thread.allocate_lock()
      while cmd!="exit":
        sys.__stdout__.write(model.getCurrentState()+" > ")
        cmd=string.strip(sys.__stdin__.readline())
        if cmd=="exit":
          break
        lock.acquire()
        model.event(cmd, [], lock)
        lock.acquire()
        lock.release()
    model.runFinalizer()

  def initModel(self, run_initializer=1, run_enter_actions=1):

    self.clearEnteredStates()
    self.addInState(10) # init state "ON.NORMAL.RED.RED_WAIT"
    self.recordEnteredState(2)
    self.recordEnteredState(6)
    self.recordEnteredState(8)
    self.recordEnteredState(10)
    if run_initializer:
      self.runInitializer()
    if not self.HasInteractor:
      self.start(None, run_enter_actions)

  def handleEvent(self, se, params=[], lock=None, call_submodels=1):

    if not self.Started:
      if lock:
        lock.release()
      return 0
    self.EventsLock.acquire()
    self.HandleEventRunning=1
    self.EventsLock.release()
    self.params=params
    e=self.eventStr2Int(se)
    if e==0: # event "CROSSWALK"
      if self.isInState(10) and self.testCondition(0):
        self.runExitActionsForStates(8)
	self.clearEnteredStates()
        self.changeState(10, 9)
        self.runEnterActionsForStates(self.StatesEntered, 1)
        if lock:
          lock.release()
        self.checkPendingEvents()
        return 1
    elif e==1: # event "ON-OFF"
      if self.isInState(1) and self.testCondition(1):
        self.runExitActionsForStates(-1)
	self.clearEnteredStates()
        self.changeState(1, 2, 1)
        self.runEnterActionsForStates(self.StatesEntered, 1)
        if lock:
          lock.release()
        self.checkPendingEvents()
        return 1
      if self.isInState(2) and self.testCondition(2):
        self.runExitActionsForStates(-1)
	self.clearEnteredStates()
        self.changeState(2, 1)
        self.runEnterActionsForStates(self.StatesEntered, 1)
        if lock:
          lock.release()
        self.checkPendingEvents()
        return 1
    elif e==2: # event "POLICE"
      if self.isInState(3) and self.testCondition(3):
        self.runExitActionsForStates(2)
	self.clearEnteredStates()
        self.changeState(3, 6)
        self.runEnterActionsForStates(self.StatesEntered, 1)
        if lock:
          lock.release()
        self.checkPendingEvents()
        return 1
      if self.isInState(6) and self.testCondition(4):
        self.runExitActionsForStates(2)
	self.clearEnteredStates()
        self.changeState(6, 3)
        self.runEnterActionsForStates(self.StatesEntered, 1)
        if lock:
          lock.release()
        self.checkPendingEvents()
        return 1
    elif e==3: # event "QUIT"
      if self.isInState(2) and self.testCondition(5):
        self.runExitActionsForStates(-1)
	self.clearEnteredStates()
        self.changeState(2, 0)
        self.runEnterActionsForStates(self.StatesEntered, 1)
        if lock:
          lock.release()
        self.checkPendingEvents()
        return 1
    elif e==4: # event "__INTERNAL_0_TIME_0"
      if self.isInState(10) and self.testCondition(6):
        self.runExitActionsForStates(8)
	self.clearEnteredStates()
        self.changeState(10, 9)
        self.runEnterActionsForStates(self.StatesEntered, 1)
        if lock:
          lock.release()
        self.checkPendingEvents()
        return 1
    elif e==5: # event "__INTERNAL_0_TIME_1"
      if self.isInState(7) and self.testCondition(7):
        self.runExitActionsForStates(6)
	self.clearEnteredStates()
        self.changeState(7, 11)
        self.runEnterActionsForStates(self.StatesEntered, 1)
        if lock:
          lock.release()
        self.checkPendingEvents()
        return 1
    elif e==6: # event "__INTERNAL_0_TIME_2"
      if self.isInState(11) and self.testCondition(8):
        self.runExitActionsForStates(6)
	self.clearEnteredStates()
        self.changeState(11, 8)
        self.runEnterActionsForStates(self.StatesEntered, 1)
        if lock:
          lock.release()
        self.checkPendingEvents()
        return 1
    elif e==7: # event "__INTERNAL_0_TIME_3"
      if self.isInState(9) and self.testCondition(9):
        self.runExitActionsForStates(6)
	self.clearEnteredStates()
        self.changeState(9, 7)
        self.runEnterActionsForStates(self.StatesEntered, 1)
        if lock:
          lock.release()
        self.checkPendingEvents()
        return 1
    elif e==8: # event "__INTERNAL_0_TIME_4"
      if self.isInState(4) and self.testCondition(10):
        self.runExitActionsForStates(3)
	self.clearEnteredStates()
        self.changeState(4, 5)
        self.runEnterActionsForStates(self.StatesEntered, 1)
        if lock:
          lock.release()
        self.checkPendingEvents()
        return 1
    elif e==9: # event "__INTERNAL_0_TIME_5"
      if self.isInState(5) and self.testCondition(11):
        self.runExitActionsForStates(3)
	self.clearEnteredStates()
        self.changeState(5, 4)
        self.runEnterActionsForStates(self.StatesEntered, 1)
        if lock:
          lock.release()
        self.checkPendingEvents()
        return 1
    if lock:
      lock.release()
    self.checkPendingEvents()
    return 0

  def forceIntoState(self, s):

    changed=0
    s2=self.state
    while s2!=None:
      HasCommonParent=0
      for i in range(TrafficLightBehaviour.StateNum):
        if self.isParent(i, s2.StateID) and self.isParent(i, s):
          HasCommonParent=1
          if not self.hasOrthogonalStateInBetween(i, s2.StateID):
            self.changeState(s2.StateID, s)
            changed=1
      if not HasCommonParent:
        self.changeState(s2.StateID, s)
        changed=1
      s2=s2.Next
    if not changed:
      self.addInState(s)

  def changeState(self, s1, s2, check_history=0, top_level=0):

    # t1=common(s1, s2)
    t1=TrafficLightBehaviour.CommonStateTable[s1][s2]
    self.recordHistory(t1)
    if t1>=0:
      self.removeOutStates(t1)
    else:
      self.state=None
    # t2=history(s2)
    t2=TrafficLightBehaviour.HistoryStateTable[s2]
    if t2==0: # no history
      self.generateStates(t1, s2)
    elif t2==1: # normal history
      if not check_history:
        self.generateStates(t1, s2)
      elif self.hasHistoryRecorded(s2):
        self.generateStates(t1, self.history[s2].States[s2])
      else:
        self.generateStates(t1, s2, 1)
    elif t2==2: # deep history
      if check_history and self.hasHistoryRecorded(s2):
        for i in range(TrafficLightBehaviour.StateNum):
          hs=self.history[s2].States[i]
          if hs>=0 and self.isLeafState(hs):
            # used only when --ext is set
            self.recordEnteredState(hs, 1, 1, t1)
            self.addInState(hs)
      else:
        self.generateStates(t1, s2)

  def addInState(self, s):

    if not self.isInState(s):
      st=State()
      st.StateID=s
      st.Next=self.state
      self.state=st
      return 1
    else:
      return 0

  def generateStates(self, common, dest, history_type=0):

    if common==-1:
      if dest==0:
        if history_type!=2 or self.check_history(-1):
          if history_type!=2 or self.check_history(0):
            self.recordEnteredState(0)
            self.addInState(0)  # move into leaf state "DEAD"
      elif dest==1:
        if history_type!=2 or self.check_history(-1):
          if history_type!=2 or self.check_history(1):
            self.recordEnteredState(1)
            self.addInState(1)  # move into leaf state "OFF"
      elif dest==2:
        if history_type!=2 or self.check_history(-1):
          if history_type!=2 or self.check_history(2):
            self.recordEnteredState(2)
            if history_type!=2 or self.check_history(6):
              self.recordEnteredState(6)
              if history_type!=2 or self.check_history(8):
                self.recordEnteredState(8)
                if history_type!=2 or self.check_history(10):
                  self.recordEnteredState(10)
                  self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
      elif dest==3:
        if history_type!=2 or self.check_history(-1):
          if history_type!=2 or self.check_history(2):
            self.recordEnteredState(2)
            if history_type!=2 or self.check_history(3):
              self.recordEnteredState(3)
              if history_type!=2 or self.check_history(5):
                self.recordEnteredState(5)
                self.addInState(5)  # move into leaf state "ON.FLASHING.YELLOW_ON"
      elif dest==4:
        if history_type!=2 or self.check_history(-1):
          if history_type!=2 or self.check_history(2):
            self.recordEnteredState(2)
            if history_type!=2 or self.check_history(3):
              self.recordEnteredState(3)
              if history_type!=2 or self.check_history(4):
                self.recordEnteredState(4)
                self.addInState(4)  # move into leaf state "ON.FLASHING.YELLOW_OFF"
      elif dest==5:
        if history_type!=2 or self.check_history(-1):
          if history_type!=2 or self.check_history(2):
            self.recordEnteredState(2)
            if history_type!=2 or self.check_history(3):
              self.recordEnteredState(3)
              if history_type!=2 or self.check_history(5):
                self.recordEnteredState(5)
                self.addInState(5)  # move into leaf state "ON.FLASHING.YELLOW_ON"
      elif dest==6:
        if history_type!=2 or self.check_history(-1):
          if history_type!=2 or self.check_history(2):
            self.recordEnteredState(2)
            if history_type!=2 or self.check_history(6):
              self.recordEnteredState(6)
              if history_type!=2 or self.check_history(8):
                self.recordEnteredState(8)
                if history_type!=2 or self.check_history(10):
                  self.recordEnteredState(10)
                  self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
      elif dest==7:
        if history_type!=2 or self.check_history(-1):
          if history_type!=2 or self.check_history(2):
            self.recordEnteredState(2)
            if history_type!=2 or self.check_history(6):
              self.recordEnteredState(6)
              if history_type!=2 or self.check_history(7):
                self.recordEnteredState(7)
                self.addInState(7)  # move into leaf state "ON.NORMAL.GREEN"
      elif dest==8:
        if history_type!=2 or self.check_history(-1):
          if history_type!=2 or self.check_history(2):
            self.recordEnteredState(2)
            if history_type!=2 or self.check_history(6):
              self.recordEnteredState(6)
              if history_type!=2 or self.check_history(8):
                self.recordEnteredState(8)
                if history_type!=2 or self.check_history(10):
                  self.recordEnteredState(10)
                  self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
      elif dest==9:
        if history_type!=2 or self.check_history(-1):
          if history_type!=2 or self.check_history(2):
            self.recordEnteredState(2)
            if history_type!=2 or self.check_history(6):
              self.recordEnteredState(6)
              if history_type!=2 or self.check_history(8):
                self.recordEnteredState(8)
                if history_type!=2 or self.check_history(9):
                  self.recordEnteredState(9)
                  self.addInState(9)  # move into leaf state "ON.NORMAL.RED.GREEN_SOON"
      elif dest==10:
        if history_type!=2 or self.check_history(-1):
          if history_type!=2 or self.check_history(2):
            self.recordEnteredState(2)
            if history_type!=2 or self.check_history(6):
              self.recordEnteredState(6)
              if history_type!=2 or self.check_history(8):
                self.recordEnteredState(8)
                if history_type!=2 or self.check_history(10):
                  self.recordEnteredState(10)
                  self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
      elif dest==11:
        if history_type!=2 or self.check_history(-1):
          if history_type!=2 or self.check_history(2):
            self.recordEnteredState(2)
            if history_type!=2 or self.check_history(6):
              self.recordEnteredState(6)
              if history_type!=2 or self.check_history(11):
                self.recordEnteredState(11)
                self.addInState(11)  # move into leaf state "ON.NORMAL.YELLOW"
    elif common==0:
      if dest==0:
        if history_type!=2 or self.check_history(0):
          self.recordEnteredState(0)
          self.addInState(0)  # move into leaf state "DEAD"
    elif common==1:
      if dest==1:
        if history_type!=2 or self.check_history(1):
          self.recordEnteredState(1)
          self.addInState(1)  # move into leaf state "OFF"
    elif common==2:
      if dest==2:
        if history_type!=2 or self.check_history(2):
          self.recordEnteredState(2)
          if history_type!=2 or self.check_history(6):
            self.recordEnteredState(6)
            if history_type!=2 or self.check_history(8):
              self.recordEnteredState(8)
              if history_type!=2 or self.check_history(10):
                self.recordEnteredState(10)
                self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
      elif dest==3:
        if history_type!=2 or self.check_history(2):
          self.recordEnteredState(2)
          if history_type!=2 or self.check_history(3):
            self.recordEnteredState(3)
            if history_type!=2 or self.check_history(5):
              self.recordEnteredState(5)
              self.addInState(5)  # move into leaf state "ON.FLASHING.YELLOW_ON"
      elif dest==4:
        if history_type!=2 or self.check_history(2):
          self.recordEnteredState(2)
          if history_type!=2 or self.check_history(3):
            self.recordEnteredState(3)
            if history_type!=2 or self.check_history(4):
              self.recordEnteredState(4)
              self.addInState(4)  # move into leaf state "ON.FLASHING.YELLOW_OFF"
      elif dest==5:
        if history_type!=2 or self.check_history(2):
          self.recordEnteredState(2)
          if history_type!=2 or self.check_history(3):
            self.recordEnteredState(3)
            if history_type!=2 or self.check_history(5):
              self.recordEnteredState(5)
              self.addInState(5)  # move into leaf state "ON.FLASHING.YELLOW_ON"
      elif dest==6:
        if history_type!=2 or self.check_history(2):
          self.recordEnteredState(2)
          if history_type!=2 or self.check_history(6):
            self.recordEnteredState(6)
            if history_type!=2 or self.check_history(8):
              self.recordEnteredState(8)
              if history_type!=2 or self.check_history(10):
                self.recordEnteredState(10)
                self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
      elif dest==7:
        if history_type!=2 or self.check_history(2):
          self.recordEnteredState(2)
          if history_type!=2 or self.check_history(6):
            self.recordEnteredState(6)
            if history_type!=2 or self.check_history(7):
              self.recordEnteredState(7)
              self.addInState(7)  # move into leaf state "ON.NORMAL.GREEN"
      elif dest==8:
        if history_type!=2 or self.check_history(2):
          self.recordEnteredState(2)
          if history_type!=2 or self.check_history(6):
            self.recordEnteredState(6)
            if history_type!=2 or self.check_history(8):
              self.recordEnteredState(8)
              if history_type!=2 or self.check_history(10):
                self.recordEnteredState(10)
                self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
      elif dest==9:
        if history_type!=2 or self.check_history(2):
          self.recordEnteredState(2)
          if history_type!=2 or self.check_history(6):
            self.recordEnteredState(6)
            if history_type!=2 or self.check_history(8):
              self.recordEnteredState(8)
              if history_type!=2 or self.check_history(9):
                self.recordEnteredState(9)
                self.addInState(9)  # move into leaf state "ON.NORMAL.RED.GREEN_SOON"
      elif dest==10:
        if history_type!=2 or self.check_history(2):
          self.recordEnteredState(2)
          if history_type!=2 or self.check_history(6):
            self.recordEnteredState(6)
            if history_type!=2 or self.check_history(8):
              self.recordEnteredState(8)
              if history_type!=2 or self.check_history(10):
                self.recordEnteredState(10)
                self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
      elif dest==11:
        if history_type!=2 or self.check_history(2):
          self.recordEnteredState(2)
          if history_type!=2 or self.check_history(6):
            self.recordEnteredState(6)
            if history_type!=2 or self.check_history(11):
              self.recordEnteredState(11)
              self.addInState(11)  # move into leaf state "ON.NORMAL.YELLOW"
    elif common==3:
      if dest==3:
        if history_type!=2 or self.check_history(3):
          self.recordEnteredState(3)
          if history_type!=2 or self.check_history(5):
            self.recordEnteredState(5)
            self.addInState(5)  # move into leaf state "ON.FLASHING.YELLOW_ON"
      elif dest==4:
        if history_type!=2 or self.check_history(3):
          self.recordEnteredState(3)
          if history_type!=2 or self.check_history(4):
            self.recordEnteredState(4)
            self.addInState(4)  # move into leaf state "ON.FLASHING.YELLOW_OFF"
      elif dest==5:
        if history_type!=2 or self.check_history(3):
          self.recordEnteredState(3)
          if history_type!=2 or self.check_history(5):
            self.recordEnteredState(5)
            self.addInState(5)  # move into leaf state "ON.FLASHING.YELLOW_ON"
    elif common==4:
      if dest==4:
        if history_type!=2 or self.check_history(4):
          self.recordEnteredState(4)
          self.addInState(4)  # move into leaf state "ON.FLASHING.YELLOW_OFF"
    elif common==5:
      if dest==5:
        if history_type!=2 or self.check_history(5):
          self.recordEnteredState(5)
          self.addInState(5)  # move into leaf state "ON.FLASHING.YELLOW_ON"
    elif common==6:
      if dest==6:
        if history_type!=2 or self.check_history(6):
          self.recordEnteredState(6)
          if history_type!=2 or self.check_history(8):
            self.recordEnteredState(8)
            if history_type!=2 or self.check_history(10):
              self.recordEnteredState(10)
              self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
      elif dest==7:
        if history_type!=2 or self.check_history(6):
          self.recordEnteredState(6)
          if history_type!=2 or self.check_history(7):
            self.recordEnteredState(7)
            self.addInState(7)  # move into leaf state "ON.NORMAL.GREEN"
      elif dest==8:
        if history_type!=2 or self.check_history(6):
          self.recordEnteredState(6)
          if history_type!=2 or self.check_history(8):
            self.recordEnteredState(8)
            if history_type!=2 or self.check_history(10):
              self.recordEnteredState(10)
              self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
      elif dest==9:
        if history_type!=2 or self.check_history(6):
          self.recordEnteredState(6)
          if history_type!=2 or self.check_history(8):
            self.recordEnteredState(8)
            if history_type!=2 or self.check_history(9):
              self.recordEnteredState(9)
              self.addInState(9)  # move into leaf state "ON.NORMAL.RED.GREEN_SOON"
      elif dest==10:
        if history_type!=2 or self.check_history(6):
          self.recordEnteredState(6)
          if history_type!=2 or self.check_history(8):
            self.recordEnteredState(8)
            if history_type!=2 or self.check_history(10):
              self.recordEnteredState(10)
              self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
      elif dest==11:
        if history_type!=2 or self.check_history(6):
          self.recordEnteredState(6)
          if history_type!=2 or self.check_history(11):
            self.recordEnteredState(11)
            self.addInState(11)  # move into leaf state "ON.NORMAL.YELLOW"
    elif common==7:
      if dest==7:
        if history_type!=2 or self.check_history(7):
          self.recordEnteredState(7)
          self.addInState(7)  # move into leaf state "ON.NORMAL.GREEN"
    elif common==8:
      if dest==8:
        if history_type!=2 or self.check_history(8):
          self.recordEnteredState(8)
          if history_type!=2 or self.check_history(10):
            self.recordEnteredState(10)
            self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
      elif dest==9:
        if history_type!=2 or self.check_history(8):
          self.recordEnteredState(8)
          if history_type!=2 or self.check_history(9):
            self.recordEnteredState(9)
            self.addInState(9)  # move into leaf state "ON.NORMAL.RED.GREEN_SOON"
      elif dest==10:
        if history_type!=2 or self.check_history(8):
          self.recordEnteredState(8)
          if history_type!=2 or self.check_history(10):
            self.recordEnteredState(10)
            self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
    elif common==9:
      if dest==9:
        if history_type!=2 or self.check_history(9):
          self.recordEnteredState(9)
          self.addInState(9)  # move into leaf state "ON.NORMAL.RED.GREEN_SOON"
    elif common==10:
      if dest==10:
        if history_type!=2 or self.check_history(10):
          self.recordEnteredState(10)
          self.addInState(10)  # move into leaf state "ON.NORMAL.RED.RED_WAIT"
    elif common==11:
      if dest==11:
        if history_type!=2 or self.check_history(11):
          self.recordEnteredState(11)
          self.addInState(11)  # move into leaf state "ON.NORMAL.YELLOW"

  def removeOutStates(self, common_state):

    s=self.state
    prev=None
    while s!=None:
      if self.isParent(common_state, s.StateID):
        if prev==None:
          self.state=self.state.Next
        else:
          prev.Next=s.Next
      else:
        prev=s
      s=s.Next

  def eventStr2Int(self, event):

    for i in range(10):
      if event==TrafficLightBehaviour.EventNames[i]:
        return i
    return -1

  def stateInt2Str(self, state):

    if state==-1:
      return ""
    else:
      return TrafficLightBehaviour.StateNames[state]

  def getCurrentStateList(self):

    sl=StringList()
    slend=sl
    s=self.state
    while s!=None:
      sm=self.Submodels[s.StateID]
      curstate=self.stateInt2Str(s.StateID)
      if sm!=None:
        slend.Next=sm.getCurrentStateList()
        while slend.Next!=None:
          slend.Next.str=curstate+"."+slend.Next.str
          slend=slend.Next
      else:
        slend.Next=StringList(curstate)
        slend=slend.Next
      s=s.Next
    return sl.Next

  def getCurrentState(self, states=None):

    if states==None:
      states=self.getCurrentStateList()
      if states!=None:
        strst="[%s'%s']" % (self.getCurrentState(states), states.str)
      else:
        strst="[]"
    else:
      if states.Next:
        strst="%s'%s', " % (self.getCurrentState(states.Next), states.Next.str)
      else:
        strst=""
    return strst

  def getParentState(self, state):

    return TrafficLightBehaviour.ParentTable[state]

  def getSubstates(self, state):

    substates=None
    if state==-1: # substates of ""
      # add substate "DEAD"
      st=IntList()
      st.int=0
      st.Next=substates
      substates=st
      # add substate "OFF"
      st=IntList()
      st.int=1
      st.Next=substates
      substates=st
      # add substate "ON"
      st=IntList()
      st.int=2
      st.Next=substates
      substates=st
    elif state==0: # substates of "DEAD"
      pass
    elif state==1: # substates of "OFF"
      pass
    elif state==2: # substates of "ON"
      # add substate "ON.FLASHING"
      st=IntList()
      st.int=3
      st.Next=substates
      substates=st
      # add substate "ON.NORMAL"
      st=IntList()
      st.int=6
      st.Next=substates
      substates=st
    elif state==3: # substates of "ON.FLASHING"
      # add substate "ON.FLASHING.YELLOW_OFF"
      st=IntList()
      st.int=4
      st.Next=substates
      substates=st
      # add substate "ON.FLASHING.YELLOW_ON"
      st=IntList()
      st.int=5
      st.Next=substates
      substates=st
    elif state==4: # substates of "ON.FLASHING.YELLOW_OFF"
      pass
    elif state==5: # substates of "ON.FLASHING.YELLOW_ON"
      pass
    elif state==6: # substates of "ON.NORMAL"
      # add substate "ON.NORMAL.GREEN"
      st=IntList()
      st.int=7
      st.Next=substates
      substates=st
      # add substate "ON.NORMAL.RED"
      st=IntList()
      st.int=8
      st.Next=substates
      substates=st
      # add substate "ON.NORMAL.YELLOW"
      st=IntList()
      st.int=11
      st.Next=substates
      substates=st
    elif state==7: # substates of "ON.NORMAL.GREEN"
      pass
    elif state==8: # substates of "ON.NORMAL.RED"
      # add substate "ON.NORMAL.RED.GREEN_SOON"
      st=IntList()
      st.int=9
      st.Next=substates
      substates=st
      # add substate "ON.NORMAL.RED.RED_WAIT"
      st=IntList()
      st.int=10
      st.Next=substates
      substates=st
    elif state==9: # substates of "ON.NORMAL.RED.GREEN_SOON"
      pass
    elif state==10: # substates of "ON.NORMAL.RED.RED_WAIT"
      pass
    elif state==11: # substates of "ON.NORMAL.YELLOW"
      pass
    return substates

  def isHistoryState(self, state):

    return TrafficLightBehaviour.HistoryStateTable[state]>0

  def isLeafState(self, state):

    if isinstance(state, int):
      return TrafficLightBehaviour.LeafStateTable[state]!=None

    elif isinstance(state, str):
      for i in range(TrafficLightBehaviour.StateNum):
        if TrafficLightBehaviour.LeafStateTable[i]==None:
          continue
        if state==TrafficLightBehaviour.LeafStateTable[i] and self.Submodels[i]==None:
          return 1
        elif startswith(state, TrafficLightBehaviour.LeafStateTable[i]+".") and self.Submodels[i]!=None:
          SubmodelState=state[TrafficLightBehaviour.LeafStateTable[i].length()+1:]
          return self.Submodels[i].isLeafState(SubmodelState)
    return 0

  def isHistoryUp2Date(self, state, time):

    for i in range(TrafficLightBehaviour.StateNum):
      if self.history[state].Times[i]>=time:
        return 1
    return 0

  def mergeHistory(self, state, states, times):

    max=-1
    for i in range(TrafficLightBehaviour.StateNum):
      if times[i]>max:
        max=times[i]
    if self.isHistoryUp2Date(state, max):
      for i in range(TrafficLightBehaviour.StateNum):
        if times[i]>self.history[state].Times[i]:
          self.history[state].States[i]=states[i]
          self.history[state].Times[i]=times[i]
    else:
      self.history[state].States=copy.copy(states)
      self.history[state].Times=copy.copy(times)

  def recordHistory(self, top_state):

    curtime=time.time();
    s=self.state;
    while s!=None:
      child=s.StateID
      states=[]
      times=[]
      for i in range(TrafficLightBehaviour.StateNum):
        states.append(-1)
        times.append(-1)
      states[child]=child
      times[child]=curtime
      if top_state<0 or self.isParent(top_state, child):
        parent=self.getParentState(child)
        if self.isHistoryState(child):
          self.history[child].Submodel=self.Submodels[child]
        while parent!=top_state and times[parent]!=curtime:
          states[parent]=child
          times[parent]=curtime
          if self.isHistoryState(parent):
            self.mergeHistory(parent, states, times)
          child=parent
          parent=self.getParentState(child)
      s=s.Next

  def hasHistoryRecorded(self, state):

    for i in range(TrafficLightBehaviour.StateNum):
      if self.history[state].States[i]!=-1:
        return 1
      if self.Submodels[state]!=None:
        return 1
    return 0

  def hasOrthogonalStateInBetween(self, parent, leaf):

    return TrafficLightBehaviour.OrthogonalInBetween[parent+1][leaf]

  def check_history(self, dest):

    s=self.state
    while s!=None:
      if self.isParent(dest, s.StateID) and not self.hasOrthogonalStateInBetween(dest, s.StateID):
        return 0
      s=s.Next
    return 1

  def getEnabledEvents(self):

    events=EventList()
    if self.isInState(10):
      events.Append("CROSSWALK")
    if self.isInState(1):
      events.Append("ON-OFF")
    if self.isInState(2):
      events.Append("ON-OFF")
    if self.isInState(3):
      events.Append("POLICE")
    if self.isInState(6):
      events.Append("POLICE")
    if self.isInState(2):
      events.Append("QUIT")
    if self.isInState(10):
      events.Append("__INTERNAL_0_TIME_0")
    if self.isInState(7):
      events.Append("__INTERNAL_0_TIME_1")
    if self.isInState(11):
      events.Append("__INTERNAL_0_TIME_2")
    if self.isInState(9):
      events.Append("__INTERNAL_0_TIME_3")
    if self.isInState(4):
      events.Append("__INTERNAL_0_TIME_4")
    if self.isInState(5):
      events.Append("__INTERNAL_0_TIME_5")
    return events.Next

  def getHierarchy(self, start_level, state_prefix):

    h=Hierarchy()
    lasth=h
    # Generate state "DEAD" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="DEAD"
    if state_prefix==None:
      lasth.Next.PathName="DEAD"
    else:
      lasth.Next.PathName=state_prefix+".DEAD"
    lasth.Next.StateNum=0
    lasth.Next.Level=start_level+0
    lasth=lasth.Next
    # Generate state "OFF" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="OFF"
    if state_prefix==None:
      lasth.Next.PathName="OFF"
    else:
      lasth.Next.PathName=state_prefix+".OFF"
    lasth.Next.StateNum=1
    lasth.Next.Level=start_level+0
    lasth=lasth.Next
    # Generate state "ON" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="ON"
    if state_prefix==None:
      lasth.Next.PathName="ON"
    else:
      lasth.Next.PathName=state_prefix+".ON"
    lasth.Next.StateNum=2
    lasth.Next.Level=start_level+0
    lasth=lasth.Next
    # Generate state "ON.FLASHING" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="FLASHING"
    if state_prefix==None:
      lasth.Next.PathName="ON.FLASHING"
    else:
      lasth.Next.PathName=state_prefix+".ON.FLASHING"
    lasth.Next.StateNum=3
    lasth.Next.Level=start_level+1
    lasth=lasth.Next
    # Generate state "ON.FLASHING.YELLOW_OFF" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="YELLOW_OFF"
    if state_prefix==None:
      lasth.Next.PathName="ON.FLASHING.YELLOW_OFF"
    else:
      lasth.Next.PathName=state_prefix+".ON.FLASHING.YELLOW_OFF"
    lasth.Next.StateNum=4
    lasth.Next.Level=start_level+2
    lasth=lasth.Next
    # Generate state "ON.FLASHING.YELLOW_ON" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="YELLOW_ON"
    if state_prefix==None:
      lasth.Next.PathName="ON.FLASHING.YELLOW_ON"
    else:
      lasth.Next.PathName=state_prefix+".ON.FLASHING.YELLOW_ON"
    lasth.Next.StateNum=5
    lasth.Next.Level=start_level+2
    lasth=lasth.Next
    # Generate state "ON.NORMAL" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="NORMAL"
    if state_prefix==None:
      lasth.Next.PathName="ON.NORMAL"
    else:
      lasth.Next.PathName=state_prefix+".ON.NORMAL"
    lasth.Next.StateNum=6
    lasth.Next.Level=start_level+1
    lasth=lasth.Next
    # Generate state "ON.NORMAL.GREEN" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="GREEN"
    if state_prefix==None:
      lasth.Next.PathName="ON.NORMAL.GREEN"
    else:
      lasth.Next.PathName=state_prefix+".ON.NORMAL.GREEN"
    lasth.Next.StateNum=7
    lasth.Next.Level=start_level+2
    lasth=lasth.Next
    # Generate state "ON.NORMAL.RED" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="RED"
    if state_prefix==None:
      lasth.Next.PathName="ON.NORMAL.RED"
    else:
      lasth.Next.PathName=state_prefix+".ON.NORMAL.RED"
    lasth.Next.StateNum=8
    lasth.Next.Level=start_level+2
    lasth=lasth.Next
    # Generate state "ON.NORMAL.RED.GREEN_SOON" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="GREEN_SOON"
    if state_prefix==None:
      lasth.Next.PathName="ON.NORMAL.RED.GREEN_SOON"
    else:
      lasth.Next.PathName=state_prefix+".ON.NORMAL.RED.GREEN_SOON"
    lasth.Next.StateNum=9
    lasth.Next.Level=start_level+3
    lasth=lasth.Next
    # Generate state "ON.NORMAL.RED.RED_WAIT" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="RED_WAIT"
    if state_prefix==None:
      lasth.Next.PathName="ON.NORMAL.RED.RED_WAIT"
    else:
      lasth.Next.PathName=state_prefix+".ON.NORMAL.RED.RED_WAIT"
    lasth.Next.StateNum=10
    lasth.Next.Level=start_level+3
    lasth=lasth.Next
    # Generate state "ON.NORMAL.YELLOW" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="YELLOW"
    if state_prefix==None:
      lasth.Next.PathName="ON.NORMAL.YELLOW"
    else:
      lasth.Next.PathName=state_prefix+".ON.NORMAL.YELLOW"
    lasth.Next.StateNum=11
    lasth.Next.Level=start_level+2
    lasth=lasth.Next
    return h.Next

  def topLevelHistory(self):

    s=self.state.StateID
    t=self.getParentState(s)
    while t!=-1:
      s=t
      t=self.getParentState(s)
    self.changeState(s, s)

  def runActionCode(self, code_num):

    if code_num==0: # model finalizer
      pass
    elif code_num==1: # model initializer
      pass
    elif code_num==2: # enter actions for state "ON.NORMAL.RED.GREEN_SOON"
      # a timed transition
      sched=Scheduler(self, "__INTERNAL_0_TIME_3", eval("2", self.DefaultInterpreter.locals), 1)
      sched.Next=self.TimedTransitions[9]
      self.TimedTransitions[9]=sched
      sched.start()
    elif code_num==3: # enter actions for state "OFF"
      self.runCode("gui.setDead()")
    elif code_num==4: # enter actions for state "ON.NORMAL.RED.RED_WAIT"
      # a timed transition
      sched=Scheduler(self, "__INTERNAL_0_TIME_0", eval("6", self.DefaultInterpreter.locals), 1)
      sched.Next=self.TimedTransitions[10]
      self.TimedTransitions[10]=sched
      sched.start()
    elif code_num==5: # enter actions for state "ON.NORMAL.YELLOW"
      self.runCode("gui.setYellow()")
      # a timed transition
      sched=Scheduler(self, "__INTERNAL_0_TIME_2", eval("2", self.DefaultInterpreter.locals), 1)
      sched.Next=self.TimedTransitions[11]
      self.TimedTransitions[11]=sched
      sched.start()
    elif code_num==6: # enter actions for state "ON.NORMAL.GREEN"
      self.runCode("gui.setGreen()")
      # a timed transition
      sched=Scheduler(self, "__INTERNAL_0_TIME_1", eval("5", self.DefaultInterpreter.locals), 1)
      sched.Next=self.TimedTransitions[7]
      self.TimedTransitions[7]=sched
      sched.start()
    elif code_num==7: # enter actions for state "DEAD"
      self.runCode("gui.root.destroy()")
    elif code_num==8: # enter actions for state "ON.FLASHING.YELLOW_OFF"
      self.runCode("gui.setDead()")
      # a timed transition
      sched=Scheduler(self, "__INTERNAL_0_TIME_4", eval("0.5", self.DefaultInterpreter.locals), 1)
      sched.Next=self.TimedTransitions[4]
      self.TimedTransitions[4]=sched
      sched.start()
    elif code_num==9: # enter actions for state "ON.FLASHING.YELLOW_ON"
      self.runCode("gui.setYellow()")
      # a timed transition
      sched=Scheduler(self, "__INTERNAL_0_TIME_5", eval("0.5", self.DefaultInterpreter.locals), 1)
      sched.Next=self.TimedTransitions[5]
      self.TimedTransitions[5]=sched
      sched.start()
    elif code_num==10: # enter actions for state "ON.NORMAL.RED"
      self.runCode("gui.setRed()")
    elif code_num==11: # exit actions for state "ON.NORMAL.RED.GREEN_SOON"
      # clean up timed transitions
      if self.TimedTransitions[9]:
        self.TimedTransitions[9].clear()
        self.TimedTransitions[9]=None
    elif code_num==12: # exit actions for state "ON.NORMAL.RED.RED_WAIT"
      # clean up timed transitions
      if self.TimedTransitions[10]:
        self.TimedTransitions[10].clear()
        self.TimedTransitions[10]=None
    elif code_num==13: # exit actions for state "ON.NORMAL.GREEN"
      # clean up timed transitions
      if self.TimedTransitions[7]:
        self.TimedTransitions[7].clear()
        self.TimedTransitions[7]=None
    elif code_num==14: # exit actions for state "ON.FLASHING.YELLOW_OFF"
      # clean up timed transitions
      if self.TimedTransitions[4]:
        self.TimedTransitions[4].clear()
        self.TimedTransitions[4]=None
    elif code_num==15: # exit actions for state "ON.FLASHING.YELLOW_ON"
      # clean up timed transitions
      if self.TimedTransitions[5]:
        self.TimedTransitions[5].clear()
        self.TimedTransitions[5]=None
    elif code_num==16: # exit actions for state "ON.NORMAL.YELLOW"
      # clean up timed transitions
      if self.TimedTransitions[11]:
        self.TimedTransitions[11].clear()
        self.TimedTransitions[11]=None

  def testCondition(self, cond_num):

    if cond_num==0 and \
       self.DefaultInterpreter.runsource("eventhandler.TestResult=(1)")==0 and self.TestResult:
      return 1
    elif cond_num==1 and \
       self.DefaultInterpreter.runsource("eventhandler.TestResult=(1)")==0 and self.TestResult:
      return 1
    elif cond_num==2 and \
       self.DefaultInterpreter.runsource("eventhandler.TestResult=(1)")==0 and self.TestResult:
      return 1
    elif cond_num==3 and \
       self.DefaultInterpreter.runsource("eventhandler.TestResult=(1)")==0 and self.TestResult:
      return 1
    elif cond_num==4 and \
       self.DefaultInterpreter.runsource("eventhandler.TestResult=(1)")==0 and self.TestResult:
      return 1
    elif cond_num==5 and \
       self.DefaultInterpreter.runsource("eventhandler.TestResult=(1)")==0 and self.TestResult:
      return 1
    elif cond_num==6 and \
       self.DefaultInterpreter.runsource("eventhandler.TestResult=(1)")==0 and self.TestResult:
      return 1
    elif cond_num==7 and \
       self.DefaultInterpreter.runsource("eventhandler.TestResult=(1)")==0 and self.TestResult:
      return 1
    elif cond_num==8 and \
       self.DefaultInterpreter.runsource("eventhandler.TestResult=(1)")==0 and self.TestResult:
      return 1
    elif cond_num==9 and \
       self.DefaultInterpreter.runsource("eventhandler.TestResult=(1)")==0 and self.TestResult:
      return 1
    elif cond_num==10 and \
       self.DefaultInterpreter.runsource("eventhandler.TestResult=(1)")==0 and self.TestResult:
      return 1
    elif cond_num==11 and \
       self.DefaultInterpreter.runsource("eventhandler.TestResult=(1)")==0 and self.TestResult:
      return 1
    return 0

  def runEnterActions(self, state):

    if state==9: # enter action(s) for state "ON.NORMAL.RED.GREEN_SOON"
      self.runActionCode(2)
    elif state==1: # enter action(s) for state "OFF"
      self.runActionCode(3)
    elif state==10: # enter action(s) for state "ON.NORMAL.RED.RED_WAIT"
      self.runActionCode(4)
    elif state==11: # enter action(s) for state "ON.NORMAL.YELLOW"
      self.runActionCode(5)
    elif state==7: # enter action(s) for state "ON.NORMAL.GREEN"
      self.runActionCode(6)
    elif state==0: # enter action(s) for state "DEAD"
      self.runActionCode(7)
    elif state==4: # enter action(s) for state "ON.FLASHING.YELLOW_OFF"
      self.runActionCode(8)
    elif state==5: # enter action(s) for state "ON.FLASHING.YELLOW_ON"
      self.runActionCode(9)
    elif state==8: # enter action(s) for state "ON.NORMAL.RED"
      self.runActionCode(10)

  def runExitActions(self, state):

    if state==9: # exit action(s) for state "ON.NORMAL.RED.GREEN_SOON"
      self.runActionCode(11)
    elif state==10: # exit action(s) for state "ON.NORMAL.RED.RED_WAIT"
      self.runActionCode(12)
    elif state==7: # exit action(s) for state "ON.NORMAL.GREEN"
      self.runActionCode(13)
    elif state==4: # exit action(s) for state "ON.FLASHING.YELLOW_OFF"
      self.runActionCode(14)
    elif state==5: # exit action(s) for state "ON.FLASHING.YELLOW_ON"
      self.runActionCode(15)
    elif state==11: # exit action(s) for state "ON.NORMAL.YELLOW"
      self.runActionCode(16)

  def recordAllEnteredStates(self):

    st=self.state
    while st!=None:
      self.recordEnteredState(st.StateID, 1, 1)
      st=st.Next

  def recordEnteredState(self, s, superstates=0, submodel=0, commonstate=-1):

    # test if s is already recorded
    se=self.StatesEntered
    found=0
    while se!=None:
      if se.int==s:
        found=1
        break
      se=se.Next

    if not found:
      if superstates:
        parent=self.getParentState(s)
        if parent>=0 and parent!=commonstate:
          self.recordEnteredState(parent, 1)
      st=IntList()
      st.Next=self.StatesEntered
      st.int=s
      self.StatesEntered=st
      if submodel and self.Submodels[s]:
        self.Submodels[s].recordAllEnteredStates()

  def runAllEnterActions(self):

    self.runEnterActionsForStates(self.StatesEntered, 1)

  def runEnterActionsForStates(self, states, recursive=0):

    if states:
      self.runEnterActionsForStates(states.Next, 0)
      self.runEnterActions(states.int)
    if recursive:
      for s in self.Submodels:
        if s:
          s.runAllEnterActions()

  def runExitActionsForStates(self, common_state):

    substates=self.getSubstates(common_state)
    if substates==None:
      s=self.state
      while s!=None and s.StateID!=common_state:
        s=s.Next
      if s!=None and self.Submodels[s.StateID]:
        self.Submodels[s.StateID].runExitActionsForStates(-1)
      return s!=None
    else:
      has_current_substate=0
      while substates!=None:
        res=self.runExitActionsForStates(substates.int)
        has_current_substate=has_current_substate or res
        if res:
          self.runExitActions(substates.int)
        substates=substates.Next
      return has_current_substate

  def runInitializer(self):

    self.runActionCode(1)
    for s in self.Submodels:
      if s:
        s.runInitializer()

  def runFinalizer(self):

    if self.Started:
      for s in self.Submodels:
        if s:
          s.runFinalizer()
      self.runActionCode(0)
      self.Started=0

  def clearEnteredStates(self):

    self.StatesEntered=None
    for s in self.Submodels:
      if s:
        s.clearEnteredStates()

  def runCode(self, c):

    if len(c)>0:
      l=""
      for i in string.split(c, "\n"):
        if len(l)==0:
          l=i
        elif string.find(i, " ")!=0 and not (string.find(i, "else")==0 and string.strip(i[4:])==":") and \
                               string.find(i, "elif ")!=0 and string.find(i, "elif\t")!=0 and \
                               not (string.find(i, "except")==0 and string.strip(i[6:])==":") and \
                               string.find(i, "except ")!=0 and string.find(i, "except\t")!=0:
          self.DefaultInterpreter.runsource(l+"\n")
          l=i
        else:
          l=l+"\n"+i
      if len(l)>0:
        self.DefaultInterpreter.runsource(l+"\n")

  def setupInterpreter(self):

    self.DefaultInterpreter.locals["eventhandler"]=self
    self.DefaultInterpreter.locals["dump_message"]=self.dump_message

  def checkPendingEvents(self):

    self.EventsLock.acquire()
    ev=self.PendingEvents
    if ev!=None:
      self.PendingEvents=ev.Next
      if self.PendingEvents==None:
        self.PendingEventsTail=None
      self.EventsLock.release()
      self.handleEvent(ev.Event[0], ev.Event[1], ev.Event[2], ev.Event[3])
    else:
      self.HandleEventRunning=0
      self.EventsLock.release()

  def get_event_params(self):

    return self.params

  def dump_message(self, msg):

    print msg

  def is_in_state(self, state, check_substate=0):

    i=0
    while i<TrafficLightBehaviour.StateNum and TrafficLightBehaviour.StateNames[i]!=state:
      i=i+1
    if i<TrafficLightBehaviour.StateNum:
      return (not check_substate or self.isLeafState(i)) and self.isInState(i)
    else:
      return 0

  def start(self, lock=None, run_enter_actions=1):

    if run_enter_actions:
      self.runEnterActionsForStates(self.StatesEntered, 1)
    self.Started=1
    if run_enter_actions:
      self.checkPendingEvents()
    if lock:
      lock.release()

  def shutdown(self):

    pass

  def event(self, e, params=[], lock=None, call_submodels=1):

    self.EventsLock.acquire()
    running=self.HandleEventRunning
    if not running and self.Started:
      self.HandleEventRunning=1
    self.EventsLock.release()
    if not running and self.Started:
      thread.start_new_thread(self.handleEvent, (e, params, lock, call_submodels))
    else:
      self.EventsLock.acquire()
      ev=EventList()
      ev.Event=[e, params, lock, call_submodels]
      if self.PendingEventsTail!=None:
        self.PendingEventsTail.Next=ev
      else:
        self.PendingEvents=ev
      self.PendingEventsTail=ev
      self.EventsLock.release()


# main
if __name__=="__main__":
  TrafficLightBehaviour().main(sys.argv)