function [airways,flight_plans,flights] = UR_flight_manager(roads,s_name)
% UR_flight_manager - handles 
% On input:
%     roads (road data structure): defines roads
%      .vertexes (nx2 array): 2D points
%      .edges (mx2 array): road edges
%     s_name (string): name of simulation info file
% On output:
%     airways (airways data structure): contains airways data
%     flight_plans (vector struct): has plans for all flights
%      (k).data (px9 array): each row has:
%        [t1 t2 speed cor USS_id op_id pf_id launch_rd_ver land_rd_ver]
%     flights (vector struct): has flights organized by corridor
%       flights(c).flights (qx9 array): flights through corridor
%         [t1 t3 speed cor USS_id OP_id pf_id launch_rd_ver land_rd_ver]
% Call:
%     [aw,fp,f] = UR_flight_manager(roads,'sim_data1.txt');
% Author:
%     T. Henderson
%     UU
%     Summer 2019
%

global g_radius g_offset g_del
global g_USS_info
global g_airways
global g_z_upper g_z_lower g_z_circle g_z_launch g_z_land 
global g_speed
global g_flights g_flight_plans
global g_launch_vertexes g_land_vertexes
global g_ht

persistent first FM_comm

COMM_DIRECTORY = 1;
COMM_SEND = 2;
COMM_RECEIVE = 3;
M_USS2FM = 1;
M_FM2USS = 2;
M_REGISTER = 1;
M_REQUEST = 2;

if isempty(first)
    first = 0;
    fid = fopen('LAUNCH_SITES','r');
    g_launch_vertexes = fscanf(fid,'%d');
    fclose(fid);
    fid = fopen('LAND_SITES','r');
    g_land_vertexes = fscanf(fid,'%d');
    fclose(fid);
    fid = fopen(s_name,'r');
    params = fscanf(fid,'%d');
    fclose(fid);
    radius = params(1);
    offset = params(2);
    del = params(3);
    z_upper = params(4);
    z_lower = params(5);
    z_circle = params(6);
    z_launch = params(7);
    z_land = params(8);
    g_ht = params(9);
    
    g_radius = radius;
    g_offset = offset;
    g_del = del;
    g_z_upper = z_upper;
    g_z_lower = z_lower;
    g_z_circle = z_circle;
    g_z_launch = z_launch;
    g_z_land = z_land;
    g_speed = 1;
    g_flight_plans = [];
    g_airways = UR_gen_airways(roads,g_launch_vertexes,g_land_vertexes);
    num_cors = length(g_airways.corridors(:,1));
    for c = 1:num_cors
        g_flights(c).flights = [];
    end
    FM_comm = UR_comms(COMM_DIRECTORY,'flight-manager',[]);
end

airways = g_airways;
flights = g_flights;
flight_plans = g_flight_plans;

messages = UR_comms(COMM_RECEIVE,[FM_comm,0],[]);

if isempty(messages)
    return
end

num_messages = length(messages);
for m = 1:num_messages
    mess = messages(m).mess;
    if isempty(g_USS_info)
        len_g_USS_info = 0;
    else
        len_g_USS_info = length(g_USS_info);
    end
    switch mess.type
        case M_USS2FM
            switch mess.action
                case M_REGISTER
                    % handle USS registrations
                    found = 0;
                    for u = 1:len_g_USS_info
                        if g_USS_info(u).id==mess.code
                            found = 1;
                            break
                        end
                    end
                    if found==0
                        len_g_USS_info = len_g_USS_info + 1;
                        g_USS_info(len_g_USS_info).id = mess.code;
                        g_USS_info(len_g_USS_info).uname = mess.data;
                        g_USS_info(len_g_USS_info).requests = [];
                        g_USS_info(len_g_USS_info).flights = [];
                    end
                    mess_out.type = M_FM2USS;
                    mess_out.code = FM_comm;
                    mess_out.action = M_REGISTER;
                    mess_out.data = len_g_USS_info;
                    UR_comms(COMM_SEND,[FM_comm,mess.code],mess_out);
                case M_REQUEST
                    % handle USS flight requests
                    found = 0;
                    u = 0;
                    while found==0&u<len_g_USS_info
                        u = u + 1;
                        if g_USS_info(u).id==mess.code
                            found = 1;
                        end
                    end
                    if found==0
                        return
                    end
                    req_num = mess.data(9);
                    if isempty(find(g_USS_info(u).requests==req_num))
                        g_USS_info(u).requests = [g_USS_info(u).requests;...
                            req_num,0];
                        params = mess.data;
%                        flight_plan = UR_find_fp_uni(params(7),params(8),...
%                            params(2),params(5),params(6),g_ht);
                        flight_plan = UR_find_fp(params(7),params(8),...
                            params(2),params(5),params(6),g_ht);
                        if ~isempty(flight_plan)
                            num_cors = length(flight_plan(:,1));
                            flight_info = zeros(num_cors,9);
                            for c = 1:num_cors
                                flight_info(c,1:4) = flight_plan(c,1:4);
                                flight_info(c,5) = params(1);
                                flight_info(c,6:9) = params(3:6);
                            end
                            UR_reserve_flight(flight_info);
                            flights = g_flights;
                            num_flight_plans = length(g_flight_plans) + 1;
                            g_flight_plans(num_flight_plans).data = ...
                                flight_info;
                            g_USS_info(u).requests(end,2) = 1;
                        end
                    end
            end
    end
end
flight_plans = g_flight_plans;
