# Path: attacker.py
# class DamageTypes(object):
#     PHYSICAL = "physical_damage_type"
#     MAGIC = "magic_damage_type"
#     BLUNT = "blunt_damage_type"
#     PIERCING = "piercing_damage_type"
#     CUTTING = "cutting_damage_type"
#     BLEED = "bleed_damage_type"
#     ACID = "acid_damage_type"
#     POISON = "poison_damage_type"
#     LIGHTNING = "lightning_damage_type"
#     FIRE = "fire_damage_type"
#     REFLECT = "reflect_damage_type"
# 
#     IGNORE_ARMOR = "ignore_armor_damage_type"
# 
#     FALL = "fall_damage_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: dungeontrash.py
# class PoolOfBlood(Composite):
#     """
#     A pool of blood. Totally useless but looks nice
#     and gives the user feedback when a monster is hurt.
#     """
#     def __init__(self):
#         super(PoolOfBlood, self).__init__()
#         self.set_child(DataPoint(DataTypes.GAME_PIECE_TYPE, GamePieceTypes.DUNGEON_TRASH))
#         self.set_child(Position())
#         self.set_child(DungeonLevel())
#         self.set_child(Description("A pool of blood.", "A pool of blood."))
#         self.set_child(GraphicChar(None, colors.RED, random.choice(icon.BLOOD_ICONS)))
#         self.set_child(CharPrinter())
#         self.set_child(Mover())
# 
# Path: graphic.py
# class GraphicChar(Leaf):
#     """
#     Composites holding this has a graphical representation as a char.
#     """
# 
#     def __init__(self, color_bg, color_fg, icon):
#         super(GraphicChar, self).__init__()
#         self.component_type = "graphic_char"
#         self._color_bg = color_bg
#         self._color_fg = color_fg
#         self._icon = icon
# 
#     @property
#     def color_bg(self):
#         if self._color_bg:
#             return self._color_bg
#         elif self.next:
#             return self.next.color_bg
#         return None
# 
# 
#     @color_bg.setter
#     def color_bg(self, value):
#         self._color_bg = value
# 
#     @property
#     def color_fg(self):
#         if self._color_fg:
#             return self._color_fg
#         elif self.next:
#             return self.next.color_fg
#         return None
# 
#     @color_fg.setter
#     def color_fg(self, value):
#         self._color_fg = value
# 
#     @property
#     def icon(self):
#         if self._icon:
#             return self._icon
#         elif self.next:
#             return self.next.icon
#         return None
# 
#     @icon.setter
#     def icon(self, value):
#         self._icon = value
# 
#     def copy(self):
#         """
#         Makes a copy of this component.
#         """
#         return GraphicChar(self.color_bg, self.color_fg, self.icon)
# 
# Path: messenger.py
# NO_LONGER_PARALYZED_MESSAGE = "%(source_entity)s is no longer paralyzed."


import logging
import counter
import colors
import entityeffect
import geometry
import icon
import rng
import settings
import shapegenerator
from attacker import DamageTypes
from compositecore import Leaf
from dungeontrash import PoolOfBlood
from graphic import GraphicChar
from messenger import NO_LONGER_PARALYZED_MESSAGE

class HealthModifier(Leaf):
    def __init__(self):
        super(HealthModifier, self).__init__()
        self.component_type = "health_modifier"

    def hurt(self, damage, entity=None, damage_types=[]):
        """
        Damages the entity by reducing hp by damage.
        """
        if damage == 0 and rng.coin_flip():
            damage = 1  # You should never be completely safe
        if damage == 0:
            return damage
        self.parent.health.hp.decrease(damage)
        self._animate_hurt(damage_types)
        if self.parent.health.is_dead():
            self.parent.health.killer = entity
        self._call_damage_taken_effect(damage, entity, damage_types)
        return damage

    def _animate_hurt(self, damage_types):
        """
        Adds a blink animation to hurt entity.
        """
        frame_length = max(settings.ANIMATION_DELAY / 2, 1)
        hurt_colors = self._get_hurt_colors(damage_types)
        self.parent.char_printer.append_fg_color_blink_frames(hurt_colors, frame_length)

    def _get_hurt_colors(self, damage_types):

# Path: attacker.py
# class DamageTypes(object):
#     PHYSICAL = "physical_damage_type"
#     MAGIC = "magic_damage_type"
#     BLUNT = "blunt_damage_type"
#     PIERCING = "piercing_damage_type"
#     CUTTING = "cutting_damage_type"
#     BLEED = "bleed_damage_type"
#     ACID = "acid_damage_type"
#     POISON = "poison_damage_type"
#     LIGHTNING = "lightning_damage_type"
#     FIRE = "fire_damage_type"
#     REFLECT = "reflect_damage_type"
# 
#     IGNORE_ARMOR = "ignore_armor_damage_type"
# 
#     FALL = "fall_damage_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: dungeontrash.py
# class PoolOfBlood(Composite):
#     """
#     A pool of blood. Totally useless but looks nice
#     and gives the user feedback when a monster is hurt.
#     """
#     def __init__(self):
#         super(PoolOfBlood, self).__init__()
#         self.set_child(DataPoint(DataTypes.GAME_PIECE_TYPE, GamePieceTypes.DUNGEON_TRASH))
#         self.set_child(Position())
#         self.set_child(DungeonLevel())
#         self.set_child(Description("A pool of blood.", "A pool of blood."))
#         self.set_child(GraphicChar(None, colors.RED, random.choice(icon.BLOOD_ICONS)))
#         self.set_child(CharPrinter())
#         self.set_child(Mover())
# 
# Path: graphic.py
# class GraphicChar(Leaf):
#     """
#     Composites holding this has a graphical representation as a char.
#     """
# 
#     def __init__(self, color_bg, color_fg, icon):
#         super(GraphicChar, self).__init__()
#         self.component_type = "graphic_char"
#         self._color_bg = color_bg
#         self._color_fg = color_fg
#         self._icon = icon
# 
#     @property
#     def color_bg(self):
#         if self._color_bg:
#             return self._color_bg
#         elif self.next:
#             return self.next.color_bg
#         return None
# 
# 
#     @color_bg.setter
#     def color_bg(self, value):
#         self._color_bg = value
# 
#     @property
#     def color_fg(self):
#         if self._color_fg:
#             return self._color_fg
#         elif self.next:
#             return self.next.color_fg
#         return None
# 
#     @color_fg.setter
#     def color_fg(self, value):
#         self._color_fg = value
# 
#     @property
#     def icon(self):
#         if self._icon:
#             return self._icon
#         elif self.next:
#             return self.next.icon
#         return None
# 
#     @icon.setter
#     def icon(self, value):
#         self._icon = value
# 
#     def copy(self):
#         """
#         Makes a copy of this component.
#         """
#         return GraphicChar(self.color_bg, self.color_fg, self.icon)
# 
# Path: messenger.py
# NO_LONGER_PARALYZED_MESSAGE = "%(source_entity)s is no longer paralyzed."


# Path: health.py
import logging
import counter
import colors
import entityeffect
import geometry
import icon
import rng
import settings
import shapegenerator
from attacker import DamageTypes
from compositecore import Leaf
from dungeontrash import PoolOfBlood
from graphic import GraphicChar
from messenger import NO_LONGER_PARALYZED_MESSAGE


class HealthModifier(Leaf):
    def __init__(self):
        super(HealthModifier, self).__init__()
        self.component_type = "health_modifier"

    def hurt(self, damage, entity=None, damage_types=[]):
        """
        Damages the entity by reducing hp by damage.
        """
        if damage == 0 and rng.coin_flip():
            damage = 1  # You should never be completely safe
        if damage == 0:
            return damage
        self.parent.health.hp.decrease(damage)
        self._animate_hurt(damage_types)
        if self.parent.health.is_dead():
            self.parent.health.killer = entity
        self._call_damage_taken_effect(damage, entity, damage_types)
        return damage

    def _animate_hurt(self, damage_types):
        """
        Adds a blink animation to hurt entity.
        """
        frame_length = max(settings.ANIMATION_DELAY / 2, 1)
        hurt_colors = self._get_hurt_colors(damage_types)
        self.parent.char_printer.append_fg_color_blink_frames(hurt_colors, frame_length)

    def _get_hurt_colors(self, damage_types):

        if DamageTypes.POISON in damage_types: