Index: src/acft.py
===================================================================
--- src/acft.py	(revision 7)
+++ src/acft.py	(revision 8)
@@ -3,7 +3,8 @@
 #---------------------------------------------------------------------------------------
 
+import const
+import checks
+
 import time
-
-import const
 
 #---------------------------------------------------------------------------------------
@@ -11,175 +12,87 @@
 class Aircraft(object):
     """Base class for aircraft."""
-    def __init__(self, type):
+    @staticmethod
+    def create(flight):
+        """Create an aircraft instance for the type in the given flight."""
+        return _classes[flight.aircraftType](flight)
+
+    def __init__(self, flight):
         """Construct the aircraft for the given type."""
-        self._type = type
+        self._flight = flight
         self._aircraftState = None
+
+        self._checkers = []
+
+        self._checkers.append(checks.StageChecker())
+
+        self._checkers.append(checks.AltimeterLogger())
+        
+        self._checkers.append(checks.NAV1Logger())
+        self._checkers.append(checks.NAV2Logger())
+        self._checkers.append(checks.SquawkLogger())
+
+        self._checkers.append(checks.AnticollisionLightsLogger())
+        self._checkers.append(checks.LandingLightsLogger())
+        self._checkers.append(checks.StrobeLightsLogger())
+        self._checkers.append(checks.NavLightsLogger())
+
+        self._checkers.append(checks.FlapsLogger())
+
+        self._checkers.append(checks.GearsLogger())
 
     @property
     def type(self):
         """Get the type of the aircraft."""
-        return self._type
-
-    def modelChanged(self, aircraftName, modelName):
+        return self._flight.aircraftType
+
+    @property
+    def flight(self):
+        """Get the flight the aircraft belongs to."""
+        return self._flight
+
+    @property
+    def logger(self):
+        """Get the logger to use for the aircraft."""
+        return self._flight.logger
+
+    def modelChanged(self, timestamp, aircraftName, modelName):
         """Called when the simulator's aircraft changes."""
-        print "Aircraft.modelChanged: aircraftName='%s', modelName='%s'" % \
-            (aircraftName, modelName)
+        self._flight.logger.message(timestamp,
+                                    "Aircraft: name='%s', model='%s'" % \
+                                    (aircraftName, modelName))
 
     def handleState(self, aircraftState):
         """Called when the state of the aircraft changes."""
-        timeStr = time.ctime(aircraftState.timestamp)
-
-        if self._aircraftState is None or \
-           self._aircraftState.paused != aircraftState.paused:
-            print "Aircraft.handleState: %s: paused=%d" % \
-                (timeStr, aircraftState.paused)
-
-        if self._aircraftState is None or \
-           self._aircraftState.trickMode != aircraftState.trickMode:
-            print "Aircraft.handleState: %s: trickMode=%d" % \
-                (timeStr, aircraftState.trickMode)
-
-        if self._aircraftState is None or \
-           self._aircraftState.overspeed != aircraftState.overspeed:
-            print "Aircraft.handleState: %s: overspeed=%d" % \
-                (timeStr, aircraftState.overspeed)
-
-        if self._aircraftState is None or \
-           self._aircraftState.stalled != aircraftState.stalled:
-            print "Aircraft.handleState: %s: stalled=%d" % \
-                (timeStr, aircraftState.stalled)
-
-        if self._aircraftState is None or \
-           self._aircraftState.onTheGround != aircraftState.onTheGround:
-            print "Aircraft.handleState: %s: onTheGround=%d" % \
-                (timeStr, aircraftState.onTheGround)
-
-        if self._aircraftState is None or \
-           self._aircraftState.grossWeight != aircraftState.grossWeight:
-            print "Aircraft.handleState: %s: grossWeight=%f" % \
-                (timeStr, aircraftState.grossWeight)
-
-        if self._aircraftState is None or \
-           self._aircraftState.heading != aircraftState.heading:
-            print "Aircraft.handleState: %s: heading=%f" % \
-                (timeStr, aircraftState.heading)
-
-        if self._aircraftState is None or \
-           self._aircraftState.pitch != aircraftState.pitch:
-            print "Aircraft.handleState: %s: pitch=%f" % \
-                (timeStr, aircraftState.pitch)
-
-        if self._aircraftState is None or \
-           self._aircraftState.bank != aircraftState.bank:
-            print "Aircraft.handleState: %s: bank=%f" % \
-                (timeStr, aircraftState.bank)
-
-        if self._aircraftState is None or \
-           self._aircraftState.ias != aircraftState.ias:
-            print "Aircraft.handleState: %s: ias=%f" % \
-                (timeStr, aircraftState.ias)
-
-        if self._aircraftState is None or \
-           self._aircraftState.groundSpeed != aircraftState.groundSpeed:
-            print "Aircraft.handleState: %s: groundSpeed=%f" % \
-                (timeStr, aircraftState.groundSpeed)
-
-        if self._aircraftState is None or \
-           self._aircraftState.vs != aircraftState.vs:
-            print "Aircraft.handleState: %s: vs=%f" % \
-                (timeStr, aircraftState.vs)
-
-        if self._aircraftState is None or \
-           self._aircraftState.altitude != aircraftState.altitude:
-            print "Aircraft.handleState: %s: altitude=%f" % \
-                (timeStr, aircraftState.altitude)
-
-        if self._aircraftState is None or \
-           self._aircraftState.gLoad != aircraftState.gLoad:
-            print "Aircraft.handleState: %s: gLoad=%f" % \
-                (timeStr, aircraftState.gLoad)
-
-        if self._aircraftState is None or \
-           self._aircraftState.flapsSet != aircraftState.flapsSet:
-            print "Aircraft.handleState: %s: flapsSet=%f" % \
-                (timeStr, aircraftState.flapsSet)
-
-        if self._aircraftState is None or \
-           self._aircraftState.flaps != aircraftState.flaps:
-            print "Aircraft.handleState: %s: flaps=%f" % \
-                (timeStr, aircraftState.flaps)
-
-        if self._aircraftState is None or \
-           self._aircraftState.navLightsOn != aircraftState.navLightsOn:
-            print "Aircraft.handleState: %s: navLightsOn=%d" % \
-                (timeStr, aircraftState.navLightsOn)
-
-        if self._aircraftState is None or \
-           self._aircraftState.antiCollisionLightsOn != aircraftState.antiCollisionLightsOn:
-            print "Aircraft.handleState: %s: antiCollisionLightsOn=%d" % \
-                (timeStr, aircraftState.antiCollisionLightsOn)
-
-        if self._aircraftState is None or \
-           self._aircraftState.strobeLightsOn != aircraftState.strobeLightsOn:
-            print "Aircraft.handleState: %s: strobeLightsOn=%d" % \
-                (timeStr, aircraftState.strobeLightsOn)
-
-        if self._aircraftState is None or \
-           self._aircraftState.landingLightsOn != aircraftState.landingLightsOn:
-            print "Aircraft.handleState: %s: landingLightsOn=%d" % \
-                (timeStr, aircraftState.landingLightsOn)
-
-        if self._aircraftState is None or \
-           self._aircraftState.pitotHeatOn != aircraftState.pitotHeatOn:
-            print "Aircraft.handleState: %s: pitotHeatOn=%d" % \
-                (timeStr, aircraftState.pitotHeatOn)
-
-        if self._aircraftState is None or \
-           self._aircraftState.gearsDown != aircraftState.gearsDown:
-            print "Aircraft.handleState: %s: gearsDown=%f" % \
-                (timeStr, aircraftState.gearsDown)
-
-        if self._aircraftState is None or \
-           self._aircraftState.spoilersArmed != aircraftState.spoilersArmed:
-            print "Aircraft.handleState: %s: spoilersArmed=%f" % \
-                (timeStr, aircraftState.spoilersArmed)
-
-        if self._aircraftState is None or \
-           self._aircraftState.spoilersExtension != aircraftState.spoilersExtension:
-            print "Aircraft.handleState: %s: spoilersExtension=%f" % \
-                (timeStr, aircraftState.spoilersExtension)
-
-        if self._aircraftState is None or \
-           self._aircraftState.altimeter != aircraftState.altimeter:
-            print "Aircraft.handleState: %s: altimeter=%f" % \
-                (timeStr, aircraftState.altimeter)
-
-        if self._aircraftState is None or \
-           self._aircraftState.nav1 != aircraftState.nav1:
-            print "Aircraft.handleState: %s: nav1=%s" % \
-                (timeStr, aircraftState.nav1)
-
-        if self._aircraftState is None or \
-           self._aircraftState.nav2 != aircraftState.nav2:
-            print "Aircraft.handleState: %s: nav2=%s" % \
-                (timeStr, aircraftState.nav2)
-
-        if self._aircraftState is None or \
-           self._aircraftState.fuel != aircraftState.fuel:
-            print "Aircraft.handleState: %s: fuel=%s" % \
-                (timeStr, aircraftState.fuel)
-
-        if self._aircraftState is None or \
-           self._aircraftState.n1 != aircraftState.n1:
-            print "Aircraft.handleState: %s: n1=%s" % \
-                (timeStr, aircraftState.n1)
-
-        if self._aircraftState is None or \
-           self._aircraftState.reverser != aircraftState.reverser:
-            print "Aircraft.handleState: %s: reverser=%s" % \
-                (timeStr, aircraftState.reverser)
+        for checker in self._checkers:
+            checker.check(self._flight, self, self._flight.logger,
+                          self._aircraftState, aircraftState)
 
         self._aircraftState = aircraftState
-            
+    
+    def setStage(self, aircraftState, newStage):
+        """Set the given stage as the new one and do whatever should be
+        done."""
+        self._flight.setStage(aircraftState.timestamp, newStage)
+
+    def flare(self):
+        """Called when it is detected that we are during flare.
+
+        On the first call, it should start monitoring some parameters more
+        closely to determine flare time."""
+        pass
+
+    def cancelFlare(self):
+        """Cancel flare, if it has started."""
+        pass
+
+    def checkFlightEnd(self, aircraftState):
+        """Check if the end of the flight has arrived.
+
+        This default implementation checks the N1 values, but for
+        piston-powered aircraft you need to check the RPMs."""
+        for n1 in aircraftState.n1:
+            if n1>=0.5: return False
+        return True
+
 #---------------------------------------------------------------------------------------
 
@@ -198,6 +111,6 @@
 class B736(Boeing737):
     """Boeing 737-600 aircraft."""
-    def __init__(self):
-        super(B736, self).__init__(const.AIRCRAFT_B736)
+    def __init__(self, flight):
+        super(B736, self).__init__(flight)
 
 #---------------------------------------------------------------------------------------
@@ -205,6 +118,6 @@
 class B737(Boeing737):
     """Boeing 737-700 aircraft."""
-    def __init__(self):
-        super(B737, self).__init__(const.AIRCRAFT_B737)
+    def __init__(self, flight):
+        super(B737, self).__init__(flight)
 
 #---------------------------------------------------------------------------------------
@@ -212,6 +125,6 @@
 class B738(Boeing737):
     """Boeing 737-800 aircraft."""
-    def __init__(self):
-        super(B738, self).__init__(const.AIRCRAFT_B738)
+    def __init__(self, flight):
+        super(B738, self).__init__(flight)
 
 #---------------------------------------------------------------------------------------
@@ -219,6 +132,6 @@
 class B733(Boeing737):
     """Boeing 737-300 aircraft."""
-    def __init__(self):
-        super(B733, self).__init__(const.AIRCRAFT_B733)
+    def __init__(self, flight):
+        super(B733, self).__init__(flight)
 
 #---------------------------------------------------------------------------------------
@@ -226,6 +139,6 @@
 class B734(Boeing737):
     """Boeing 737-400 aircraft."""
-    def __init__(self):
-        super(B734, self).__init__(const.AIRCRAFT_B734)
+    def __init__(self, flight):
+        super(B734, self).__init__(flight)
 
 #---------------------------------------------------------------------------------------
@@ -233,6 +146,6 @@
 class B735(Boeing737):
     """Boeing 737-500 aircraft."""
-    def __init__(self):
-        super(B735, self).__init__(const.AIRCRAFT_B735)
+    def __init__(self, flight):
+        super(B735, self).__init__(flight)
 
 #---------------------------------------------------------------------------------------
@@ -246,6 +159,6 @@
     - n1: left, right
     - reverser: left, right."""
-    def __init__(self):
-        super(DH8D, self).__init__(const.AIRCRAFT_DH8D)
+    def __init__(self, flight):
+        super(DH8D, self).__init__(flight)
 
 #---------------------------------------------------------------------------------------
@@ -264,6 +177,6 @@
 class B762(Boeing767):
     """Boeing 767-200 aircraft."""
-    def __init__(self):
-        super(B762, self).__init__(const.AIRCRAFT_B762)
+    def __init__(self, flight):
+        super(B762, self).__init__(flight)
 
 #---------------------------------------------------------------------------------------
@@ -271,6 +184,6 @@
 class B763(Boeing767):
     """Boeing 767-300 aircraft."""
-    def __init__(self):
-        super(B763, self).__init__(const.AIRCRAFT_B763)
+    def __init__(self, flight):
+        super(B763, self).__init__(cflight)
 
 #---------------------------------------------------------------------------------------
@@ -284,6 +197,6 @@
     - n1: left, right
     - reverser: left, right."""
-    def __init__(self):
-        super(CRJ2, self).__init__(const.AIRCRAFT_CRJ2)
+    def __init__(self, flight):
+        super(CRJ2, self).__init__(flight)
 
 #---------------------------------------------------------------------------------------
@@ -297,6 +210,6 @@
     - n1: left, right
     - reverser: left, right."""
-    def __init__(self):
-        super(F70, self).__init__(const.AIRCRAFT_F70)
+    def __init__(self, flight):
+        super(F70, self).__init__(flight)
 
 #---------------------------------------------------------------------------------------
@@ -310,6 +223,14 @@
     - rpm: left, right
     - reverser: left, right."""
-    def __init__(self):
-        super(DC3, self).__init__(const.AIRCRAFT_DC3)
+    def __init__(self, flight):
+        super(DC3, self).__init__(flight)
+
+    def _checkFlightEnd(self, aircraftState):
+        """Check if the end of the flight has arrived.
+
+        This implementation checks the RPM values to be 0."""
+        for rpm in aircraftState.rpm:
+            if rpm>0: return
+        self._setStage(aircraftState, const.STAGE_END)
 
 #---------------------------------------------------------------------------------------
@@ -324,6 +245,6 @@
     - n1: left, right
     - reverser: left, right."""
-    def __init__(self):
-        super(T134, self).__init__(const.AIRCRAFT_T134)
+    def __init__(self, flight):
+        super(T134, self).__init__(flight)
 
 #---------------------------------------------------------------------------------------
@@ -337,6 +258,6 @@
     - n1: left, centre, right
     - reverser: left, right"""
-    def __init__(self):
-        super(T154, self).__init__(const.AIRCRAFT_T154)
+    def __init__(self, flight):
+        super(T154, self).__init__(flight)
 
 #---------------------------------------------------------------------------------------
@@ -350,7 +271,24 @@
     - n1: left, right
     - reverser: left, right"""
-    def __init__(self):
-        super(YK40, self).__init__(const.AIRCRAFT_YK40)
-
-#---------------------------------------------------------------------------------------
-
+    def __init__(self, flight):
+        super(YK40, self).__init__(flight)
+
+#---------------------------------------------------------------------------------------
+
+_classes = { const.AIRCRAFT_B736 : B736,
+             const.AIRCRAFT_B737 : B737,
+             const.AIRCRAFT_B738 : B738,
+             const.AIRCRAFT_B733 : B733,
+             const.AIRCRAFT_B734 : B734,
+             const.AIRCRAFT_B735 : B735,
+             const.AIRCRAFT_DH8D : DH8D,
+             const.AIRCRAFT_B762 : B762,
+             const.AIRCRAFT_B763 : B763,
+             const.AIRCRAFT_CRJ2 : CRJ2,
+             const.AIRCRAFT_F70 : F70,
+             const.AIRCRAFT_DC3 : DC3,
+             const.AIRCRAFT_T134 : T134,
+             const.AIRCRAFT_T154 : T154,
+             const.AIRCRAFT_YK40 : YK40 }
+
+#---------------------------------------------------------------------------------------
