function flights = UTM_zipper_TD(flights_in,lanes,lane_degrees,co_lanes,...
    dummy2,f_td,dummy3,cur_time,dummy4)
%

UTM_load_vars;

flights = flights_in;

if flights(f_td).status~=IN_FLIGHT
    return
end
other_flights = [];

f_td_lane_index = flights(f_td).lane_index;
lane_length1 = flights(f_td).lane_lengths(f_td_lane_index);
lane1 = flights(f_td).traj(f_td_lane_index);
dist1 = flights(f_td).lane_dists(f_td_lane_index);
speed1 = flights(f_td).lane_speeds(f_td_lane_index);
TOA1 = flights(f_td).TOA(f_td_lane_index);
option = UTM_deconflict_option(lane_degrees,lane1,dist1);
te1 = TOA1;

switch option
    case {1,2,9,10,13,14}  % launch lane, 3M, between lane entry and exit points
        
        % set up f_td info
        lane2 = flights(f_td).traj(f_td_lane_index+1);
        P1 = lanes(lane1,1:3);
        P2 = lanes(lane1,4:6);
        dirP = P2 - P1;
        dirP = dirP/norm(dirP);
        O1 = P1 + dist1*dirP;
        V1 = speed1*dirP;
        ts1 = cur_time;
        te1 = TOA1;
        
        % set up other flights
        O2 = [];
        V2 = [];
        ts2 = [];
        te2 = [];
        other_flights = [];
        
        % same lane flights
        [min_d,f_ip] = UTM_im_prec_flight(flights,lane1,f_td);
        if f_ip>0
            other_flights = [other_flights; f_ip];
            f_ip_lane_index = flights(f_ip).lane_index;
            f_ip_speed1 = flights(f_ip).lane_speeds(f_ip_lane_index);
            f_ip_dist1 = flights(f_ip).lane_dists(f_ip_lane_index);
            f_ip_TOA1 = flights(f_ip).TOA(f_ip_lane_index);
            f_ip_loc = P1 + f_ip_dist1*dirP;
            O2 = [O2;f_ip_loc];
            V2 = [V2; f_ip_speed1*dirP];
            ts2 = [ts2; cur_time];
            te2 = [te2; f_ip_TOA1];
        end
        
        % other merging lane flights
        exit_in_lanes = co_lanes(lane1).exit_in;
        if ~isempty(exit_in_lanes)
            num_exit_in_lanes = length(exit_in_lanes);
            for k = 1:num_exit_in_lanes
                lane_k = exit_in_lanes(k);
                f_list = UTM_flights_in_lane(flights,lane_k);
                if ~isempty(f_list)
                    num_f_list = length(f_list(:,1));
                    for p = 1:num_f_list
                        f = f_list(p,1);
                        other_flights = [other_flights; f];
                        f_dist = f_list(p,2);
                        f_TOA1 = f_list(p,3);
                        f_lane_index = flights(f).lane_index;
                        f_speed1 = flights(f).lane_speeds(f_lane_index);
                        Q1 = lanes(lane_k,1:3);
                        Q2 = lanes(lane_k,4:6);
                        dirQ = Q2 - Q1;
                        dirQ = dirQ/norm(dirQ);
                        loc2 = Q1 + f_dist*dirQ;
                        O2 = [O2; loc2];
                        V2 = [V2; f_speed1*dirQ];
                        ts2 = [ts2; cur_time];
                        te2 = [te2; f_TOA1];
                    end
                end
            end
        end
        
        % last flights into lane2
        f_info = UTM_flights_in_lane(flights,lane2);
        last_flight = [];
        if ~isempty(f_info)
            f1 = f_info(1,1);
            last_flight = f1;
            other_flights = [other_flights; f1];
            f1_dist = f_info(1,2);
            f1_TOA = f_info(1,3);
            f1_lane_index = flights(f1).lane_index;
            Q1 = lanes(lane2,1:3);
            Q2 = lanes(lane2,4:6);
            dirQ = Q2 - Q1;
            dirQ = dirQ/norm(dirQ);
            f1_loc = Q1 + f1_dist*dirQ;
            f1_speed = flights(f1).lane_speeds(f1_lane_index);
            O2 = [O2; f1_loc];
            V2 = [V2; f1_speed*dirQ];
            ts2 = [ts2; cur_time];
            te2 = [te2; te1];
        end
        
        % find deconflicted TOA for f_td
        num_other_flights = length(other_flights);
        done = isempty(O2);
        while done==0
            if speed1<FAIL_SPEED
                flights(f_td).status = -1;
                return
            end
            done = 1;
            k = 0;
            conflict = 0;
            while k<num_other_flights&conflict==0
                k = k + 1;
                [min_d,t] = UTM_trajMinDist(O1,V1,ts1,te1,O2(k,:),...
                    V2(k,:),ts2(k),te2(k));
                if min_d<d_S
                    done = 0;
                    conflict = 1;
                    te1 = te1 + del_t;
                    speed1 = (lane_length1-dist1)/(te1-cur_time);
                    V1 = speed1*dirP;
                else  % check conflict when other flight in lane 2
                    f = other_flights(k);
                    if f~=last_flight
                        f_lane_index = flights(f).lane_index;
                        lane2 = flights(f).traj(f_lane_index+1);
                        f_TOD2 = flights(f).TOD(f_lane_index+1);
                        f_speed2 = flights(f).lane_speeds(f_lane_index+1);
                        Q1 = lanes(lane2,1:3);
                        Q2 = lanes(lane2,4:6);
                        dirQ = Q2 - Q1;
                        dirQ = dirQ/norm(dirQ);
                        O22 = Q1;
                        V22 = f_speed2*dirQ;
                        ts22 = f_TOD2;
                        te22 = te1;
                        if te22>ts22
                            dist_in_lane = speed1*(f_TOD2-cur_time) + dist1;
                            O12 = P1 + dist_in_lane*dirP;
                            V12 = V1;
                            ts12 = f_TOD2;
                            te12 = te1;
                            [min_d2,t2] = UTM_trajMinDist(O12,V12,ts12,te12,...
                                O22,V22,ts22,te22);
                            if min_d2<d_S
                                done = 0;
                                conflict = 1;
                                te1 = te1 + del_t;
                                speed1 = (lane_length1-dist1)/(te1-cur_time);
                                V1 = speed1*dirP;
                            end
                        end
                    end
                end
            end
        end
    case {3,4,11,12,15,16}  % launch lane, 3D
        % set up f_td info
        lane2 = flights(f_td).traj(f_td_lane_index+1);
        P1 = lanes(lane1,1:3);
        P2 = lanes(lane1,4:6);
        dirP = P2 - P1;
        dirP = dirP/norm(dirP);
        O1 = P1 + dist1*dirP;
        V1 = speed1*dirP;
        ts1 = cur_time;
        te1 = TOA1;
        
        % set up other flights
        O2 = [];
        V2 = [];
        ts2 = [];
        te2 = [];
        other_flights = [];
        
        % all same lane flights
        f_list = UTM_flights_in_lane(flights,lane1);
        index = find(f_list(:,1)==f_td);
        f_list = f_list(index+1:end,:);
        if ~isempty(f_list)
            num_f_list = length(f_list(:,1));
            for p = 1:num_f_list
                f = f_list(p,1);
                other_flights = [other_flights; f];
                f_dist = f_list(p,2);
                f_TOA1 = f_list(p,3);
                f_lane_index = flights(f).lane_index;
                f_speed1 = flights(f).lane_speeds(f_lane_index);
                f_loc1 = P1 + f_dist*dirP;
                O2 = [O2; f_loc1];
                V2 = [V2; f_speed1*dirP];
                ts2 = [ts2; cur_time];
                te2 = [te2; f_TOA1];
            end
        end
        
        % other diverging lane flights
        exit_out_lanes = co_lanes(lane1).exit_out;
        if ~isempty(exit_out_lanes)
            num_exit_out_lanes = length(exit_out_lanes);
            for k = 1:num_exit_out_lanes
                lane_k = exit_out_lanes(k);
                f_list = UTM_flights_in_lane(flights,lane_k);
                if ~isempty(f_list)
                    f = f_list(1,1);
                    other_flights = [other_flights; f];
                    f_dist = f_list(1,2);
                    f_TOA1 = f_list(1,3);
                    f_lane_index = flights(f).lane_index;
                    f_speed1 = flights(f).lane_speeds(f_lane_index);
                    Q1 = lanes(lane_k,1:3);
                    Q2 = lanes(lane_k,4:6);
                    dirQ = Q2 - Q1;
                    dirQ = dirQ/norm(dirQ);
                    loc2 = Q1 + f_dist*dirQ;
                    O2 = [O2; loc2];
                    V2 = [V2; f_speed1*dirQ];
                    ts2 = [ts2; cur_time];
                    te2 = [te2; f_TOA1];
                end
            end
        end
        
        % last flight into lane2
%        f_info = UTM_flights_in_lane(flights,lane2);
        last_flight = [];
%        if ~isempty(f_info)
%            f1 = f_info(1,1);
%            other_flights = [other_flights;f1];
%            last_flight = [f1];
%            f1_dist = f_info(1,2);
%            f1_TOA = f_info(1,3);
%            f1_lane_index = flights(f1).lane_index;
%            Q1 = lanes(lane2,1:3);
%            Q2 = lanes(lane2,4:6);
%            dirQ = Q2 - Q1;
%            dirQ = dirQ/norm(dirQ);
%            f1_loc = Q1 + f1_dist*dirQ;
%            f1_speed = flights(f1).lane_speeds(f1_lane_index);
%            O2 = [O2; f1_loc];
%            V2 = [V2; f1_speed*dirQ];
%            ts2 = [ts2; cur_time];
%            te2 = [te2; te1];
%        end
        
        % find deconflicted TOA for f_td
        num_other_flights = length(other_flights);
        done = isempty(O2);
        while done==0
            if speed1<FAIL_SPEED
                flights(f_td).status = -1;
                return
            end
            done = 1;
            k = 0;
            conflict = 0;
            while k<num_other_flights&conflict==0
                k = k + 1;
                [min_d,t] = UTM_trajMinDist(O1,V1,ts1,te1,O2(k,:),...
                    V2(k,:),ts2(k),te2(k));
                if min_d<d_S
                    done = 0;
                    conflict = 1;
                    te1 = te1 + del_t;
                    speed1 = (lane_length1-dist1)/(te1-cur_time);
                    V1 = speed1*dirP;
                else  % check conflict when other flight in lane 2
                    f = other_flights(k);
                    if f~=last_flight
                        f_lane_index = flights(f).lane_index;
                        lane2 = flights(f).traj(f_lane_index+1);
                        f_TOD2 = flights(f).TOD(f_lane_index+1);
                        f_speed2 = flights(f).lane_speeds(f_lane_index+1);
                        Q1 = lanes(lane2,1:3);
                        Q2 = lanes(lane2,4:6);
                        dirQ = Q2 - Q1;
                        dirQ = dirQ/norm(dirQ);
                        O22 = Q1;
                        V22 = f_speed2*dirQ;
                        ts22 = f_TOD2;
                        te22 = te1;
                        if te22>ts22
                            dist_in_lane = speed1*(f_TOD2-cur_time) + dist1;
                            O12 = P1 + dist_in_lane*dirP;
                            V12 = V1;
                            ts12 = f_TOD2;
                            te12 = te1;
                            [min_d2,t2] = UTM_trajMinDist(O12,V12,ts12,te12,...
                                O22,V22,ts22,te22);
                            if min_d2<d_S
                                done = 0;
                                conflict = 1;
                                te1 = te1 + del_t;
                                speed1 = (lane_length1-dist1)/(te1-cur_time);
                                V1 = speed1*dirP;
                            end
                        end
                    end
                end
            end
        end
    case {5,6,7,8}  % landing lane
        % set up f_td info
        P1 = lanes(lane1,1:3);
        P2 = lanes(lane1,4:6);
        dirP = P2 - P1;
        dirP = dirP/norm(dirP);
        O1 = P1 + dist1*dirP;
        V1 = speed1*dirP;
        ts1 = cur_time;
        te1 = TOA1;
        
        % same lane flights
        [min_d,f_ip] = UTM_im_prec_flight(flights,lane1,f_td);
        if f_ip>0
            other_flights = [other_flights; f_ip];
            f_ip_lane_index = flights(f_ip).lane_index;
            f_ip_speed1 = flights(f_ip).lane_speeds(f_ip_lane_index);
            f_ip_dist1 = flights(f_ip).lane_dists(f_ip_lane_index);
            f_ip_TOA1 = flights(f_ip).TOA(f_ip_lane_index);
            f_ip_loc = P1 + f_ip_dist1*dirP;
            O2 = f_ip_loc;
            V2 = f_ip_speed1*dirP;
            ts2 = cur_time;
            te2 = f_ip_TOA1;
            done = 0;
            while done==0
            if speed1<FAIL_SPEED
                flights(f_td).status = -1;
                return
            end
                done = 1;
                [min_d,t] = UTM_trajMinDist(O1,V1,ts1,te1,O2,V2,ts2,te2);
                if min_d<d_S
                    done = 0;
                    te1 = te1 + del_t;
                    speed1 = (lane_length1-dist1)/(te1-cur_time);
                    V1 = speed1*dirP;
                end
            end
        end
    case {17,18}  % single lane into single lane

        % set up f_td info
        P1 = lanes(lane1,1:3);
        P2 = lanes(lane1,4:6);
        dirP = P2 - P1;
        dirP = dirP/norm(dirP);
        O1 = P1 + dist1*dirP;
        V1 = speed1*dirP;
        ts1 = cur_time;
        te1 = TOA1;
        
        % get immediately preceding flight in lane
        [min_d,f_ip] = UTM_im_prec_flight(flights,lane1,f_td);
        
        if f_ip>0
            f_ip_lane_index = flights(f_ip).lane_index;
            f_dist = flights(f_ip).lane_dists(f_ip_lane_index);;
            f_TOA1 = flights(f_ip).TOA(f_ip_lane_index);
            f_speed1 = flights(f_ip).lane_speeds(f_ip_lane_index);
            O2 = P1;
            V2 = f_speed1*dirP;
            ts2 = cur_time;
            te2 = f_TOA1;
            lane2 = flights(f_ip).traj(f_ip_lane_index+1);
            f_TOD2 = flights(f_ip).TOD(f_lane_index+1);
            f_speed2 = flights(f_ip).lane_speeds(f_ip_lane_index+1);
            Q1 = lanes(lane2,1:3);
            Q2 = lanes(lane2,4:6);
            dirQ = Q2 - Q1;
            dirQ = dirQ/norm(dirQ);
            O22 = Q1;
            V22 = f_speed2*dirQ;
            ts22 = f_TOD2;
            
            done = 0;
            while done==0
            if speed1<FAIL_SPEED
                flights(f_td).status = -1;
                return
            end
                done = 1;
                [min_d,t] = UTM_trajMinDist(O1,V1,ts1,te1,O2,V2,ts2,te2);
                if min_d<d_S
                    done = 0;
                    te1 = te1 + del_t;
                    speed1 = (lane_length1-dist1)/(te1-cur_time);
                    V1 = speed1*dirP;
                else  % check conflict when other flight in lane 2
                    te22 = te1;
                    if te22>ts22
                        dist_in_lane = speed1*(f_TOD2-cur_time) + dist1;
                        O12 = P1 + dist_in_lane*dirP;
                        V12 = V1;
                        ts12 = f_TOD2;
                        te12 = te1;
                        [min_d2,t2] = UTM_trajMinDist(O12,V12,ts12,te12,...
                            O22,V22,ts22,te22);
                        if min_d2<d_S
                            done = 0;
                            te1 = te1 + del_t;
                            speed1 = (lane_length1-dist1)/(te1-cur_time);
                            V1 = speed1*dirP;
                        end
                    end
                end
            end
        end        
end

flights(f_td).lane_speeds(f_td_lane_index) = speed1;
flights(f_td).TOA(f_td_lane_index) = te1;
for k = f_td_lane_index+1:length(flights(f_td).traj)
    flights(f_td).TOD(k) = flights(f_td).TOA(k-1);
    flights(f_td).TOA(k) = flights(f_td).TOD(k)...
        + flights(f_td).lane_lengths(f_td_lane_index)...
        /flights(f_td).lane_speeds(f_td_lane_index);
end
