# Python source code generated by SCC (StateChart Compiler) 0.3, written by Thomas Feng
#   Source: F:/McGill/763B MODELLING/project\ballSingle_MDL.des
#   Date:   April 29, 2008
#   Time:   23:11:40


# Header Section -- definition and module importation used by the following parts
import sys
import copy
import time
import string
import thread
import threading
import time


class State:

  def __init__(self):

    self.StateID=-1
    self.Next=None

  def copy(self):

    s=State()
    s.StateID=self.StateID
    if self.Next!=None:
      s.Next=self.Next.copy()
    return s


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

  def sort(self):

    if self.Next!=None:
      self.Next=self.Next.sort()
      if self.Next.str<self.str:
        first=self.Next
        prev=self.Next
        next=self.Next.Next
        while next!=None and next.str<self.str:
          prev=next
          next=next.Next
        self.Next=next
        prev.Next=self
        return first
    return self


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


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, check_substate=1, use_backup=1):

    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=[], cond=None, scheduler=None):

    return 0

  def event(self, e, params=[], cond=None, scheduler=None):

    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 ballSingle_MDL(StateMachine):

  # Constants for this model
  StateNum=2
  EventNames=["__INTERNAL_0_TIME_0",
              "start" 
             ]
  StateNames=["init",
              "moving" 
             ]
  ParentTable=[-1,  # init -- parent (None)
               -1   # moving -- parent (None)
              ]
  HistoryStateTable=[0,
                     0 
                    ]
  LeafStateTable=["init",
                  "moving" 
                 ]
  OrthogonalInBetween=[[0, 0],
                       [0, 0],
                       [0, 0] 
                      ]
  OrthogonalTable=[[0, 0],
                   [0, 0] 
                  ]
  IntervalTable=["0.01",
                 None 
                ]
  RescheduleTable=[1,
                   -1 
                  ]
  Hierarchy=[[0, 0],  # substates of state init
             [0, 0]   # substates of state moving
            ]
  CommonStateTable=[[-1, -1],
                    [-1, -1] 
                   ]
  Description=None

  ##Lock=thread.allocate_lock()
  CurrentModel=None

  def __init__(self, Interpreter=None, Parent=None, OldInstance=None):

    # Variables
    self.Parent=Parent
    self.HistoryCount=0
    self.state=None
    self.BackState=None
    if OldInstance!=None:
      self.Submodels=OldInstance.Submodels
    else:
      self.Submodels=[]
      for i in range(ballSingle_MDL.StateNum):
        self.Submodels.append(None)
    self.history=[]
    for i in range(ballSingle_MDL.StateNum):
      self.history.append(None)

    # Constructor
    for i in range(ballSingle_MDL.StateNum):
      self.history[i]=History()
      self.history[i].States=[]
      self.history[i].Times=[]
      for j in range(ballSingle_MDL.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(ballSingle_MDL.StateNum):
      self.TimedTransitions.append(None)

    self.clearEnteredStates()
    self.HasInteractor=0

    # Interpreter of action code
    if self.Parent==None:  # Top-level model
      if Interpreter:
        self.DefaultInterpreter=Interpreter
      else:
        self.DefaultInterpreter=InteractiveInterpreter()
      self.setupInterpreter()

      ##self.EventsCond=threading.Condition()
      ##self.SchedulerCond=threading.Condition()
      self.Schedules=[]
      self.PendingEvents=None
      self.PendingEventsTail=None
    else:
      self.DefaultInterpreter=Interpreter
    self.Started=0
    self.Stopped=0

    self.description=ballSingle_MDL.Description

  # Methods
  def isParent(self, sp, sc):

    return sc>=0 and (sp<0 or ballSingle_MDL.Hierarchy[sp][sc])

  def isInState(self, s, check_substate=1, use_backup=1):

    if isinstance(s, int):
      if use_backup:
        st=self.BackState
      else:
        st=self.state
      while st!=None:
        if st.StateID==s or (check_substate and self.isParent(s, st.StateID)):
          return 1
        else:
          st=st.Next
      return 0

    elif isinstance(s, str):
      i=0
      while i<ballSingle_MDL.StateNum:
        if s==ballSingle_MDL.StateNames[i]:
          return self.isInState(i, check_substate, use_backup)
        i=i+1
      i=0
      while i<ballSingle_MDL.StateNum:
        stname=ballSingle_MDL.StateNames[i]
        if self.Submodels[i]!=None and startsWith(s, stname+"."):
          pos=len(stname)+1
          SubmodelState=s[pos:]
          return self.isInState(i, 0, use_backup) and self.Submodels[i].isInState(SubmodelState, check_substate, use_backup);
        i=i+1
      return 0

    else:
      return 0

  class main_callable:
    def __call__(self, argv):
      model=ballSingle_MDL()
      cmd=""
      model.initModel()
      if model.HasInteractor:
        model.runInteractor()
      else:
        ##cond=thread.allocate_lock()
        while cmd!="exit":
          sys.__stdout__.write(model.getCurrentState()+" > ")
          cmd=string.strip(sys.__stdin__.readline())
          if cmd=="exit":
            break
          if not model.Stopped:
            ##cond.acquire()
            ##model.event(cmd, [], cond)
            model.event(cmd, [])
            ##cond.acquire()
            ##cond.release()
      model.runFinalizer()
  main=main_callable()

  def initModel(self, run_initializer=1, run_enter_actions=1, TkInstance = None ):

    self.clearEnteredStates()
    if self.Parent==None and ballSingle_MDL.Description!=None:
      sys.__stdout__.write(ballSingle_MDL.Description+"\n")
    self.addInState(0) # init state "init"
    self.recordEnteredState(0)
    if run_initializer:
      self.runInitializer()
    if not self.HasInteractor:
      self.start(None, run_enter_actions, TkInstance )

  def applyMask(self, mask, dest):

    i=0
    while i<ballSingle_MDL.StateNum:
      dest[i]=dest[i] and mask[i]
      i=i+1

  def handleEvent(self, se, params=[], cond=None, scheduler=None):

    if not self.Started:
      if cond:
        cond.release()
      return 0
    self.params=params
    handled=0
    table=[]
    i=0
    while i<ballSingle_MDL.StateNum:
      table.append(1)
      i=i+1
    if self.state:
      self.BackState=self.state.copy()
    else:
      self.BackState=None
    e=self.eventStr2Int(se)
    if e==0: # event "__INTERNAL_0_TIME_0"
      if table[1] and self.isInState(1) and self.testCondition(0):
        if (scheduler==self or scheduler==None) and table[1]:
          self.runActionCode(2) # output action(s)
          self.runExitActionsForStates(-1)
	  self.clearEnteredStates()
          self.changeState(1, 1)
          self.runEnterActionsForStates(self.StatesEntered, 1)
          self.applyMask(ballSingle_MDL.OrthogonalTable[1], table)
          handled=1
    elif e==1: # event "start"
      if table[0] and self.isInState(0) and self.testCondition(1):
        if (scheduler==self or scheduler==None) and table[0]:
          self.runActionCode(3) # output action(s)
          self.runExitActionsForStates(-1)
	  self.clearEnteredStates()
          self.changeState(0, 1)
          self.runEnterActionsForStates(self.StatesEntered, 1)
          self.applyMask(ballSingle_MDL.OrthogonalTable[0], table)
          handled=1
    if cond and self.Parent==None:  # Top-level model
      cond.release()
    if not handled and e>=0 and (scheduler==self or scheduler==None) and ballSingle_MDL.RescheduleTable[e]>=0:
      self.addSchedule(ballSingle_MDL.RescheduleTable[e], ballSingle_MDL.IntervalTable[e], ballSingle_MDL.EventNames[e], scheduler)
    return handled

  def forceIntoState(self, s):

    changed=0
    s2=self.state
    while s2!=None:
      HasCommonParent=0
      for i in range(ballSingle_MDL.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=ballSingle_MDL.CommonStateTable[s1][s2]
    self.recordHistory(t1)
    if t1>=0:
      self.removeOutStates(t1)
    else:
      self.state=None
    # t2=history(s2)
    t2=ballSingle_MDL.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) and self.Submodels[s2]==None:
        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):
        if self.Submodels[s2]:
          self.recordEnteredState(s2, 1, 1, t1)
          self.addInState(s2)
        else:
          for i in range(ballSingle_MDL.StateNum):
            hs=self.history[s2].States[i]
            if hs>=0 and self.isLeafState(hs):
              self.recordEnteredState(hs, 1, 1, t1)
              self.addInState(hs)
      else:
        self.generateStates(t1, s2)

  def addInState(self, s):

    if not self.isInState(s, 1, 0):
      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 "init"
      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 "moving"
    elif common==0:
      if dest==0:
        if history_type!=2 or self.check_history(0):
          self.addInState(0)  # move into leaf state "init"
    elif common==1:
      if dest==1:
        if history_type!=2 or self.check_history(1):
          self.addInState(1)  # move into leaf state "moving"

  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(2):
      if event==ballSingle_MDL.EventNames[i]:
        return i
    return -1

  def stateInt2Str(self, state):

    if state==-1:
      return ""
    else:
      return ballSingle_MDL.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:
        states=states.sort()
        strst="['%s'%s]" % (states.str, self.getCurrentState(states))
      else:
        strst="[]"
    else:
      if states.Next:
        strst=", '%s'%s" % (states.Next.str, self.getCurrentState(states.Next))
      else:
        strst=""
    return strst

  def getParentState(self, state):

    return ballSingle_MDL.ParentTable[state]

  def getSubstates(self, state):

    substates=None
    if state==-1: # substates of ""
      # add substate "init"
      st=IntList()
      st.int=0
      st.Next=substates
      substates=st
      # add substate "moving"
      st=IntList()
      st.int=1
      st.Next=substates
      substates=st
    elif state==0: # substates of "init"
      pass
    elif state==1: # substates of "moving"
      pass
    return substates

  def isHistoryState(self, state):

    return ballSingle_MDL.HistoryStateTable[state]>0

  def isLeafState(self, state):

    if isinstance(state, int):
      return ballSingle_MDL.LeafStateTable[state]!=None

    elif isinstance(state, str):
      for i in range(ballSingle_MDL.StateNum):
        if ballSingle_MDL.LeafStateTable[i]==None:
          continue
        if state==ballSingle_MDL.LeafStateTable[i] and self.Submodels[i]==None:
          return 1
        elif startsWith(state, ballSingle_MDL.LeafStateTable[i]+".") and self.Submodels[i]!=None:
          SubmodelState=state[ballSingle_MDL.LeafStateTable[i].length()+1:]
          return self.Submodels[i].isLeafState(SubmodelState)
    return 0

  def isHistoryUp2Date(self, state, time):

    for i in range(ballSingle_MDL.StateNum):
      if self.history[state].Times[i]>=time:
        return 1
    return 0

  def mergeHistory(self, state, states, times):

    max=-1
    for i in range(ballSingle_MDL.StateNum):
      if times[i]>max:
        max=times[i]
    if self.isHistoryUp2Date(state, max):
      for i in range(ballSingle_MDL.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=self.HistoryCount
    self.HistoryCount=self.HistoryCount+1
    s=self.state
    while s!=None:
      child=s.StateID
      states=[]
      times=[]
      for i in range(ballSingle_MDL.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>=0 and times[parent]!=curtime:
          states[parent]=child
          times[parent]=curtime
          if self.isHistoryState(parent):
            self.mergeHistory(parent, states, times)
          if parent==top_state:
            break
          child=parent
          parent=self.getParentState(child)
      s=s.Next

  def hasHistoryRecorded(self, state):

    for i in range(ballSingle_MDL.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 ballSingle_MDL.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(1):
      events.Append("__INTERNAL_0_TIME_0")
    if self.isInState(0):
      events.Append("start")
    return events.Next

  def getHierarchy(self, start_level, state_prefix):

    h=Hierarchy()
    lasth=h
    # Generate state "init" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="init"
    if state_prefix==None:
      lasth.Next.PathName="init"
    else:
      lasth.Next.PathName=state_prefix+".init"
    lasth.Next.StateNum=0
    lasth.Next.Level=start_level+0
    lasth=lasth.Next
    # Generate state "moving" in the hierarchy table
    lasth.Next=Hierarchy()
    lasth.Next.StateName="moving"
    if state_prefix==None:
      lasth.Next.PathName="moving"
    else:
      lasth.Next.PathName=state_prefix+".moving"
    lasth.Next.StateNum=1
    lasth.Next.Level=start_level+0
    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: # output action(s) of a transition
      self.runCode("for b in balls: ctl.bounce(b, 0.01)")
      # repeated timed transition
      self.addSchedule(1, ballSingle_MDL.IntervalTable[0], ballSingle_MDL.EventNames[0], self)
    elif code_num==3: # output action(s) of a transition
      self.runCode("ctl = eventhandler.get_event_params()")
      self.runCode("bid = counter")
      self.runCode("counter += 1")
      self.runCode("gid, pos, speed = ctl.init(bid)")
      self.runCode("balls[bid] = {\'pos\': pos, \'speed\': speed, \'gid\':gid}")
      self.runCode("width = ctl.getWidth()")
      self.runCode("height = ctl.getHeight()")
    elif code_num==4: # enter actions for state "init"
      self.runCode("counter = 0")
      self.runCode("max = 160")
      self.runCode("balls = {}")
    elif code_num==5: # enter actions for state "moving"
      # a timed transition
      self.addSchedule(1, ballSingle_MDL.IntervalTable[0], ballSingle_MDL.EventNames[0], self)
    elif code_num==6: # exit actions for state "moving"
      # clean up timed transitions
      self.removeSchedule(1, self)

  def testCondition(self, cond_num):

    if cond_num==0 and \
       eval("(1)", self.DefaultInterpreter.locals):
      return 1
    elif cond_num==1 and \
       eval("(1)", self.DefaultInterpreter.locals):
      return 1
    return 0

  def runEnterActions(self, state):

    if state==0: # enter action(s) for state "init"
      self.runActionCode(4)
    elif state==1: # enter action(s) for state "moving"
      self.runActionCode(5)

  def runExitActions(self, state):

    if state==1: # exit action(s) for state "moving"
      self.runActionCode(6)

  def compareSchedule(self, sched_a, sched_b):

    return cmp(sched_a[1], sched_b[1])

  def addSchedule(self, id, interval, event, scheduler):

    if self.Parent!=None:  # Non-top-level model
      self.Parent.addSchedule(id, interval, event, scheduler)
      return
    f=eval(interval, self.DefaultInterpreter.locals)
    ##self.SchedulerCond.acquire()
    t=time.time()+f
    s=[id, t, interval, event, scheduler]
    self.Schedules.append(s)
    self.Schedules.sort(self.compareSchedule)
    ##self.SchedulerCond.notify()
    ##self.SchedulerCond.release()

  def removeSchedule(self, id, scheduler):

    if self.Parent!=None:  # Non-top-level model
      self.Parent.removeSchedule(id, scheduler)
      return
    ##self.SchedulerCond.acquire()
    i=0
    while i<len(self.Schedules):
      if self.Schedules[i][0]==id and self.Schedules[i][4]==scheduler:
        del self.Schedules[i]
      else:
        i=i+1
    ##self.SchedulerCond.release()

  def scheduler(self):

    if( not self.Schedules): return

    while( self.Schedules and self.Schedules[0][1]<=time.time()):
      this_sched=self.Schedules[0]
      del self.Schedules[0]
      self.event(this_sched[3], [], None, this_sched[4])

    if self.Schedules:
      t=self.Schedules[0][1]-time.time()

  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, 0, commonstate)
      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:
      self.Started=0
      for s in self.Submodels:
        if s:
          s.runFinalizer()
      self.runActionCode(0)
      if self.Parent==None:  # Top-level model
        ##self.EventsCond.acquire()
        ##self.SchedulerCond.acquire()
        self.Stopped=1
        ##self.EventsCond.notify()
        ##self.SchedulerCond.notify()
        ##self.SchedulerCond.release()
        ##self.EventsCond.release()
      else:
        self.Stopped=1

  def clearEnteredStates(self):

    self.StatesEntered=None
    for s in self.Submodels:
      if s:
        s.clearEnteredStates()

  def get_current_state(self):

    return self.getCurrentState()

  def runCode(self, c):

    self.DefaultInterpreter.runsource(c+"\n", "<input>", "exec")

  def setupInterpreter(self):

    self.DefaultInterpreter.locals["eventhandler"]=self
    self.DefaultInterpreter.locals["dump_message"]=self.dump_message

  def get_event_params(self):

    return self.params

  def dump_message(self, msg):

    print msg

  def is_in_state(self, s, check_substate=1):

    return self.isInState(s, check_substate)

  def start(self, lock=None, run_enter_actions=1, TkInstance = None):

    if self.Parent==None:  # Top-level model
      if run_enter_actions:
        self.runEnterActionsForStates(self.StatesEntered, 1)
      self.Started=1
      
      if( TkInstance ):
        self.sleepMethod = TkInstance.after 
        startTkMainloop = False
      else:
        import Tkinter
        TkInstance = Tkinter.Tk()
        self.sleepMethod = TkInstance.after 
        startTkMainloop = True
      
      self.pollingStation() 
      ##thread.start_new_thread(self.handleEvent_wrapper, ())
      ##thread.start_new_thread(self.scheduler, ())
      ## if lock:
        ## lock.release()
    else:
      self.Started=1
    for submodel in self.Submodels:
      if submodel!=None:
        submodel.start()

    if( self.Parent==None and startTkMainloop == None ): TkInstance.mainloop()

  def pollingStation(self):

    self.sleepMethod( 100, self.pollingStation )
    if self.Stopped: return 
    #self.handleEvent_wrapper()
    self.scheduler()
    #todo: pollingStation\,
  def shutdown(self):

    pass

  def handleEvent_wrapper(self):

    if( self.PendingEvents==None ): return
    event=self.PendingEvents
    self.PendingEvents=self.PendingEvents.Next
    if self.PendingEvents==None:
      self.PendingEventsTail=None
    event.next=None
    self.handleEvent(event.Event[0], event.Event[1], event.Event[2], event.Event[3])
    self.handleEvent_wrapper()

  def event(self, e, params=[], cond=None, scheduler=None):

    ev=EventList()
    ev.Event=[e, params, cond, scheduler]
    if self.PendingEventsTail!=None:
      self.PendingEventsTail.Next=ev
    else:
      self.PendingEvents=ev
    self.PendingEventsTail=ev
    self.handleEvent_wrapper()


# main
if __name__=="__main__":
  ballSingle_MDL.main(sys.argv)