def extend_tile(p1, p2, currentcase, oldcase, tile):
    # Copy of visualize
    visitedcases = [currentcase % len(tile)]
    tilepoints = list()
    to_visit = [(p1, p2, currentcase, oldcase)]
    while to_visit:
        p1, p2, currentcase, oldcase = to_visit.pop()
        realcurrent = currentcase % len(tile)
        # visitedcases.append(realcurrent) #too late! if two cases go to the same case that doesn't get explored until after
        points = get_face_points(p1, p2, len(tile[realcurrent]))
        if DEBUG1: Draw.polygon_shape(points, (255, 0, 0), alpha=0.1, outline=1)
        if DEBUG4: print("Extend", currentcase)
        if DEBUG4: print(visitedcases)
        if DEBUG1: Draw.text_center(str(realcurrent), *centerpoint(points), (0, 0, 0), 12)
        if DEBUG1: Draw.refresh()
        # sleep(0.01)
        tilepoints.append(points)
        currentborder = tile[realcurrent]  # print(currentborder, 'of shape', realcurrent, ', coming from', oldcase)
        base, match = find_matching(oldcase, currentcase, tile)
        # if(DEBUG1):print(match)
        shift = currentborder.index(match)  # index = current.index(-oldcase + 2 * (oldcase % len(order)))
        # if(DEBUG1):print("Aligned on %d index %d"%(oldcase,shift))
        # print(index)
        currentborder = currentborder[shift:] + currentborder[:shift + 1]
        for index, nextcase in enumerate(currentborder):
            p1 = points[index % len(points)]
            p2 = points[(index + 1) % len(points)]
            if (nextcase not in visitedcases) and (nextcase % len(tile) == nextcase):
                to_visit.append([p2, p1, nextcase, currentcase])
                visitedcases.append(nextcase)
                # if(DEBUG1):print("De %d, index %d next %d"%(realcurrent, index,nextcase))
        if DEBUG1: Draw.wait_for_input()
    return tilepoints
def get_neighbours_positions(tile, p1=P1, p2=P2, startcase=0, recurse=0):
    neighbours_coords = dict()
    if recurse:
        neighbours_neighbours = dict()
        if DEBUG4:
            nn_debug = dict()
    explored = list()
    ####PART 1 : explore and list all neighbouring tiles
    to_explore = [list((p1, p2, startcase))]
    while to_explore:
        initial_p1, initial_p2, case = to_explore.pop()  # the initial shape from which the exploration starts
        if recurse:
            c = centeroftilestarting(initial_p1, initial_p2, tile[case % len(tile)][0], case, tile, 1)
            if DEBUG4:
                print("Center received", c)
                Draw.text_center("_0_", *c, (128, 0, 0), 30)
        initial_points = get_face_points(initial_p1, initial_p2, len(tile[case]))
        if DEBUG1: Draw.polygon_shape(initial_points, (0, 255 * recurse, 0), alpha=.5, outline=1)
        initial_points = initial_points + initial_points
        if DEBUG1: Draw.text_center(str(case), *centerpoint(initial_points), (0, 0, 255), 12)
        if DEBUG1: Draw.refresh()
        explored.append(case)
        if DEBUG1: Draw.wait_for_input()
        for index, next in enumerate(tile[case]):
            branch_p1 = initial_points[index]
            branch_p2 = initial_points[index + 1]
            branch_points = 2 * get_face_points(branch_p2, branch_p1, len(
                tile[next % len(tile)]))  # the direction of the segment has to be reversed
            # branch_points triangle starts at [case] as its origin
            # but next triangle loop considers starts at 0 (forgets previous)
            # rotate the triangle so that the origin side is 0
            if next % len(tile) == next and next != case:
                side_offset = len(tile[next]) - tile[next].index(case)
                next_p1, next_p2 = branch_points[side_offset:side_offset + 2]
                # inside the net (excluding self-ref which are outside)
                if next not in explored:
                    # Branch out inside
                    to_explore.append([next_p1, next_p2, next])
            else:
                # outside the net= neighbour data
                branch_p1 = initial_points[index]
                branch_p2 = initial_points[index + 1]
                # branch_points = 2*get_face_points(branch_p2, branch_p1, len(tile[case])) #the direction of the segment has to be reversed
                # side_offset = len(tile[next%len(tile)])-index#len(tile[next%len(tile)])-find_matching_offset(case,next,tile)
                # next_p1, next_p2 = branch_points[side_offset:side_offset+2]
                if DEBUG1: print("Going outside: %d to %d index %d" % (case, next % len(tile), index))
                neighbour = centeroftilestarting(branch_p2, branch_p1, case, next,
                                                 tile)  # this takes prev tile so no shift
                neighbours_coords.setdefault(neighbour, [])
                neighbours_coords[neighbour].append((case, next))

                if recurse:
                    # current, sym = find_matching(case,next,tile)
                    side_offset = len(tile[next % len(tile)]) - find_matching_offset(case, next, tile)
                    next_p1, next_p2 = branch_points[side_offset:side_offset + 2]
                    nn = get_neighbours_positions(tile, next_p1, next_p2, next % len(tile), recurse=False)
                    for n in nn:
                        nn[n].sort()
                    if DEBUG4:
                        debug_data = (next_p1, next_p2, next % len(tile))
                        if neighbour in neighbours_neighbours:
                            if neighbours_neighbours[neighbour] != nn:
                                print("Not matching when reading neighbour", neighbour,
                                      "'s neighbours from two different sides:\nOriginal:")
                                print(nn_debug[neighbour])
                                pp.pprint(neighbours_neighbours[neighbour])
                                print("New: (coming from %d to %d)" % (case, next))
                                print(debug_data)
                                pp.pprint(nn)
                        nn_debug.setdefault(neighbour, debug_data)
                    neighbours_neighbours.setdefault(neighbour, nn)
            all_tilings = dict()
            dictpart = code[code.index("{"):]
            namepart = code[code.index("'")+1:code.index("]")-1]
            print(namepart)
            shape_name = namepart
            print(dictpart)
            all_tilings[namepart]=eval(dictpart)
            for tilingname, tiling in all_tilings.items():
                net = tiling
                shape = net
                tilename = tilingname
                order = list(tiling.keys())
                drawn = visualise(p1, p2, 0, net[0][0], 2)
                fill_screen(p1, p2, order[0], color=3,refresh=False)
            Draw.refresh()
            Draw.wait_for_input()
    elif len(sys.argv)>1 and sys.argv[1].endswith(".py"):
        with open(sys.argv[1],"r") as codefile:
            code = codefile.read()
            dictpart = code[code.index("{"):]
            namepart = code[code.index("'")+1:code.index("]")-1]
            print(namepart)
            print(dictpart)
        tiling=eval(dictpart)
        import pygame
        pygame.init()
        screen = pygame.display.set_mode((800, 800), pygame.DOUBLEBUF)
        screen.fill((255, 255, 255, 255))
        outlines = pygame.Surface((800, 800), pygame.SRCALPHA)
        area = (0,0,1000,1000)