import math


def _get_xy_index(files,dims,layout):
    """ Get the x and y indices from a list of filename dictionaries

    The FilePattern iterate function returns a list of dictionaries containing
    a filename and variable values parsed from a filename. This function uses
    that list of dictionaries and assigns them to a position in a grid. If dims
    contains two characters, then the images are assigned an x-position based on
    the first character and a y-position based on the second character. If dims
    contains a single character, then this function assigns positions to images
    so that they would fit into the smallest square possible.

    The grid positions are stored in the file dictionaries based on the position
    of the dims position in layout. The layout variable indicates all variables
    at every grid layer, starting from the smallest and ending with the largest
    grid. Using the notation from DeepZooms folder structure, the highest
    resolution values are stored with the largest index. So, if dims is the
    first element in the layout list and layout has 3 items in the list, then
    the grid positions will be stored in the file dictionary as '2_gridX' and
    '2_gridY'.

    Inputs:
        files - a list of dictionaries containing file information
        dims - the dimensions by which the grid will be organized
        layout - a list indicating the grid layout
    Outputs:
        grid_dims - Dimensions of the grid
    """

    grid_dims = []

    if len(dims)==2:
        # get row and column vals
        cols = [f[dims[0]] for f in files]
        rows = [f[dims[1]] for f in files]

        # Get the grid dims
        col_min = min(cols)
        row_min = min(rows)
        col_max = max(cols)
        row_max = max(rows)
        grid_dims.append(col_max - col_min + 1)
        grid_dims.append(row_max - row_min + 1)

        # convert to 0 based grid indexing, store in dictionary
        index = len(layout)-1
        for l in layout[:-1]:
            if dims[0] in l or dims[1] in l:
                break
            index -= 1
        for f in files:
            f[str(index) + '_gridX'] = f[dims[0]]-col_min
            f[str(index) + '_gridY'] = f[dims[1]]-row_min
    else:
        # determine number of rows and columns
        pos = [f[dims[0]] for f in files]
        pos = list(set(pos))
        pos_min = min(pos)
        col_max = int(math.ceil(math.sqrt(len(pos))))
        row_max = int(round(math.sqrt(len(pos))))
        grid_dims.append(col_max)
        grid_dims.append(row_max)

        # Store grid positions in the dictionary
        index = len(layout)-1
        for l in layout[:-1]:
            if l==dims:
                break
            index -= 1
        for f in files:
            f[str(index) + '_gridX'] = int((f[dims[0]]-pos_min) % col_max)
            f[str(index) + '_gridY'] = int((f[dims[0]]-pos_min)//col_max)

    return grid_dims