import numpy as np
import random
import math
import time
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
import csv

UAV_R = 20
ROW = 100
COL = 100
UE_TOTAL = 150
UAV_R2 = UAV_R ** 2


def read_csv(addr):
    ue_list = []
    with open(addr, 'r') as f:
        f = csv.reader(f, delimiter=',')
        next(f)
        for row in f:
            ue_list.append(row)
    for i in range(len(ue_list)):
        ue_list[i] = list(map(int, ue_list[i]))
    return ue_list


def cal_los_mat(loc, R, height2, pl_f):
    dist_1 = (loc[0] - R) ** 2 + (loc[1] - R) ** 2
    dist = math.sqrt(dist_1 + height2)
    los = 20 * math.log10(dist / 100) + pl_f
    return los


def Create_Boundary_pattern(R1, height, pl_f):
    height2 = height ** 2
    R_pattern = R1 * 2 + 1
    con_pattern = np.zeros((R_pattern, R_pattern))
    mat_pattern = np.zeros((R_pattern, R_pattern))
    for i in range(R1):
        con_pattern[i, R1] = 1
        con_pattern[R_pattern - i - 1, R1] = 1
        con_pattern[R1, i] = 1
        con_pattern[R1, R_pattern - i - 1] = 1

        los = cal_los_mat([i, R1], R1, height2, pl_f)
        mat_pattern[i, R1] = los
        mat_pattern[R_pattern - i - 1, R1] = los
        mat_pattern[R1, i] = los
        mat_pattern[R1, R_pattern - i - 1] = los
        for j in range(R1):
            if ((i - R1) ** 2 + (j - R1) ** 2) <= R1 ** 2:
                con_pattern[i, j] = 1
                con_pattern[i, R_pattern - j - 1] = 1
                con_pattern[R_pattern - i - 1, j] = 1
                con_pattern[R_pattern - i - 1, R_pattern - j - 1] = 1

                los = cal_los_mat([i, j], R1, height2, pl_f)
                mat_pattern[i, j] = los
                mat_pattern[i, R_pattern - j - 1] = los
                mat_pattern[R_pattern - i - 1, j] = los
                mat_pattern[R_pattern - i - 1, R_pattern - j - 1] = los

    con_pattern[R1, R1] = 1
    mat_pattern[R1, R1] = cal_los_mat([R1, R1], R1, height2, pl_f)
    return con_pattern, mat_pattern


# input:     R1(联通半径)    row_in(全局行数)      col_in(全局列数)
# output:    matlist(生成的矩阵)
def Create_Boundary_list(R1, row_in, col_in, row_x, col_y, patt):
    mat_pattern = patt
    j = row_x
    i = col_y

    mat_main = np.zeros((row_in, col_in))
    if i - R1 < 0:
        col_left = R1 - i
        m_col_left = 0
    else:
        col_left = 0
        m_col_left = i - R1
    if i + R1 >= col_in:
        col_right = R1 + col_in - i
        m_col_right = col_in
    else:
        col_right = 2 * R1 + 1
        m_col_right = i + R1 + 1
    if j - R1 < 0:
        row_up = R1 - j
        m_row_up = 0
    else:
        row_up = 0
        m_row_up = j - R1
    if j + R1 >= row_in:
        row_down = R1 + row_in - j
        m_row_down = row_in
    else:
        row_down = 2 * R1 + 1
        m_row_down = j + R1 + 1

    mat_main[m_row_up:m_row_down, m_col_left:m_col_right] = mat_pattern[row_up:row_down, col_left:col_right]

    return mat_main


def Create_map(ue_list, c_pattern):
    map_mat = np.zeros((ROW, COL))
    for i in range(len(ue_list)):
        map_mat += Create_Boundary_list(UAV_R, ROW, COL, ue_list[i][0], ue_list[i][1], c_pattern)
    return map_mat


def Distance_check(ue_loc, uav_loc, pass_dis):
    dis = (ue_loc[0] - uav_loc[0]) ** 2 + (ue_loc[1] - uav_loc[1]) ** 2
    dis = math.sqrt(dis)
    if dis <= pass_dis:
        return 1
    else:
        return 0


def Solve_process(ue_list, bound_pattern, los_pattern, pass_dis, ue_num_list):
    hot_map = Create_map(ue_list, bound_pattern)
    max_val = np.max(hot_map)
    hot_map[hot_map < max_val] = 0
    hot_map[hot_map > 0] = 1
    ue_num_list.append(max_val)

    los_map = Create_map(ue_list, los_pattern)
    los_map = los_map * hot_map

    min_val = np.min(los_map[np.nonzero(los_map)])
    aim = np.where(los_map == min_val)
    rand_num = random.randint(0, len(aim[0]) - 1)
    aim_loc = [aim[0][rand_num], aim[1][rand_num]]

    for i in range(len(ue_list) - 1, -1, -1):
        if Distance_check(ue_list[i], aim_loc, pass_dis) == 1:
            del ue_list[i]

    return aim_loc


def Draw_result(u_list, solve_list, R1, ue_num_list):
    fig = plt.figure('fig')
    ax = fig.add_subplot(111)  # 111代表1*1的图的第一个子图
    for i in range(len(u_list)):
        plt.plot(u_list[i][0], u_list[i][1], "xy")
    for i in range(len(solve_list)):
        plt.plot(solve_list[i][0], solve_list[i][1], "vr")
        circle = Circle(xy=(solve_list[i][0], solve_list[i][1]), radius=R1, alpha=0.1, color='b')
        ax.add_patch(circle)
        plt.text(solve_list[i][0], solve_list[i][1], str(i + 1) + str('--') + str(int(ue_num_list[i])), fontsize=15)
    title = 'solve-greedy' + '.jpg'
    plt.show()
    #fig.savefig(title)
    fig.clf()

def read_csv(addr):
    ue_list = []
    with open(addr, 'r') as f:
        f = csv.reader(f, delimiter=',')
        next(f)
        for row in f:
            ue_list.append(row)
    for i in range(len(ue_list)):
        ue_list[i] = list(map(int, ue_list[i]))
    return ue_list

def main(origin_ue_loc_list,UAV_R=20):
    addr = r"D:\pycharm\deploy_algorithms\data\list_ue100_1.csv"
    origin_ue_loc_list = read_csv(addr)

    starttime = time.time()
    uav_list = []
    ue_num_list = []
    glo_pl_f = (20 * math.log10(2000000000)) + 20 * math.log10(4 * (math.pi) / 3 / 100000000)
    glo_height = 18
    con_pattern, los_pattern = Create_Boundary_pattern(UAV_R, glo_height, glo_pl_f)
    ue_list = origin_ue_loc_list.copy()
    while (len(ue_list) > 0):
        uav_loc = Solve_process(ue_list, con_pattern, los_pattern, UAV_R, ue_num_list)
        uav_list.append(uav_loc)
    endtime = time.time()
    # print("程序运行时间为：%.8s s" % (endtime - starttime))  # 时间显示到微秒
    #Draw_result(origin_ue_loc_list, uav_list, UAV_R, ue_num_list)
    print(uav_list)
    return uav_list

if __name__ == '__main__':
    main()