class FixedPointSimulatorApp(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.title('Fixed-Point Gibbot Simulator')

        self.controller = controllerTypes[0]()
        self.bot = defaultBot
        self.timeScale = TIME_SCALE
        self.t = 0 # elapsed simulation time

        self.inputFrame = FixedPointInputFrame(self, controllerTypes, TIME_SCALE, defaultBot, self.restart)
        self.inputFrame.grid(row=0, column=0, sticky=N+W)

        self.gibbotFrame = FixedPointGibbotFrame(self)
        self.gibbotFrame.grid(row=0, column=1, sticky=N+S+E+W)
        self.rowconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)

        self.startTime = time.time()
        self.animate()

    def animate(self):
        self.animating = True
        frameStartTime = time.time()

        # update UI
        self.inputFrame.update(self.bot, self.t)
        self.gibbotFrame.update(self.bot)

        # advance physics
        while self.t / self.timeScale < frameStartTime - self.startTime:
            controlTorque = self.controller.control(self.bot)
            beforeQ1 = self.bot.q1
            self.bot.advanceState(controlTorque, DT)
            if abs(beforeQ1 - self.bot.q1) > 4:
                print '*** flipped at time', self.t, '***'
                self.animating = False
                return
            self.t += DT

        # schedule next frame
        self.after(1, self.animate)

    def restart(self, controllerType, timeScale, bot):
        print '** RESTART **'
        self.controller = controllerType()
        self.timeScale = timeScale
        self.bot = bot
        self.t = 0
        self.startTime = time.time()
        if not self.animating:
            self.animate()
class FixedPointSimulatorApp(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.title('Fixed-Point Gibbot Simulator')

        self.controller = controllerTypes[0]()
        self.bot = defaultBot
        self.timeScale = 1
        self.t = 0

        self.inputFrame = FixedPointInputFrame(self, controllerTypes, TIME_SCALE, defaultBot, self.restart)
        self.inputFrame.grid(row=0, column=0, sticky=N+W)

        self.gibbotFrame = FixedPointGibbotFrame(self)
        self.gibbotFrame.grid(row=0, column=1, sticky=N+S+E+W)
        self.rowconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)


        self.animate()

    def animate(self):
        frameStartTime = time.time()
        frameInterval = 1.0/FPS

        # update UI
        self.inputFrame.update(self.bot, self.t)
        self.gibbotFrame.update(self.bot)

        # advance physics
        simulationInterval = frameInterval * self.timeScale
        simulationTicks = int(simulationInterval / DT)
        for i in xrange(0, simulationTicks):
            controlTorque = self.controller.control(self.bot)
            self.bot.advanceState(controlTorque, DT)
        self.t += simulationInterval

        # schedule next frame
        waitTime = frameStartTime + frameInterval - time.time()
        millis = int(waitTime * 1000)
        if millis < 1:
            millis = 1
        self.after(millis, self.animate)

    def restart(self, controllerType, timeScale, bot):
        print '** RESTART **'
        self.controller = controllerType()
        self.timeScale = timeScale
        self.bot = bot
        self.t = 0
    def __init__(self):
        Tk.__init__(self)
        self.title('Fixed-Point Gibbot Simulator')

        self.controller = controllerTypes[0]()
        self.bot = defaultBot
        self.timeScale = 1
        self.t = 0

        self.inputFrame = FixedPointInputFrame(self, controllerTypes, TIME_SCALE, defaultBot, self.restart)
        self.inputFrame.grid(row=0, column=0, sticky=N+W)

        self.gibbotFrame = FixedPointGibbotFrame(self)
        self.gibbotFrame.grid(row=0, column=1, sticky=N+S+E+W)
        self.rowconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)


        self.animate()