# (define (problem items)
#    (:domain simple)
#
#    (:objects agent - agent
# 			 door1 - door
# 			 door2 - door
# 			 door3 - door
# 			 door4 - otherDoor
# 			 inventory - inventory
# 			 gold - gold
# 			 redstone -redstone
# 			 chest - chest
# 			 pickaxe - pickaxe
#    )
#
#    (:init (symbol_1 inventory)
#           (symbol_2 gold)
#           (symbol_3 redstone)
#           (symbol_4 chest)
#           (symbol_5 pickaxe)
#           (symbol_6 door4)
#           (symbol_7 door1)
#           (symbol_7 door2)
#           (symbol_7 door3)
#           (symbol_10 agent)
#           (notfailed)
#     )
#    (:goal (symbol_46 chest) )
# )


class ProblemDefinition:
    def __init__(self, problem_name, domain_name):
        self.name = problem_name
        self.domain = domain_name
        self.objects = dict()
        self.types = set()
        self.start_predicates = dict()
        self.start_propositions = list()
        self.goal_predicates = dict()
        self.goal_propositions = list()

    def add_object(self, id: int, object: str, type: str):
        self.objects[id] = (object, type)
        self.types.add(type)

    def add_start_predicate(self, predicate, object_id=None):
        if object_id is None:
            self.start_propositions.append(predicate)
        else:
            self.start_predicates[object_id] = predicate

    def add_goal_predicate(self, predicate, object_id=None):
        if object_id is None:
            self.goal_propositions.append(predicate)
        else:
            self.goal_predicates[object_id] = predicate

    def __str__(self):

        objects = ''
        init = ''
        goal = ''
        description = ' (define (problem {})\n' \
                      '\t(:domain {})\n\n' \
                      '\t(:objects {}' \
                      '\t)\n\n' \
                      '\t(:init {}' \
                      '\t)\n\n' \
                      '(:goal {} )\n' \
                      ' )'.format(self.name, self.domain, objects, init, goal)
        return description
