# Path: intelligine/core/exceptions.py
# class DirectionException(Exception):
#     pass
# 
# Path: intelligine/simulation/object/brain/part/BrainPart.py
# class BrainPart():
# 
#     def __init__(self, host_brain):
#         self._host_brain = host_brain
#         self._context = self._host_brain.get_context()
#         self._host = self._host_brain.get_host()
# 
#     def get_host_brain(self):
#         return self._host_brain
# 
#     def get_host(self):
#         return self.get_host_brain().get_host()
# 
#     def done(self):
#         pass
# 
# Path: intelligine/synergy/event/move/direction.py
# NORTH = 11
# NORTH_EST = 12
# EST = 15
# SOUTH_EST = 18
# SOUTH = 17
# SOUTH_WEST = 16
# WEST = 13
# NORTH_WEST = 10
# CENTER = 14
# def get_direction_for_degrees(degrees):
# def get_direction_opposite(direction):
# def get_position_with_direction_decal(direction=CENTER, point=(0, 0, 0)):


from intelligine.core.exceptions import DirectionException
from intelligine.simulation.object.brain.part.BrainPart import BrainPart
from intelligine.synergy.event.move.direction import directions_same_level, directions_slighty
from random import randint, choice, randrange
from synergine_xyz.cst import BLOCKED_SINCE, PREVIOUS_DIRECTION

class MoveBrainPart(BrainPart):

    @classmethod
    def get_direction(cls, context, object_id):
        try:
            return cls._get_slighty_direction(context, object_id)
        except DirectionException:
            return cls._get_random_direction(context, object_id)

    @classmethod
    def _get_slighty_direction(cls, context, object_id):
        # TODO: A terme le calcul de la direction devra prendre en compte les directions bloques
        blocked_since = context.metas.value.get(BLOCKED_SINCE, object_id, allow_empty=True, empty_value=0)
        if blocked_since <= 3:  #TODO: config
            try:
                previous_direction = context.metas.value.get(PREVIOUS_DIRECTION, object_id)
            except KeyError:
                # No previous direction
                return cls._get_random_direction(context, object_id)
            # TODO: Faut mettre ca en plus propre (proba d'aller tou droit, config, etc)
            if randrange(100) < 75:  # 75% de change d'aller tout droit
                # Dans le futur: les fourmis vont moins tout droit quand elle se croient et se touche
                return previous_direction

            directions_list = directions_slighty[previous_direction]
            # TODO: TMP tant que 1 niveau (z)
            directions_list = [direction for direction in directions_list if 9 < direction < 19]
            return choice(directions_list)


# Path: intelligine/core/exceptions.py
# class DirectionException(Exception):
#     pass
# 
# Path: intelligine/simulation/object/brain/part/BrainPart.py
# class BrainPart():
# 
#     def __init__(self, host_brain):
#         self._host_brain = host_brain
#         self._context = self._host_brain.get_context()
#         self._host = self._host_brain.get_host()
# 
#     def get_host_brain(self):
#         return self._host_brain
# 
#     def get_host(self):
#         return self.get_host_brain().get_host()
# 
#     def done(self):
#         pass
# 
# Path: intelligine/synergy/event/move/direction.py
# NORTH = 11
# NORTH_EST = 12
# EST = 15
# SOUTH_EST = 18
# SOUTH = 17
# SOUTH_WEST = 16
# WEST = 13
# NORTH_WEST = 10
# CENTER = 14
# def get_direction_for_degrees(degrees):
# def get_direction_opposite(direction):
# def get_position_with_direction_decal(direction=CENTER, point=(0, 0, 0)):


# Path: intelligine/simulation/object/brain/part/move/MoveBrainPart.py
from intelligine.core.exceptions import DirectionException
from intelligine.simulation.object.brain.part.BrainPart import BrainPart
from intelligine.synergy.event.move.direction import directions_same_level, directions_slighty
from random import randint, choice, randrange
from synergine_xyz.cst import BLOCKED_SINCE, PREVIOUS_DIRECTION


class MoveBrainPart(BrainPart):

    @classmethod
    def get_direction(cls, context, object_id):
        try:
            return cls._get_slighty_direction(context, object_id)
        except DirectionException:
            return cls._get_random_direction(context, object_id)

    @classmethod
    def _get_slighty_direction(cls, context, object_id):
        # TODO: A terme le calcul de la direction devra prendre en compte les directions bloques
        blocked_since = context.metas.value.get(BLOCKED_SINCE, object_id, allow_empty=True, empty_value=0)
        if blocked_since <= 3:  #TODO: config
            try:
                previous_direction = context.metas.value.get(PREVIOUS_DIRECTION, object_id)
            except KeyError:
                # No previous direction
                return cls._get_random_direction(context, object_id)
            # TODO: Faut mettre ca en plus propre (proba d'aller tou droit, config, etc)
            if randrange(100) < 75:  # 75% de change d'aller tout droit
                # Dans le futur: les fourmis vont moins tout droit quand elle se croient et se touche
                return previous_direction

            directions_list = directions_slighty[previous_direction]
            # TODO: TMP tant que 1 niveau (z)
            directions_list = [direction for direction in directions_list if 9 < direction < 19]
            return choice(directions_list)


        raise DirectionException()