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

import os
from room import *

class GeneratorError(Exception):
    pass

class Generator:

    def __init__(self, l = []):

        self.middle = {}
        self.boss = {}
        self.armory = {}
        self.spawn = {}
        self.wall = {}
        self.all = {'middle': self.middle, 'boss': self.boss, 'armory': self.armory, 'spawn': self.spawn}
        self.sort(l)

    def add(self, room):
        if not isinstance(room, (Room, Wall)):
            raise GeneratorError("Generator only accepts 'Room' class objects")
        if room.type != 'wall':
            if room.floor in self.all[room.type].keys():
                self.all[room.type][room.floor].append(room)
            else:
                self.all[room.type][room.floor] = [room]
        else:
            if room.wall_type in self.wall.keys():
                self.wall[room.wall_type].append(room)
            else:
                self.wall[room.wall_type] = [room]

    def sort(self, l):
        if isinstance(l, list):
            for i,e in enumerate(l):
                if isinstance(e, list):
                    self.sort(e)
                elif isinstance(e, Room):
                    self.add(e)
                else:
                    raise Generator('Element in l[{0}] is not an Room'.format(i))
        else:
            raise Generator("must be give a list of Rooms,a Room or a list with list of Rooms")

    def make(self):
        for type in self.all:
            path = '../rooms_py/functions/{0}'.format(type)
            if not os.path.exists(path):
                os.makedirs(path)
                print("Directory ", path , " Created ")

            self.floor_sort(type)

            for floor in self.all[type]:
                percentage = 0
                for room in self.all[type][floor]:
                        percentage += room.percentage
                if percentage != 100:
                    raise GeneratorError("The percentage of {0} floor_{1} isn't equal to 100%".format(type, floor))

            self.room_sort(type, floor)

        self.make_walls()

    def make_walls(self):
        path = '../rooms_py/functions/wall'
        if not os.path.exists(path):
            os.makedirs(path)
            print("Directory ", path , " Created ")

        f = open('../rooms_py/functions/wall/floor_sort.mcfunction', 'w')
        f.write('function rng:percentage\n\n')
        for type in self.wall:
            f.write('execute if entity @s[tag={0}] run function rooms_py:wall/{0}\n'.format(type))

            percentage = 0
            for wall in self.wall[type]:
                percentage += wall.percentage
            if percentage != 100:
                raise GeneratorError("The percentage of walls {0} isn't equal to 100%".format(type))

            f2 = open('../rooms_py/functions/wall/{0}.mcfunction'.format(type), 'w')
            min = 0
            walls = self.wall[type]

            for i,wall in enumerate(walls):
                max = min + wall.percentage - 1
                if i+1 == len(walls):
                    max += 1
                f2.write("""
#{4} %
execute if entity @s[tag=N] if score out rng matches {0}..{1} run setblock ~ ~1 ~ structure_block{{mode:"LOAD",name:"rooms:wall/{2}/{3}",posX:1,posY:3,posZ:0,rotation:"CLOCKWISE_90"}} replace
execute if entity @s[tag=S] if score out rng matches {0}..{1} run setblock ~ ~1 ~ structure_block{{mode:"LOAD",name:"rooms:wall/{2}/{3}",posX:1,posY:3,posZ:0,rotation:"CLOCKWISE_90"}} replace
execute if entity @s[tag=E] if score out rng matches {0}..{1} run setblock ~ ~1 ~ structure_block{{mode:"LOAD",name:"rooms:wall/{2}/{3}",posX:0,posY:3,posZ:-1,rotation:"NONE"}} replace
execute if entity @s[tag=W] if score out rng matches {0}..{1} run setblock ~ ~1 ~ structure_block{{mode:"LOAD",name:"rooms:wall/{2}/{3}",posX:0,posY:3,posZ:-1,rotation:"NONE"}} replace\n""".format(min, max, wall.wall_type, wall.id, wall.percentage))
                min += wall.percentage
            f2.close()
        f.write("""
# Activate structure blocks
setblock ~ ~2 ~ air replace
setblock ~ ~2 ~ redstone_block replace

# Remove marker
kill @s

setblock ~ ~ ~ air replace
setblock ~ ~1 ~ air replace
setblock ~ ~2 ~ air replace""")
        f.close()

    def floor_sort(self, type):
        f = open('../rooms_py/functions/{0}/floor_sort.mcfunction'.format(type), 'w')
        for floor in self.all[type]:
            f.write('execute if score floor dungeon matches {0} run function rooms_py:{1}/floor_{0}\n'.format(floor, type))
        f.close()

    def room_sort(self, type, floor):
        f = open('../rooms_py/functions/{0}/floor_{1}.mcfunction'.format(type, floor), 'w')
        min = 0
        rooms = self.all[type][floor]

        for i,room in enumerate(rooms):
            max = min + room.percentage - 1
            if i+1 == len(rooms):
                max += 1

            f.write(
'''#{5} %
execute if score out rng matches {0}..{1} run setblock ~ ~ ~ structure_block{{mode:"LOAD",name:"rooms:{2}/floor_{3}/{4}"}} replace
execute if score out rng matches {0}..{1} run tag @s add {4} \n'''.format(min, max, type, floor, room.id, room.percentage))

            for e in room.tag:
                f.write('execute if score out rng matches {0}..{1} run tag @s add {2}'.format(min, max, e))

            min += room.percentage

        f.close()
