# -*- coding: utf-8 -*-

import os
from mob import *

class GenError(Exception):
    pass

class Generator:

    def __init__(self, l, type = "enemies", floor = "Other"):
        self.type = type
        self.floor = floor
        self.floor_ = floor.replace(' ', '_').lower()
        self.mobs = []
        self.add(l)

    def add(self, l):
        if isinstance(l, list):
            for i,mob in enumerate(l):
                if isinstance(mob, Entity):
                    self.mobs.append(mob)
                else:
                    raise GenError('mob {0} must be a list of Entity'.format(i))
        else:
            if isinstance(mob, Enemy):
                self.mobs.append(l)
            else:
                raise GenError('mob {0} must be a list of Entity'.format(i))

    def make(self):
        f = '../{}_py/functions'.format(self.type)
        p = '../{}_py/predicates/death_trigger/type'.format(self.type)
        for path in [f, p]:
            if not os.path.exists(path):
                os.makedirs(path)
                print("Directory ", path , " Created ")

        for mob in self.mobs:
            self.spawn(mob)
            self.death_trigger(mob)

        self.book_root()
        self.book_floor_root()
        self.book_type_root()
        self.book_register_mob()

        p = open('../{0}_py/predicates/death_trigger/is_trigger.json'.format(self.type), 'w')
        p.write(
"""
{
	"condition": "minecraft:entity_properties",
	"entity": "this",
	"predicate": {
		"nbt": "{Item:{tag:{Tags:['death_trigger']}}}"
	}
}""")
        p.close()

# -------- Book ------
    def spawn(self, mob):
        f = open('../{0}_py/functions/{1}.mcfunction'.format(self.type, mob.name_), 'w')
        f.write('execute if score summon_cursed EB_generic matches -1 run function 0_enemy_boss:is_summon_cursed\n\n')
        f.write('execute if score summon_cursed EB_generic matches 0 run summon {0} ~ ~ ~ {1}\n\n'.format(mob.mob, mob.nbt()))
        f.write('execute if score summon_cursed EB_generic matches 1 run summon {0} ~ ~ ~ {1}\n\n'.format(mob.mob, mob.nbt(True)))

        for command in mob.commands:
            f.write(command+'\n')
        if "custom_sound" in mob.tags:
            f.write("\nexecute as @e[tag={},tag=init,sort=nearest,limit=1] run function 0_enemy_boss:sound_cooldown/spawn\n".format(mob.name_))
        f.write("\nexecute if score boss_spawn EB_generic matches 1 run tag @e[tag={},tag=init,sort=nearest,limit=1] add boss_spawn\n".format(mob.name_))
        f.write("\ntag @e[tag={},tag=init,sort=nearest,limit=1] remove init\n".format(mob.name_))
        f.write("\nscoreboard players set summon_cursed EB_generic -1".format(mob.name_))
        f.write("\nscoreboard players set boss_spawn EB_generic 0\n".format(mob.name_))
        if mob.type == 'boss':
            f.write("\nexecute if score spawn_count EB_generic matches 1 run scoreboard players add #bosses_spawned EB_generic 1".format(mob.name_))
        else:
            f.write("\nexecute if score spawn_count EB_generic matches 1 run scoreboard players add #enemies_spawned EB_generic 1".format(mob.name_))
        f.write("\nscoreboard players set spawn_count EB_generic 1".format(mob.name_))

        f.close()

    def book_register_mob(self):
        for i,mob in enumerate(self.mobs):
            parent_path = 'book_py:{}/{}/{}_{}'.format(self.floor_, self.type, i-1, self.mobs[i-1].name_)
            if i == 0:
                parent_path = 'book_py:{}/{}/root'.format(self.floor_, self.type)
            fpath = 'book_py:{}/{}'.format(self.type, mob.name_)

            description = '''
        [
            {{"translate":"stats","color":"gray"}},{{"text":":\\n"}},
            {{"text":"  \\u2022 {} ","color":"dark_gray"}},{{"text":"\\uf810","color":"white","italic":false}},{{"text":"\\n"}},
            {{"text":"  \\u2022 {} ","color":"dark_gray"}},{{"text":"\\uf811","color":"white","italic":false}},{{"text":"\\n"}},
            {{"text":"  \\u2022 {} ","color":"dark_gray"}},{{"text":"\\uf813","color":"white","italic":false}},{{"text":"\\n"}},
            {{"text":"  \\u2022 {} ","color":"dark_gray"}},{{"text":"\\uf816","color":"white","italic":false}}
        ]'''.format(mob.hp, mob.attack_damage, mob.movement_speed, mob.knockback_resistance if mob.knockback_resistance != None else "0")

            data = '''
{{
    "display": {{
        "title": {0}                ,
        "description": {1},
        "icon": {{
            "item": "minecraft:{2}",
            "nbt":"{{{3}}}"
        }},
        "frame": "task",
        "show_toast": true,
        "announce_to_chat": false,
        "hidden": true
    }},
    "criteria": {{
        "{4}": {{
            "trigger": "minecraft:player_killed_entity",
            "conditions": {{
                "entity":{{
                    "nbt": "{{Tags:[\\"{4}\\"]}}"
                }}
            }}
        }}
    }},
    "rewards": {{
       "function": "{5}"
    }},
    "parent": "{6}"
}}
'''.format(JLine([mob.name]).json('advancement'), description, mob.icon["item"], mob.icon["nbt"], mob.name_, fpath, parent_path)

            f = open('../book_py/advancements/{}/{}/{}_{}.json'.format(self.floor_, self.type, i, mob.name_),'w')
            f.write(data)
            f.close()

            f = open('../book_py/functions/{}/{}.mcfunction'.format(self.type, mob.name_),'w')
            f.write("advancement grant @a only book_py:{}/{}/root {}".format(self.floor_, self.type, mob.name_))
            f.close()

    def book_type_root(self):
        criteria = ''
        for i,mob in enumerate(self.mobs):
            criteria += '\n\t\t\t"{0}":{{"trigger": "minecraft:impossible"}}'.format(mob.name_)
            if i+1 < len(self.mobs):
                criteria += ','

        color = "dark_red" if self.type != "enemies" else "red"
        icon = "skeleton_skull" if self.type == "enemies" else "wither_skeleton_skull"
        data = '''
{{
    "display": {{
        "title": {{"translate": "{}", "color": "{}"}},
        "description": {{"text": ""}},
        "icon": {{
            "item": "minecraft:{}"
        }},
        "frame": "goal",
        "show_toast": true,
        "announce_to_chat": false,
        "hidden": false
    }},
    "criteria": {{ {}
    }},
    "parent": "book_py:{}/root"
}}
'''.format(self.type, color, icon, criteria, self.floor_)
        f = open("../book_py/advancements/{0}/{1}/root.json".format(self.floor_, self.type),'w')
        f.write(data)
        f.close()

    def book_floor_root(self):
        model = {"tutorial":6100,"others":6101,"community_builders":6102,"floor_1":6103,"floor_2":6104,"floor_3":6105}
        if 'floor' in self.floor_:
            title = '[{{"translate": "floor", "color": "gold"}}, {{"text": " {0}", "color": "gold"}}]'.format(self.floor_.split('_')[-1])
        else:
            title = '[{{"translate": "{0}", "color": "gold"}}]'.format(self.floor_)
        data = '''
{{
    "display": {{
        "title": {0},
        "description": {{"text": ""}},
        "icon": {{
            "item": "minecraft:slime_ball",
            "nbt":"{{CustomModelData:{1}}}"
        }},
        "frame": "goal",
        "show_toast": false,
        "announce_to_chat": false,
        "hidden": false
    }},
    "criteria": {{
        "null": {{"trigger": "minecraft:tick"}}
    }},
    "parent": "book_py:root"
}}
'''.format(title, model[self.floor_])
        f = open('../book_py/advancements/{}/root.json'.format(self.floor_),'w')
        f.write(data)
        f.close()

    def book_root(self):
        p = '../book_py/advancements/{}/{}'.format(self.floor_, self.type)
        if not os.path.exists(p):
            os.makedirs(p)
            print("Directory ", p , " Created ")
        p = '../book_py/functions/{}'.format(self.type)
        if not os.path.exists(p):
            os.makedirs(p)
            print("Directory ", p , " Created ")

        data = '''
{
    "display": {
        "title": {"translate": "mobs", "color": "gold"},
        "description": {"text": ""},
        "icon": {"item": "minecraft:zombie_head"},
        "frame": "challenge",
        "show_toast": false,
        "announce_to_chat": false,
        "hidden": false,
        "background": "minecraft:textures/block/nether_wart_block.png"
    },
    "criteria": {
        "null": {"trigger": "minecraft:tick"}
    }
}
'''
        f = open('../book_py/advancements/root.json','w')
        f.write(data)
        f.close()

    def death_trigger(self, mob):
        p = open('../{0}_py/predicates/death_trigger/type/{1}.json'.format(self.type, mob.name_), 'w')
        p.write(
"""
{
	"condition": "minecraft:entity_properties",
	"entity": "this",
	"predicate": {
		"nbt": "{Item:{tag:{Tags:['NAME']}}}"
	}
}""".replace('NAME', mob.name_))
