# Path: abilities/physical_abilities.py
# class PhysicalAbilities(Enum):
#     GRASP = 0
#     STAND = 1
#     SEE = 2
#     HEAR = 3
#     BITE = 4
#     PUNCH = 5
#     KICK = 6
#     EAT = 7
#     THINK = 8
#     MOVE = 9
#     LIVE = 10
#     BREATHE = 11
# 
# Path: combat/attack.py
# class UnarmedAttackTemplate(AttackTemplate):
#     # TODO I admit, this looks ugly.
#     def __init__(self, name, description, message, basic_damage_dice=DiceStack(1, Dice(3)), bodypart_id_needed="humanoid_hand",
#                  target_type=enums.TargetType.Single, attack_range=0, modifiers=None, hit_stat_used=StatsEnum.Strength,
#                  damage_stat_used=StatsEnum.Strength, damage_type=enums.DamageType.Blunt, 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=damage_type, requirements=requirements)
# 
#         self.basic_damage_dice = basic_damage_dice
#         self.bodypart_id_needed = bodypart_id_needed
# 
#     def get_damage_dice(self, *args, **kwargs):
#         if 'attacker' in kwargs:
#             return DiceStack(1, Dice(kwargs['attacker'].stats.size - 1))
#         return self.basic_damage_dice
# 
#     def get_damage_bonus(self, attacker, **kwargs):
#         return (self.modifiers.get('damage_modifier', 0) +
#                 attacker.get_stat_modifier(self.damage_stat_used))
# 
# 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: combat/enums.py
# class DamageType(Enum):
#     Blunt = 0
#     Slash = 1
#     Pierce = 2
# 
# Path: util/requirements.py
# class CompareType(Enum):
# class RequirementType(Enum):
# class Requirement(object):
# class StatRequirement(Requirement):
# class PhysicalAbilityRequirement(Requirement):
# class ItemDamageTypeRequirement(Requirement):
#     def __init__(self, requirement_type, compare_type, key, value):
#     def evaluate(self, game_object):
#     def compare(compare_type, value, other_value):
#     def __init__(self, compare_type, value, stat):
#     def evaluate(self, game_object):
#     def __init__(self, compare_type, value, ability_enum):
#     def evaluate(self, game_object):
#     def __init__(self, compare_type, damage_type_enum):
#     def evaluate(self, game_object):


from abilities.physical_abilities import PhysicalAbilities
from combat.attack import UnarmedAttackTemplate, MeleeAttackTemplate
from combat.enums import DamageType
from util import requirements


# TODO The melee damage type is repeated.. change that. (Variable AND in requirement)
# TODO Also use the requirements to fetch... requirements... like required bodypart. (Requirement!!)


punch_template = UnarmedAttackTemplate(
    name="Punch",
    description="The mighty fist is presented to the weak flesh.",
    message="{attacker} throws {attacker_his} fist at {defender}",
    requirements=[
        requirements.PhysicalAbilityRequirement(requirements.CompareType.GreaterOrEqual, 1, PhysicalAbilities.PUNCH)]
)
slash_template = MeleeAttackTemplate(
    name="Slash",
    description="The sharpened blade parts the flesh.",
    message="{attacker} slashes {attacker_weapon} at {defender}",
    required_item_melee_damage_type=DamageType.Slash,
    requirements=[requirements.ItemDamageTypeRequirement(requirements.CompareType.Equal, DamageType.Slash)]
)
smash_template = MeleeAttackTemplate(
    name="Smash",
    description="The hardened metal crushes the bone.",
    message="{attacker} smashes {attacker_weapon} at {defender}",
    required_item_melee_damage_type=DamageType.Blunt,

# Path: abilities/physical_abilities.py
# class PhysicalAbilities(Enum):
#     GRASP = 0
#     STAND = 1
#     SEE = 2
#     HEAR = 3
#     BITE = 4
#     PUNCH = 5
#     KICK = 6
#     EAT = 7
#     THINK = 8
#     MOVE = 9
#     LIVE = 10
#     BREATHE = 11
# 
# Path: combat/attack.py
# class UnarmedAttackTemplate(AttackTemplate):
#     # TODO I admit, this looks ugly.
#     def __init__(self, name, description, message, basic_damage_dice=DiceStack(1, Dice(3)), bodypart_id_needed="humanoid_hand",
#                  target_type=enums.TargetType.Single, attack_range=0, modifiers=None, hit_stat_used=StatsEnum.Strength,
#                  damage_stat_used=StatsEnum.Strength, damage_type=enums.DamageType.Blunt, 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=damage_type, requirements=requirements)
# 
#         self.basic_damage_dice = basic_damage_dice
#         self.bodypart_id_needed = bodypart_id_needed
# 
#     def get_damage_dice(self, *args, **kwargs):
#         if 'attacker' in kwargs:
#             return DiceStack(1, Dice(kwargs['attacker'].stats.size - 1))
#         return self.basic_damage_dice
# 
#     def get_damage_bonus(self, attacker, **kwargs):
#         return (self.modifiers.get('damage_modifier', 0) +
#                 attacker.get_stat_modifier(self.damage_stat_used))
# 
# 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: combat/enums.py
# class DamageType(Enum):
#     Blunt = 0
#     Slash = 1
#     Pierce = 2
# 
# Path: util/requirements.py
# class CompareType(Enum):
# class RequirementType(Enum):
# class Requirement(object):
# class StatRequirement(Requirement):
# class PhysicalAbilityRequirement(Requirement):
# class ItemDamageTypeRequirement(Requirement):
#     def __init__(self, requirement_type, compare_type, key, value):
#     def evaluate(self, game_object):
#     def compare(compare_type, value, other_value):
#     def __init__(self, compare_type, value, stat):
#     def evaluate(self, game_object):
#     def __init__(self, compare_type, value, ability_enum):
#     def evaluate(self, game_object):
#     def __init__(self, compare_type, damage_type_enum):
#     def evaluate(self, game_object):


# Path: data/python_templates/attacks.py
from abilities.physical_abilities import PhysicalAbilities
from combat.attack import UnarmedAttackTemplate, MeleeAttackTemplate
from combat.enums import DamageType
from util import requirements



# TODO The melee damage type is repeated.. change that. (Variable AND in requirement)
# TODO Also use the requirements to fetch... requirements... like required bodypart. (Requirement!!)


punch_template = UnarmedAttackTemplate(
    name="Punch",
    description="The mighty fist is presented to the weak flesh.",
    message="{attacker} throws {attacker_his} fist at {defender}",
    requirements=[
        requirements.PhysicalAbilityRequirement(requirements.CompareType.GreaterOrEqual, 1, PhysicalAbilities.PUNCH)]
)
slash_template = MeleeAttackTemplate(
    name="Slash",
    description="The sharpened blade parts the flesh.",
    message="{attacker} slashes {attacker_weapon} at {defender}",
    required_item_melee_damage_type=DamageType.Slash,
    requirements=[requirements.ItemDamageTypeRequirement(requirements.CompareType.Equal, DamageType.Slash)]
)
smash_template = MeleeAttackTemplate(
    name="Smash",
    description="The hardened metal crushes the bone.",
    message="{attacker} smashes {attacker_weapon} at {defender}",
    required_item_melee_damage_type=DamageType.Blunt,

    requirements=[requirements.ItemDamageTypeRequirement(requirements.CompareType.Equal, DamageType.Blunt)]