# Path: combat/enums.py
# class TargetType(Enum):
# class DamageType(Enum):
# class ThreatLevel(Enum):
# 
# Path: combat/attack.py
# class MeleeAttackTemplate(AttackTemplate):
#     def __init__(self, name, description, message, required_item_melee_damage_type,
#                  target_type=enums.TargetType.Single, attack_range=0, modifiers=None, hit_stat_used=StatsEnum.Strength,
#                  damage_stat_used=StatsEnum.Strength, requirements=None):
# 
#         super().__init__(name=name, description=description, message=message, target_type=target_type,
#                          attack_range=attack_range, modifiers=modifiers, hit_stat_used=hit_stat_used,
#                          damage_stat_used=damage_stat_used, damage_type=None, requirements=requirements)
# 
#         self.required_item_melee_damage_type = required_item_melee_damage_type
# 
#     def make_attack(self, attacker, defender, **kwargs):
#         attacker_weapon = self.get_used_weapon(attacker)
#         return super().make_attack(attacker, defender, attacker_weapon=attacker_weapon)
# 
#     def get_hit_bonus(self, attacker, **kwargs):
#         # TODO Weapon could have bonuses to hit
#         return super().get_hit_bonus(attacker, **kwargs)
# 
#     def get_damage_bonus(self, attacker, **kwargs):
#         # TODO Weapon could have bonuses to damage
#         return super().get_damage_bonus(attacker, **kwargs)
# 
#     def get_damage_dice(self, **kwargs):
#         attacker_weapon = kwargs.get("attacker_weapon")
#         return attacker_weapon.weapon.damage_dice
# 
#     def get_used_weapon(self, attacker):
#         for wielded_item in attacker.equipment.get_wielded_items():
#             weapon = wielded_item.get_component('weapon')
#             if weapon.melee_damage_type == self.required_item_melee_damage_type:
#                 return wielded_item
# 
#     def get_damage_type(self, **kwargs):
#         item = kwargs.get("attacker_weapon")
#         if item.weapon:
#             return item.weapon.melee_damage_type
#         else:
#             # TODO This indicates an improvised weapon. We'll need to get a better way to handle this.
#             return DamageType.Blunt
# 
# Path: stats/enums.py
# class StatsEnum(Enum):
#     Health = 'health'
#     Mana = 'mana'
#     Strength = 'strength'
#     Dexterity = 'dexterity'
#     Constitution = 'constitution'
#     Intelligence = 'intelligence'
#     Charisma = 'charisma'
#     Wisdom = 'wisdom'
#     Sharpness = 'sharpness'
#     Hardness = 'hardness'
#     Weight = 'weight'
#     Size = 'size'
#     Potency = 'potency'
#     MaxDamage = 'max_damage'
#     MinDamage = 'min_damage'
#     ArmorClass = 'armor_class'
# 
# Path: managers/echo.py
# class EchoService(object):
# class MessageVariables(Enum):
#     def __init__(self, console, game_context):
#     def combat_context_echo(self, message, attacker=None, defender=None,
#                             attacker_weapon=None, defender_weapon=None, defender_bodypart=None):
# def his_her_it(target, **kwargs):
# def him_her_it(target, **kwargs):
# def he_her_it(target, **kwargs):
# def name_or_you(target, **kwargs):
# 
# Path: util/colors.py
# class Colors:
#     BLACK_COLOR = (0, 0, 0)
#     WHITE_COLOR = (255, 255, 255)
#     DARK_BLUE = (0, 0, 100)
#     DARK_GRAY = (75, 75, 75)
#     TROLL_GREEN = (100, 180, 150)
#     ORC_GREEN = (150, 250, 230)
#     BLOOD_RED = (255, 50, 50)


import random
from combat import enums as combat_enums
from combat.attack import MeleeAttackTemplate
from stats.enums import StatsEnum
from managers import echo
from util.colors import Colors
        take_damage(defender, attack_result)
    else:
        choose_defense(attacker, defender, attack_result.total_hit_roll).make_defense(attacker, defender)
    echo.EchoService.singleton.console.printStr(str(attack_result) + "\n")


def take_damage(actor, attack_result):
    # TODO Here we take each damage dealt, apply resistance
    # TODO Determine threat level for total damage
    if attack_result.total_damage <= 0:
        return
    damage_string = "... "
    wound_strings = []

    for damage, damage_type in attack_result.separated_damage:
        if damage > 0:
            wound_strings.append(describe_wounds(damage_type))
            actor.stats.modify_core_current_value(StatsEnum.Health, -damage)

    damage_string += ",".join(wound_strings)
    damage_string += " {} {} for {} damage!".format(
        echo.his_her_it(actor), attack_result.body_part_hit.name, attack_result.total_damage)
    echo.EchoService.singleton.console.printStr(damage_string + "\n")

    # TODO THIS MUST BE EXTRACTED
    # check for death. if there's a death function, call it
    if actor.stats.get_current_value(StatsEnum.Health) <= 0:
        if actor.is_player:
            player_death(actor, echo.EchoService.singleton.console)
        else:

# Path: combat/enums.py
# class TargetType(Enum):
# class DamageType(Enum):
# class ThreatLevel(Enum):
# 
# Path: combat/attack.py
# class MeleeAttackTemplate(AttackTemplate):
#     def __init__(self, name, description, message, required_item_melee_damage_type,
#                  target_type=enums.TargetType.Single, attack_range=0, modifiers=None, hit_stat_used=StatsEnum.Strength,
#                  damage_stat_used=StatsEnum.Strength, requirements=None):
# 
#         super().__init__(name=name, description=description, message=message, target_type=target_type,
#                          attack_range=attack_range, modifiers=modifiers, hit_stat_used=hit_stat_used,
#                          damage_stat_used=damage_stat_used, damage_type=None, requirements=requirements)
# 
#         self.required_item_melee_damage_type = required_item_melee_damage_type
# 
#     def make_attack(self, attacker, defender, **kwargs):
#         attacker_weapon = self.get_used_weapon(attacker)
#         return super().make_attack(attacker, defender, attacker_weapon=attacker_weapon)
# 
#     def get_hit_bonus(self, attacker, **kwargs):
#         # TODO Weapon could have bonuses to hit
#         return super().get_hit_bonus(attacker, **kwargs)
# 
#     def get_damage_bonus(self, attacker, **kwargs):
#         # TODO Weapon could have bonuses to damage
#         return super().get_damage_bonus(attacker, **kwargs)
# 
#     def get_damage_dice(self, **kwargs):
#         attacker_weapon = kwargs.get("attacker_weapon")
#         return attacker_weapon.weapon.damage_dice
# 
#     def get_used_weapon(self, attacker):
#         for wielded_item in attacker.equipment.get_wielded_items():
#             weapon = wielded_item.get_component('weapon')
#             if weapon.melee_damage_type == self.required_item_melee_damage_type:
#                 return wielded_item
# 
#     def get_damage_type(self, **kwargs):
#         item = kwargs.get("attacker_weapon")
#         if item.weapon:
#             return item.weapon.melee_damage_type
#         else:
#             # TODO This indicates an improvised weapon. We'll need to get a better way to handle this.
#             return DamageType.Blunt
# 
# Path: stats/enums.py
# class StatsEnum(Enum):
#     Health = 'health'
#     Mana = 'mana'
#     Strength = 'strength'
#     Dexterity = 'dexterity'
#     Constitution = 'constitution'
#     Intelligence = 'intelligence'
#     Charisma = 'charisma'
#     Wisdom = 'wisdom'
#     Sharpness = 'sharpness'
#     Hardness = 'hardness'
#     Weight = 'weight'
#     Size = 'size'
#     Potency = 'potency'
#     MaxDamage = 'max_damage'
#     MinDamage = 'min_damage'
#     ArmorClass = 'armor_class'
# 
# Path: managers/echo.py
# class EchoService(object):
# class MessageVariables(Enum):
#     def __init__(self, console, game_context):
#     def combat_context_echo(self, message, attacker=None, defender=None,
#                             attacker_weapon=None, defender_weapon=None, defender_bodypart=None):
# def his_her_it(target, **kwargs):
# def him_her_it(target, **kwargs):
# def he_her_it(target, **kwargs):
# def name_or_you(target, **kwargs):
# 
# Path: util/colors.py
# class Colors:
#     BLACK_COLOR = (0, 0, 0)
#     WHITE_COLOR = (255, 255, 255)
#     DARK_BLUE = (0, 0, 100)
#     DARK_GRAY = (75, 75, 75)
#     TROLL_GREEN = (100, 180, 150)
#     ORC_GREEN = (150, 250, 230)
#     BLOOD_RED = (255, 50, 50)


# Path: managers/combat_manager.py
import random
from combat import enums as combat_enums
from combat.attack import MeleeAttackTemplate
from stats.enums import StatsEnum
from managers import echo
from util.colors import Colors

        take_damage(defender, attack_result)
    else:
        choose_defense(attacker, defender, attack_result.total_hit_roll).make_defense(attacker, defender)
    echo.EchoService.singleton.console.printStr(str(attack_result) + "\n")


def take_damage(actor, attack_result):
    # TODO Here we take each damage dealt, apply resistance
    # TODO Determine threat level for total damage
    if attack_result.total_damage <= 0:
        return
    damage_string = "... "
    wound_strings = []

    for damage, damage_type in attack_result.separated_damage:
        if damage > 0:
            wound_strings.append(describe_wounds(damage_type))
            actor.stats.modify_core_current_value(StatsEnum.Health, -damage)

    damage_string += ",".join(wound_strings)
    damage_string += " {} {} for {} damage!".format(
        echo.his_her_it(actor), attack_result.body_part_hit.name, attack_result.total_damage)
    echo.EchoService.singleton.console.printStr(damage_string + "\n")

    # TODO THIS MUST BE EXTRACTED
    # check for death. if there's a death function, call it
    if actor.stats.get_current_value(StatsEnum.Health) <= 0:
        if actor.is_player:
            player_death(actor, echo.EchoService.singleton.console)
        else:

            monster_death(actor, echo.EchoService.singleton.console)