import numpy as np


def TSE_k_space_fill(n_ex, ETL, k_steps, TE_eff_number, N_center, order, dummy):
    # function defines phase encoding steps for k space filling in liner order
    # with shifting according to the TE effective number

    if dummy:
        k_space_dummy = ['dummy']*ETL
        k_space_dummy = [k_space_dummy]
    k_space_list_with_zero = []
    for i in range(ETL):
        #k_space_list_with_zero.append(int((ETL - 1) * n_ex - i * n_ex))
        k_space_list_with_zero.append(i * n_ex)

    if n_ex > 1:
        k_space_order_filing_temp = [k_space_list_with_zero]
        for i in range(n_ex - 1):
            k_space_list_temp = []
            for k in k_space_list_with_zero:
                k_space_list_temp.append(k + i + 1)
            k_space_order_filing_temp.append(k_space_list_temp)
    else:
        k_space_order_filing_temp = [k_space_list_with_zero]


    kk = 0
    for k_space_list_with_central_old in k_space_order_filing_temp:
        temporal = abs(k_space_list_with_central_old - N_center)
        center_index = np.argmin(temporal)

        central_line_position_old = center_index
        num_left_old = central_line_position_old
        num_right_old = len(k_space_list_with_central_old) - num_left_old - 1

        for i in range(len(k_space_list_with_central_old)):
            if k_space_list_with_central_old[i] > (k_steps - 1):
                k_space_list_with_central_old[i] = 'skip'

        k_space_list_with_central_new = ['skip'] * len(k_space_list_with_central_old)
        central_line_position_new = TE_eff_number - 1
        num_left_new = central_line_position_new
        num_right_new = len(k_space_list_with_central_new) - num_left_new - 1

        if num_left_new < num_right_new:
            min_new = num_left_new
            max_new = num_right_new
        else:
            min_new = num_right_new
            max_new = num_left_new

        k_space_list_with_central_new[central_line_position_new] = k_space_list_with_central_old[
            central_line_position_old]
        k_space_list_with_central_old[central_line_position_old] = 'passed'

        if min_new == 0: # effective time is first one
            i = 0
            k_space_list_with_central_old_abs = [0] * len(k_space_list_with_central_old)
            for ii in range(len(k_space_list_with_central_old)):
                if k_space_list_with_central_old[ii] != 'skip' and k_space_list_with_central_old[ii] != 'passed':
                    k_space_list_with_central_old_abs[ii] = abs(k_space_list_with_central_old[ii] - N_center)
                    #type_of_elements = type(k_space_list_with_central_old_abs[0])
                else:
                    k_space_list_with_central_old_abs[ii] = k_space_list_with_central_old[ii]
                    #type_of_elements = type(k_space_list_with_central_old_abs[0])
            type_of_string = type('passed')

            if num_left_new < num_right_new:
                flag = True
                j = central_line_position_new + i + 1
                while flag:
                    a = min(filter(lambda i: not isinstance(i, type_of_string), k_space_list_with_central_old_abs))
                    min_index = k_space_list_with_central_old_abs.index(a)
                    k_space_list_with_central_new[j] = k_space_list_with_central_old[min_index]
                    k_space_list_with_central_old_abs[min_index] = 'passed'
                    k_space_list_with_central_old[min_index] = 'passed'
                    j += 1
                    flag = any(not isinstance(y, (type_of_string)) for y in k_space_list_with_central_old)
                k_space_order_filing_temp[kk] = k_space_list_with_central_new
                kk += 1
            else:
                flag = True
                j = central_line_position_new - i - 1
                while flag:
                    a = min(filter(lambda i: not isinstance(i, type_of_string), k_space_list_with_central_old_abs))
                    min_index = k_space_list_with_central_old_abs.index(a)
                    k_space_list_with_central_new[j] = k_space_list_with_central_old[min_index]
                    k_space_list_with_central_old_abs[min_index] = 'passed'
                    k_space_list_with_central_old[min_index] = 'passed'
                    j -= 1
                    flag = any(not isinstance(y, (type_of_string)) for y in k_space_list_with_central_old)
                k_space_order_filing_temp[kk] = k_space_list_with_central_new
                kk += 1

        else:
            for i in range(1, min_new + 1):
                k_space_list_with_central_new[central_line_position_new + i] = k_space_list_with_central_old[
                    central_line_position_old + i]
                k_space_list_with_central_old[central_line_position_old + i] = 'passed'
                k_space_list_with_central_new[central_line_position_new - i] = k_space_list_with_central_old[
                    central_line_position_old - i]
                k_space_list_with_central_old[central_line_position_old - i] = 'passed'

            k_space_list_with_central_old_abs = [0] * len(k_space_list_with_central_old)
            for ii in range(len(k_space_list_with_central_old)):
                if k_space_list_with_central_old[ii] != 'skip' and k_space_list_with_central_old[ii] != 'passed':
                    k_space_list_with_central_old_abs[ii] = abs(k_space_list_with_central_old[ii] - N_center)
                    #type_of_elements = type(k_space_list_with_central_old_abs[0])
                else:
                    k_space_list_with_central_old_abs[ii] = k_space_list_with_central_old[ii]
                    #type_of_elements = type(k_space_list_with_central_old_abs[0])
            type_of_string = type('passed')

            if num_left_new < num_right_new:
                flag = True
                j = central_line_position_new + i + 1
                while flag:
                    a = min(filter(lambda i: not isinstance(i, type_of_string), k_space_list_with_central_old_abs))
                    min_index = k_space_list_with_central_old_abs.index(a)
                    k_space_list_with_central_new[j] = k_space_list_with_central_old[min_index]
                    k_space_list_with_central_old_abs[min_index] = 'passed'
                    k_space_list_with_central_old[min_index] = 'passed'
                    j += 1
                    flag = any(not isinstance(y, (type_of_string)) for y in k_space_list_with_central_old)
                k_space_order_filing_temp[kk] = k_space_list_with_central_new
                kk += 1
            else:
                flag = True
                j = central_line_position_new - i - 1
                while flag:
                    a = min(filter(lambda i: not isinstance(i, type_of_string), k_space_list_with_central_old_abs))
                    min_index = k_space_list_with_central_old_abs.index(a)
                    k_space_list_with_central_new[j] = k_space_list_with_central_old[min_index]
                    k_space_list_with_central_old_abs[min_index] = 'passed'
                    k_space_list_with_central_old[min_index] = 'passed'
                    j -= 1
                    flag = any(not isinstance(y, (type_of_string)) for y in k_space_list_with_central_old)
                k_space_order_filing_temp[kk] = k_space_list_with_central_new
                kk += 1
            #k_space_order_filing = k_space_order_filing.append(k_space_list_with_central_new)


    """
        k_space_order_filing = []
        n_ex_shift = np.int64(n_ex/2)-1
        a = range(0-n_ex_shift, n_ex-n_ex_shift)
        for i in a:
            k_space_list_temp = []
            for kk in k_space_list_with_central_new:
                value = kk + i
                if value < 0:
                    value = value + k_steps
                if value > k_steps - 1:
                    value = 'skip'
                k_space_list_temp.append(value)
            k_space_order_filing.append(k_space_list_temp)
    """

    if dummy:
        for list in k_space_order_filing_temp:
            k_space_dummy.append(list)
    else:
        k_space_dummy = k_space_order_filing_temp
    return k_space_dummy


"""
        # find the list where
        i = 1
        for k_space_list_with_central_old in k_space_order_filing_temp:
            if N_center in list:
                k_space_list_with_central_old = list
                num_of_list = i
            else:
                i += 1
    else:
        k_space_list_with_central_old = k_space_list_with_zero

    central_line_position_old = k_space_list_with_central_old.index(N_center)
    num_left_old = central_line_position_old
    num_right_old = len(k_space_list_with_central_old) - num_left_old - 1
"""
"""
    shift = central_line_position_old - central_line_position_new
    if order == 'non_linear':
        a = k_space_list_with_central_old[:((shift-central_line_position_old)*2-1)]
        b = k_space_list_with_central_old[((shift-central_line_position_old)*2-1):]
        for i in range(1, int(len(b)/2)+1):
            a.append(b[i-1])
            a.append(b[-i])
        a.append(b[i])
    k_space_list_with_central_new = a

    """
"""
    for j in range(np.int32(np.ceil((max_new - min_new - 1)/ 2))):
        a = min(filter(lambda i: isinstance(i, type_of_elements), k_space_list_with_central_old))
        min_index = k_space_list_with_central_old.index(a)
        k_space_list_with_central_new[central_line_position_new + (i + j + 1)] = k_space_list_with_central_old[min_index]
        k_space_list_with_central_old[min_index] = 'passed'


    for j in range(np.int32(np.ceil((max_new - min_new - 1)/ 2))):

        k_space_list_with_central_new[central_line_position_new + (i + 2 * j + 1)] = N_center - n_ex * (i + j + 1)
        if N_center + n_ex * (i + j + 1) > max(k_space_list_with_central_old):
            k_space_list_with_central_new[central_line_position_new + (i + 2 * j + 2)] = N_center + n_ex * (i + j + 1) - max(k_space_list_with_central_old) - 1
        else:
            k_space_list_with_central_new[central_line_position_new + (i + 2 * j + 2)] = N_center + n_ex * (
                        i + j + 1)
    k_space_list_with_central_new[central_line_position_new + (i + 2 * (j + 1) + 1)] = N_center - n_ex * (i + (j + 1) + 1)

    k_space_order_filing = k_space_list_with_central_new

    if central_line_position_new < central_line_position_old:
        for j in range(central_line_position_old - i):
            k_space_list_with_central_new[central_line_position_new + i + 2*j + 1] = k_space_list_with_central_old[
                central_line_position_old - i - j - 1]
            k_space_list_with_central_new[central_line_position_new + i + 2*j + 2] = k_space_list_with_central_old[
                central_line_position_old + i + j + 1]
        if (len(k_space_list_with_central_new) % 2) == 0:
            k_space_list_with_central_new[-1] = k_space_list_with_central_old[-1]

    else:
        for j in range(central_line_position_old - i):
            k_space_list_with_central_new[central_line_position_new - i - 2*j - 1] = k_space_list_with_central_old[
                central_line_position_old - i - j - 1]
            k_space_list_with_central_new[central_line_position_new - i - 2*j - 2] = k_space_list_with_central_old[
                central_line_position_old + i + j + 1]
        #if (len(k_space_list_with_central_new) % 2) == 0:
        #    k_space_list_with_central_new[0] = k_space_list_with_central_old[-1]
    """