# Path: compositecore.py
# class Leaf(Component):
#     """
#     Abstract leaf class of composite design pattern.
# 
#     Component classes of leaf type should inherit from this class.
#     """
# 
#     def __init__(self):
#         super(Leaf, self).__init__()
# 
#     def get_relative_of_type(self, component_type):
#         return self.parent.get_child_or_ancestor(component_type)
# 
#     def has_relative_of_type(self, component_type):
#         return self.parent.has_child_or_ancestor(component_type)
# 
# Path: position.py
# class DungeonLevel(Leaf):
#     """
#     Composites holding this is in a DungeonLevel.
#     """
#     def __init__(self):
#         super(DungeonLevel, self).__init__()
#         self.component_type = "dungeon_level"
#         self._value = None
#         self.last_dungeon_level = None
# 
#     @property
#     def value(self):
#         """
#         Gets the dungeon_level the entity is currently in.
#         """
#         return self._value
# 
#     @value.setter
#     def value(self, new_dungeon_level):
#         """
#         Sets current dungeon_level of the entity.
#         Also updates the visibility/solidity of the dungeon_level tiles.
#         """
#         if not self._value is new_dungeon_level:
#             old_dungeon_level = self._value
#             self._value = new_dungeon_level
#             self._signal_dungeon_level_changed()
#             if(not old_dungeon_level is None and
#                self.has_sibling("actor")):
#                 old_dungeon_level.remove_actor_if_present(self.parent)
#                 self.last_dungeon_level = old_dungeon_level
#         if self.last_dungeon_level is None:
#             self.last_dungeon_level = new_dungeon_level
# 
#     def _signal_dungeon_level_changed(self):
#         """
#         Is called when dungeon level has changed.
#         """
#         if self.has_parent() and not self.value is None:
#             self.parent.send_message(CompositeMessage.DUNGEON_LEVEL_CHANGED)
#             if self.has_sibling("actor"):
#                 self.value.add_actor_if_not_present(self.parent)
#             if self.has_sibling("is_dungeon_feature"):
#                 self.value.add_dungeon_feature_if_not_present(self.parent)
# 
#     def on_parent_changed(self):
#         """
#         When the parent changes try to add it to the dungeon.
#         """
#         self._signal_dungeon_level_changed()
# 
# Path: stats.py
# def max_instances_of_composite_on_tile(composite):
#     return GamePieceTypes.MAX_INSTANCES_ON_TILE[composite.game_piece_type.value]
# 
# class IntelligenceLevel(DataPoint):
#     MINDLESS = 0
#     PLANT = 1
#     ANIMAL = 2
#     NORMAL = 3
#     HIGH = 4
# 
# Path: statusflags.py
# class StatusFlags(Leaf):
#     """
#     Composites holding this has status flags, describing their behaviour.
#     """
#     INVISIBILE = 0
#     SEE_INVISIBILITY = 1
#     FLYING = 2
#     IS_ALIVE = 3
#     CAN_OPEN_DOORS = 4
#     HAS_HEART = 5
# 
#     def __init__(self, status_flags=[]):
#         super(StatusFlags, self).__init__()
#         self.component_type = "status_flags"
#         self._status_flags = set(status_flags)
#         self._temp_status_flags = set()
# 
#     def has_status(self, status):
#         """
#         Returns True if parent entity has the status given.
#         """
#         if not self.next is None:
#             return (status in self._status_flags or
#                     status in self._temp_status_flags or
#                     next.has_status(status))
#         else:
#             return (status in self._status_flags or
#                     status in self._temp_status_flags)
# 
#     def add_temp_status(self, status):
#         """
#         Adds a temporary status that will be removed the next tick.
#         """
#         self._temp_status_flags.add(status)
# 
#     def before_tick(self, time):
#         self._temp_status_flags = set()


import random
import Status
import direction
import geometry
import trigger
from compositecore import Leaf
from position import DungeonLevel
from stats import max_instances_of_composite_on_tile, IntelligenceLevel
from statusflags import StatusFlags
        Moves parent to new position, assumes that it fits there.
        """
        self._remove_from_old_tile()
        dungeon_level.get_tile(new_position).add(self.parent)
        self.parent.position.value = new_position
        if not self.has_sibling("dungeon_level"):
            self.parent.set_child(DungeonLevel())
        self.parent.dungeon_level.value = dungeon_level

    def replace_move(self, new_position, new_dungeon_level=None):
        """
        Moves parent to new position and replaces what was already there.
        """
        if new_dungeon_level is None:
            new_dungeon_level = self.parent.dungeon_level.value
        if not new_dungeon_level.has_tile(new_position):
            return False
        new_tile = new_dungeon_level.get_tile(new_position)
        self._remove_from_old_tile()
        piece_type = self.parent.game_piece_type.value
        new_place = new_tile.game_pieces[piece_type]
        for piece in new_place:
            piece.mover.try_remove_from_dungeon()
        return self.try_move(new_position, new_dungeon_level)

    def _can_fit_on_tile(self, tile):
        """
        Checks if the parent can fit on the tile.
        """
        piece_type = self.parent.game_piece_type

# Path: compositecore.py
# class Leaf(Component):
#     """
#     Abstract leaf class of composite design pattern.
# 
#     Component classes of leaf type should inherit from this class.
#     """
# 
#     def __init__(self):
#         super(Leaf, self).__init__()
# 
#     def get_relative_of_type(self, component_type):
#         return self.parent.get_child_or_ancestor(component_type)
# 
#     def has_relative_of_type(self, component_type):
#         return self.parent.has_child_or_ancestor(component_type)
# 
# Path: position.py
# class DungeonLevel(Leaf):
#     """
#     Composites holding this is in a DungeonLevel.
#     """
#     def __init__(self):
#         super(DungeonLevel, self).__init__()
#         self.component_type = "dungeon_level"
#         self._value = None
#         self.last_dungeon_level = None
# 
#     @property
#     def value(self):
#         """
#         Gets the dungeon_level the entity is currently in.
#         """
#         return self._value
# 
#     @value.setter
#     def value(self, new_dungeon_level):
#         """
#         Sets current dungeon_level of the entity.
#         Also updates the visibility/solidity of the dungeon_level tiles.
#         """
#         if not self._value is new_dungeon_level:
#             old_dungeon_level = self._value
#             self._value = new_dungeon_level
#             self._signal_dungeon_level_changed()
#             if(not old_dungeon_level is None and
#                self.has_sibling("actor")):
#                 old_dungeon_level.remove_actor_if_present(self.parent)
#                 self.last_dungeon_level = old_dungeon_level
#         if self.last_dungeon_level is None:
#             self.last_dungeon_level = new_dungeon_level
# 
#     def _signal_dungeon_level_changed(self):
#         """
#         Is called when dungeon level has changed.
#         """
#         if self.has_parent() and not self.value is None:
#             self.parent.send_message(CompositeMessage.DUNGEON_LEVEL_CHANGED)
#             if self.has_sibling("actor"):
#                 self.value.add_actor_if_not_present(self.parent)
#             if self.has_sibling("is_dungeon_feature"):
#                 self.value.add_dungeon_feature_if_not_present(self.parent)
# 
#     def on_parent_changed(self):
#         """
#         When the parent changes try to add it to the dungeon.
#         """
#         self._signal_dungeon_level_changed()
# 
# Path: stats.py
# def max_instances_of_composite_on_tile(composite):
#     return GamePieceTypes.MAX_INSTANCES_ON_TILE[composite.game_piece_type.value]
# 
# class IntelligenceLevel(DataPoint):
#     MINDLESS = 0
#     PLANT = 1
#     ANIMAL = 2
#     NORMAL = 3
#     HIGH = 4
# 
# Path: statusflags.py
# class StatusFlags(Leaf):
#     """
#     Composites holding this has status flags, describing their behaviour.
#     """
#     INVISIBILE = 0
#     SEE_INVISIBILITY = 1
#     FLYING = 2
#     IS_ALIVE = 3
#     CAN_OPEN_DOORS = 4
#     HAS_HEART = 5
# 
#     def __init__(self, status_flags=[]):
#         super(StatusFlags, self).__init__()
#         self.component_type = "status_flags"
#         self._status_flags = set(status_flags)
#         self._temp_status_flags = set()
# 
#     def has_status(self, status):
#         """
#         Returns True if parent entity has the status given.
#         """
#         if not self.next is None:
#             return (status in self._status_flags or
#                     status in self._temp_status_flags or
#                     next.has_status(status))
#         else:
#             return (status in self._status_flags or
#                     status in self._temp_status_flags)
# 
#     def add_temp_status(self, status):
#         """
#         Adds a temporary status that will be removed the next tick.
#         """
#         self._temp_status_flags.add(status)
# 
#     def before_tick(self, time):
#         self._temp_status_flags = set()


# Path: mover.py
import random
import Status
import direction
import geometry
import trigger
from compositecore import Leaf
from position import DungeonLevel
from stats import max_instances_of_composite_on_tile, IntelligenceLevel
from statusflags import StatusFlags

        Moves parent to new position, assumes that it fits there.
        """
        self._remove_from_old_tile()
        dungeon_level.get_tile(new_position).add(self.parent)
        self.parent.position.value = new_position
        if not self.has_sibling("dungeon_level"):
            self.parent.set_child(DungeonLevel())
        self.parent.dungeon_level.value = dungeon_level

    def replace_move(self, new_position, new_dungeon_level=None):
        """
        Moves parent to new position and replaces what was already there.
        """
        if new_dungeon_level is None:
            new_dungeon_level = self.parent.dungeon_level.value
        if not new_dungeon_level.has_tile(new_position):
            return False
        new_tile = new_dungeon_level.get_tile(new_position)
        self._remove_from_old_tile()
        piece_type = self.parent.game_piece_type.value
        new_place = new_tile.game_pieces[piece_type]
        for piece in new_place:
            piece.mover.try_remove_from_dungeon()
        return self.try_move(new_position, new_dungeon_level)

    def _can_fit_on_tile(self, tile):
        """
        Checks if the parent can fit on the tile.
        """
        piece_type = self.parent.game_piece_type

        return len(tile.game_pieces[piece_type.value]) < max_instances_of_composite_on_tile(self.parent)