import random, datetime, itertools

def GenerateMap():
    #generate random empty map
    width = random.randint(5,15) #up to 15
    height = random.randint(5,10) #up to 10
    grid = []

    row = []
    for i in range(width):
        row.append('E')
    for i in range(height):
        grid.append(row.copy())

    #define number of roads for each axis
    x_roads_count = random.randint(2, max(width//3,2))
    y_roads_count = random.randint(2, max(height//3,2))

    #select coords of roads for x
    x_roads_coordinates = [] #output coords
    possible_coordiantes = [i for i in range(width)] #coords to choose from

    for i in range(x_roads_count):
        coordinate = random.choice(possible_coordiantes)
        road_area = [coordinate-1, coordinate, coordinate+1]
        possible_coordiantes = [i for i in possible_coordiantes if i not in road_area] #removes road and surrounding coords (total 3 coords) from possible coords
        x_roads_coordinates.append(coordinate)

    #select coords of roads for y
    y_roads_coordinates = [] #output coords
    possible_coordiantes = [i for i in range(height)] #coords to choose from

    for i in range(y_roads_count):
        coordinate = random.choice(possible_coordiantes)
        road_area = [coordinate-1, coordinate, coordinate+1]
        possible_coordiantes = [i for i in possible_coordiantes if i not in road_area] #removes road and surrounding coords (total 3 coords) from possible coords
        y_roads_coordinates.append(coordinate)

    #create list of road coordinates
    roads = []
    for x in x_roads_coordinates:
        for y in range(height):
            roads.append([x,y])

    for y in y_roads_coordinates:
        for x in range(width):
            roads.append([x,y])

    """AH SHIT HERE WE GO AGAIN"""
    #create list of path coords that can become new intersections by removing intersections and 8 adjacent tiles from roads
    intersections_area = []
    for x in x_roads_coordinates:
        for y in y_roads_coordinates:
            intersection_area = []
            for i in range (-1,2,1):
                for j in range (-1,2,1):
                    intersection_area.append([x+i,y+j])
            intersections_area.extend(intersection_area)

    possible_roads_to_modify = [i for i in roads if i not in intersections_area]
    roads_to_modify = []
    for i in range(1,len(possible_roads_to_modify)//3):   
        choice = random.choice(possible_roads_to_modify)
        possible_roads_to_modify.remove(choice)
        roads_to_modify.append(choice)

    """CREATION TIME"""
    #perform modification based on road
    for r in roads_to_modify:
        #select possible directions for modification
        x, y = r
        direction = random.choice([1,-1])
        if([x+1, y] in roads or [x-1, y] in roads):
            #modify y, as there is road on x coordinates
            route = []
            current_tile = [x,y+direction]
            while(True):
                if(current_tile[1]<0 or current_tile[1]>=height or current_tile in roads):
                    break
                else:
                    route.append(current_tile)
                    current_tile = [current_tile[0],current_tile[1]+direction]
        else:
            #modify x, as there is road on y coordinates
            route = []
            current_tile = [x+direction,y]
            while(True):
                if(current_tile[0]<0 or current_tile[0]>=width or current_tile in roads):
                    break
                else:
                    route.append(current_tile)
                    current_tile = [current_tile[0]+direction,current_tile[1]]
        
        #choose if the route should be complete or not
        if(len(route)>1):
            if(random.randint(1,100)<=65): #40% chance for route not to be full length
                #route.reverse()
                route_len = random.randint(1,len(route)-1)
                route = route[0:route_len]

        #add new route to roads
        roads.extend(route)

    #insert roads into the grid
    for coord in roads:
        grid[coord[1]][coord[0]] = "R"

    """OBJECTS BE HERE"""
    #Select area that possibly could hold objects
    objects_area = []
    for r in roads:
        objects_area.extend(([r[0]+1,r[1]],[r[0]-1,r[1]],[r[0],r[1]+1],[r[0],r[1]-1]))
    objects_area = [c for c in objects_area if c not in roads] #remove coords that contain roads
    objects_area.sort()
    objects_area = [objects_area[i] for i in range(len(objects_area)) if i == 0 or objects_area[i] != objects_area[i-1]] #remove duplicates
    
    houses_area = [i.copy() for i in objects_area]
    for o in objects_area:
        if(o[0] < 0 or o[1] < 0 or o[0] >= width or o[1] >= height):
            houses_area.remove(o) #remove coords outside borders

    #place dumps
    dumps_to_place = ["B","Y","G"]
    while(len(dumps_to_place) > 0):
        dump_coords = random.choice(houses_area)
        houses_area.remove(dump_coords)
        grid[dump_coords[1]][dump_coords[0]] = dumps_to_place[0]
        dumps_to_place.remove(dumps_to_place[0])


    #leave random coordinates
    houses_to_leave_count = len(houses_area)//4
    while(len(houses_area) > houses_to_leave_count):
        houses_area.remove(random.choice(houses_area))
    
    #insert houses into the grid
    for coord in houses_area:
        grid[coord[1]][coord[0]] = "H"

    #Select position for GC
    GC_position = random.choice(roads)

    #Save map to file
    name = "./Resources/Maps/map"+str(datetime.datetime.now().strftime("%Y%m%d%H%M%S%f"))+"_auto.txt"
    map_file = open(name, "w+")
    map_file.write(str(width)+" "+str(height)+"\n")
    map_file.write(str(GC_position[0])+" "+str(GC_position[1])+"\n")
    for row in grid:
        map_file.write(" ".join(row)+"\n")
    map_file.close()
    #print(name)

    return(name)