# Path: factories/factory_service.py
# class FactoryService(object):
#     """
#     This allows us to call for something built.
#     This is rudimentary for now but it could be nice to have each factory provide a list of
#     types it handles and dispatch each request to the factory that handles it.
#     """
#     def __init__(self, body_factory, character_factory=None):
#         self.body_factory = body_factory
#         self.character_factory = character_factory
# 
#     def build_body_instance_by_uid(self, body_uid):
#         return self.body_factory.build_body(body_uid)
# 
#     def assemble_body(self, body):
#         return self.body_factory.assemble_body(body)
# 
#     def build_character_instance_by_uid(self, character_uid):
#         if self.character_factory:
#             return self.character_factory.build(character_uid)
# 
# Path: factories/body_factory.py
# class BodyFactory(object):
#     def build_body(self, uid):
#         """
#         Builds a bodies instance from a template using the uid.
#         :param uid: uid of the template to instantiate.
#         :return: Built instance from template.
#         """
# 
#         body_template = body_templates[uid]
#         if body_template:
#             body_instance = self._create_instance_of_template(body_template)
#             self.assemble_body(body_instance)
#             return body_instance
#         else:
#             raise Exception("Could not find template for UID " + uid)
# 
#     def build_bodypart(self, uid):
#         template = body_part_templates[uid]
#         instance = BodyPart(
#             uid=template.uid,
#             physical_abilities=template.physical_abilities,
#             relative_size=template.relative_size,
#             threat_level=template.threat_level
#         )
# 
#         return instance
# 
#     def assemble_body(self, body):
#         for node in body.bodypart_tree.nodes:
#             node.instance = self.build_bodypart(node.body_part_uid)
# 
#     @staticmethod
#     def _create_instance_of_template(body_template):
#         return deepcopy(body_template)
# 
# Path: factories/character_factory.py
# class CharacterFactory(object):
#     """
#     At first this will only instantiate templates but eventually it should be able
#     to pump out variations of a template ex: Adjusted to match player level.
#     """
#     def __init__(self, factory_service):
#         self.template_instance_count = {}
#         self.factory_service = factory_service
# 
#     def build(self, uid):
#         """
#         Builds a characters instance from a template using the uid.
#         :param uid: uid of the template to instantiate.
#         :return: Built instance from template.
#         """
# 
#         character_template = character_templates[uid]
#         if character_template:
#             return self._create_instance_of_template(character_template)
#         else:
#             raise Exception("Could not find template for UID " + uid)
# 
#     def create(self, name, class_uid, race_uid, stats, body_uid):
#         """
#         Creates a new character based on arguments
#         :return:
#         """
#         uid = "player"
#         new_instance = Character(
#             uid=uid,
#             name=name,
#             character_class=self.get_class_template_by_uid(class_uid).copy(),
#             character_race=self.get_race_template_by_uid(race_uid).copy(),
#             stats=stats,
#             display=Display((255, 255, 255), (0, 0, 0), "@"),
#             body=self.factory_service.build_body_instance_by_uid(body_uid),
#             inventory=Inventory()
#         )
#         health_base = new_instance.character_class.hit_die
#         constitution_bonus = new_instance.get_stat_modifier(StatsEnum.Constitution)
#         total_health = health_base + constitution_bonus
#         new_instance.stats.set_core_current_value(StatsEnum.Health, total_health)
#         new_instance.stats.set_core_maximum_value(StatsEnum.Health, total_health)
# 
#         return new_instance
# 
#     def _create_instance_of_template(self, character_template):
#         instance_id = 0
#         if character_template.uid in self.template_instance_count:
#             instance_id = self.template_instance_count[character_template.uid]
#             self.template_instance_count[character_template.uid] += 1
#         else:
#             self.template_instance_count[character_template.uid] = 1
# 
#         instance_uid = character_template.uid + "_" + str(instance_id)
#         new_instance = character_template.copy()
#         new_instance.uid = instance_uid
# 
#         return new_instance
# 
#     def get_class_template_by_uid(self, uid):
#         if uid in character_class_templates:
#             return character_class_templates[uid]
# 
#     def get_race_template_by_uid(self, uid):
#         if uid in race_templates:
#             return race_templates[uid]
# 
# Path: data/python_templates/characters.py



from factories.factory_service import FactoryService
from factories.body_factory import BodyFactory
from factories.character_factory import CharacterFactory
from data.python_templates.characters import weak_orc as weak_orc_template
import unittest


class CharacterFactoryTests(unittest.TestCase):
    def setUp(self):
        self.factory_service = FactoryService(body_factory=BodyFactory())
        self.factory_service.character_factory = CharacterFactory(factory_service=self.factory_service)


# Path: factories/factory_service.py
# class FactoryService(object):
#     """
#     This allows us to call for something built.
#     This is rudimentary for now but it could be nice to have each factory provide a list of
#     types it handles and dispatch each request to the factory that handles it.
#     """
#     def __init__(self, body_factory, character_factory=None):
#         self.body_factory = body_factory
#         self.character_factory = character_factory
# 
#     def build_body_instance_by_uid(self, body_uid):
#         return self.body_factory.build_body(body_uid)
# 
#     def assemble_body(self, body):
#         return self.body_factory.assemble_body(body)
# 
#     def build_character_instance_by_uid(self, character_uid):
#         if self.character_factory:
#             return self.character_factory.build(character_uid)
# 
# Path: factories/body_factory.py
# class BodyFactory(object):
#     def build_body(self, uid):
#         """
#         Builds a bodies instance from a template using the uid.
#         :param uid: uid of the template to instantiate.
#         :return: Built instance from template.
#         """
# 
#         body_template = body_templates[uid]
#         if body_template:
#             body_instance = self._create_instance_of_template(body_template)
#             self.assemble_body(body_instance)
#             return body_instance
#         else:
#             raise Exception("Could not find template for UID " + uid)
# 
#     def build_bodypart(self, uid):
#         template = body_part_templates[uid]
#         instance = BodyPart(
#             uid=template.uid,
#             physical_abilities=template.physical_abilities,
#             relative_size=template.relative_size,
#             threat_level=template.threat_level
#         )
# 
#         return instance
# 
#     def assemble_body(self, body):
#         for node in body.bodypart_tree.nodes:
#             node.instance = self.build_bodypart(node.body_part_uid)
# 
#     @staticmethod
#     def _create_instance_of_template(body_template):
#         return deepcopy(body_template)
# 
# Path: factories/character_factory.py
# class CharacterFactory(object):
#     """
#     At first this will only instantiate templates but eventually it should be able
#     to pump out variations of a template ex: Adjusted to match player level.
#     """
#     def __init__(self, factory_service):
#         self.template_instance_count = {}
#         self.factory_service = factory_service
# 
#     def build(self, uid):
#         """
#         Builds a characters instance from a template using the uid.
#         :param uid: uid of the template to instantiate.
#         :return: Built instance from template.
#         """
# 
#         character_template = character_templates[uid]
#         if character_template:
#             return self._create_instance_of_template(character_template)
#         else:
#             raise Exception("Could not find template for UID " + uid)
# 
#     def create(self, name, class_uid, race_uid, stats, body_uid):
#         """
#         Creates a new character based on arguments
#         :return:
#         """
#         uid = "player"
#         new_instance = Character(
#             uid=uid,
#             name=name,
#             character_class=self.get_class_template_by_uid(class_uid).copy(),
#             character_race=self.get_race_template_by_uid(race_uid).copy(),
#             stats=stats,
#             display=Display((255, 255, 255), (0, 0, 0), "@"),
#             body=self.factory_service.build_body_instance_by_uid(body_uid),
#             inventory=Inventory()
#         )
#         health_base = new_instance.character_class.hit_die
#         constitution_bonus = new_instance.get_stat_modifier(StatsEnum.Constitution)
#         total_health = health_base + constitution_bonus
#         new_instance.stats.set_core_current_value(StatsEnum.Health, total_health)
#         new_instance.stats.set_core_maximum_value(StatsEnum.Health, total_health)
# 
#         return new_instance
# 
#     def _create_instance_of_template(self, character_template):
#         instance_id = 0
#         if character_template.uid in self.template_instance_count:
#             instance_id = self.template_instance_count[character_template.uid]
#             self.template_instance_count[character_template.uid] += 1
#         else:
#             self.template_instance_count[character_template.uid] = 1
# 
#         instance_uid = character_template.uid + "_" + str(instance_id)
#         new_instance = character_template.copy()
#         new_instance.uid = instance_uid
# 
#         return new_instance
# 
#     def get_class_template_by_uid(self, uid):
#         if uid in character_class_templates:
#             return character_class_templates[uid]
# 
#     def get_race_template_by_uid(self, uid):
#         if uid in race_templates:
#             return race_templates[uid]
# 
# Path: data/python_templates/characters.py



# Path: tests/factories/test_character_factory.py
from factories.factory_service import FactoryService
from factories.body_factory import BodyFactory
from factories.character_factory import CharacterFactory
from data.python_templates.characters import weak_orc as weak_orc_template
import unittest



class CharacterFactoryTests(unittest.TestCase):
    def setUp(self):
        self.factory_service = FactoryService(body_factory=BodyFactory())
        self.factory_service.character_factory = CharacterFactory(factory_service=self.factory_service)


    def test_monster_instance(self):