# Given two terminating behaviors and a condition, 
# Execute the first if the condition is true, and the second if the
# condition is false 
# Call the relevant start procedure whenever we switch
# Terminate if the relevant one is done

class TBConditional:
    def __init__(self, conditionFun, tb1, tb2):
        self.conditionFun = conditionFun
        self.tb1 = tb1
        self.tb2 = tb2

    def start(self):
        self.runningB1 = self.conditionFun()
        if self.runningB1:
            self.tb1.start()
        else:
            self.tb2.start()

    def step(self):
        shouldRunB1 = self.conditionFun()
        if shouldRunB1 and self.runningB1:
            self.tb1.step()
        elif shouldRunB1:
            self.runningB1 = True
            self.tb1.start()
            self.tb1.step()
        elif not self.runningB1:
            self.tb2.step()
        else:
            self.runningB1 = False
            self.tb2.start()
            self.tb2.step()

class TBParallelWithFun:
    def __init__(self, tb, fun):
        self.fun = fun
        self.tb = tb
    def start(self):
        self.tb.start()
        self.fun()
    def step(self):
        self.tb.step()
        self.fun()
    def done(self):
        return self.tb.done()

class TBSequence:
    def __init__(self, actions):
        self.actions = actions

    def start(self):
        self.counter = 0
        self.actions[0].start()

    def step(self):
        currentAction = self.actions[self.counter]
        currentAction.step()
        if currentAction.done():
            self.counter += 1
            if self.counter < len(self.actions):
                self.actions[self.counter].start()

    def done(self):
        return self.counter == len(self.actions)


class TBStream:
    # An action generator either returns a behavior or None
    def __init__(self, actionGenerator):
        self.actionGenerator = actionGenerator

    def start(self):
        self.currentAction = self.actionGenerator()
        self.currentAction.start()

    def step(self):
        self.currentAction.step()
        if self.currentAction.done():
            self.start()
            
    def done(self):
        return False


class Stop:
    def __init__(self, motorOutput):
        self.motorOutput = motorOutput
    def start(self):
        pass
    def step(self):
        self.motorOutput(0.0, 0.0)
    def done(self):
        return True



    


