class Behaviors():

    def __init__(self, robot, algorithm):
        self.robot = robot 
        self.lasso = Lasso()
        self.algorithm = algorithm
        self.state = algorithm.getInitialState(self.getSensorState())
        self.terminate = False

        self.behaviors = {
            "explore": self.explore,
            "faceObject": self.faceObject,
            "stop": self.stop,
            "identifyMoveableObject": self.identifyMoveableObject,
            "grab": self.grab,
            "release": self.release,
            "tryGrab": self.tryGrab,
        }

    def run(self):
        behaviorResult = None
        while not self.terminate:
            self.state = self.algorithm.eventHandler(self.state,
                    self.getSensorState(), behaviorResult)
            behaviorResult = self.behaviors[self.state]()

    def getSensorState(self):
        return {
            "frontSensors": self.robot.getFrontSensors(),
            "groundSensors": self.robot.getGroundSensors(),
            "rearSensors": self.robot.getRearSensors(),
            "accelerometer": self.robot.getAccelerometer(),
            "micIntensity": self.robot.getMicIntensity(),
            "lassoState": self.lasso.getState()
        }

    def safe(self):
        return not self.robot.overEdge()

    def grab(self):
        self.lasso.up()
        self.robot.left(10)
        self.robot.backwards(2)
        while len(filter(lambda x: x > 2500, self.robot.getRearSensors())) > 0:
            self.robot.forward(0.1)
        self.lasso.down()

    def tryGrab(self):
        self.grab()
        self.robot.forward(5)
        time.sleep(1.5)
        if len(filter(lambda x: x > 1000, self.robot.getRearSensors())) == 0:
            self.release()
            return
        
        before_sensors = self.robot.getRearSensors()
        self.robot.forward(1)
        time.sleep(0.5)
        after_sensors = self.robot.getRearSensors()
        if len(filter(lambda (x,y): abs(x-y) > 100, zip(before_sensors, after_sensors))) == 0:
            self.release()
            return

        self.robot.left(5)
        if len(filter(lambda x: x > 1000, self.robot.getRearSensors())) == 0:
            self.release()