def remove_staff(img, staff_candidates, T_length):
    staff_removed = img.copy()
    for c in range(len(staff_candidates)):
        cand = staff_candidates[c]
        for row, col in cand[1]:
            mids = []
            j = max(row - int(T_length * 1.5), 0)
            while(j < height(staff_removed) - 1 and j <= row + T_length):
                while staff_removed[j][col] == 255:
                    j+=1
                while(j < height(staff_removed) - 1 and j <= row + int(T_length * 1.5) and staff_removed[j][col] == 0):
                    j += 1
                if (staff_removed[j][col] == 255):
                    start = j
                    while(j < height(staff_removed) - 1 and j <= row + int(T_length * 1.5) and staff_removed[j][col] == 255):
                        j += 1
                    if (j - start <= T_length):
                        middle = start + ((j - start) // 2) + 1
                        if (np.abs(row - middle) < 10):
                            mids.append(middle)
                        for x in range(start, j):
                            staff_removed[x][col] = 0
            if len(mids) > 0 and col > 5:
                avg = int(np.round(sum([staff_candidates[c][1][col - i][0] for i in range(5)]) / 5.0))


                dists = [np.abs(row - m) for m in mids]
                staff_candidates[c][1][col] = ((mids[np.argmin(dists)] + avg) // 2, col)
            elif col > 20:
                avg = int(np.round(sum([staff_candidates[c][1][col - i][0] for i in range(20)]) / 20.0))
                staff_candidates[c][1][col] = (avg, col)

    return staff_removed, staff_candidates
def calc_slopes(img, chunks, lines):
    chunk_size = height(img) // chunks
    slopes = [[0 for _ in range(width(img))] for c in range(chunks)]
    for i in range(width(img)):
        s = [0 for _ in range(chunks)]
        num = [0 for _ in range(chunks)]
        for line in lines:
            x1,y1,x2,y2 = line[0]
            if (x1 <= i and x2 >= i) or (x1 <= i and x2 >= i):
                for chunk in range(chunks):
                    c1 = y1 // chunk_size
                    c2 = y2 // chunk_size
                    if (c1 >= chunk and c2 <= chunk) or (c2 >= chunk and c1 <= chunk):
                        s[chunk] += float(y2 - y1) / float(x2 - x1)
                        num[chunk] += 1

        for j in range(chunks):
            if num[j] > 0:
                slopes[j][i] = float(s[j]) / float(num[j])


    img_blank = img.copy()
    k = 0
    for s in slopes:
        row = int(np.round((height(img_blank) // len(slopes)) * (k + .5)))
        k += 1
        line = calc_staff_line(s, row, img)
        for pt in line:
            img_blank[pt[0]][pt[1]] = 255

    return slopes, img_blank
def create_initial_staff_image(img, T_length):
    img_copy = img.copy()
    for col in range(width(img_copy)):
        i = 0
        while(i < height(img_copy)):
            while(i < height(img_copy) and img_copy[i][col] == 0):
                i+=1
            mark = i
            while(i < height(img_copy) and img_copy[i][col] == 255):
                i+=1
            if (i - mark > T_length):
                for j in range(mark, i):
                    img_copy[j][col] = 0

    return img_copy
def find_staff_candidates(img, slopes, T_staff_cand, T_length, num_chunks, staff_height, staff_space, min_y, max_y):
    staff_candidates = []
    chunk_size = height(img) // num_chunks

    rows = [i for i in range(min_y - 50, max_y + 50)]

    for row in rows:
        pts, total_white = calc_staff_line_chunks(slopes, row, img, chunk_size)
        if total_white > 0:
            if (float(total_white) / width(img) > T_staff_cand):
                if (len(staff_candidates) == 0
                or (len(staff_candidates) > 0 and row - staff_candidates[-1][0] > T_length)):
                    staff_candidates.append((row, pts, total_white))
                if (len(staff_candidates) > 0 and row - staff_candidates[-1][0] <= T_length and total_white > staff_candidates[-1][2]):
                    staff_candidates[len(staff_candidates) - 1] = (row, pts, total_white)

    to_remove = []
    T_staff = (5 * staff_height) + (7 * staff_space)
    curr = []
    for cand in staff_candidates:
        curr.append(cand)
        if (curr[-1][0] - curr[0][0] > T_staff):
            curr = curr[:len(curr) - 1]
            while (len(curr) > 5):
                tr = [x for x in curr if x[2] == min([c[2] for c in curr])][0]
                to_remove.append(tr)
                curr = [x for x in curr if x != tr]

            curr = []

    for r in to_remove:
        staff_candidates.remove(r)

    print([str(x[0]) + " " + str(x[2]) for x in staff_candidates])
    return staff_candidates
def calc_staff_line(slopes, row, img):
    col = 0
    r = row
    line = []
    for slope in slopes:
        if (int(np.round(r)) < height(img) and col < width(img)):
            line.append((int(np.round(r)), col))
        r += slope
        col += 1
    return line
def calc_staff_line_chunks(slopes, row, img, chunk_size, interval = 15):
    white_seen = 0
    col = 0
    r = row
    line = []
    for col in range(0, width(img), interval):
        if (int(np.round(r)) < height(img) and col < width(img)):
            for i in range(interval):
                line.append((int(np.round(r)), col + i))
            if(img[int(np.round(r))][col] == 255):
                white_seen += 1
        if (int(r // chunk_size) < len(slopes) and int(r // chunk_size) >= 0):
            r += slopes[int(r // chunk_size)][col] * float(interval)
        col += 1
    return line, white_seen*interval