function varargout = join_cameras(varargin)
% JOIN_CAMERAS MATLAB code for join_cameras.fig
%      JOIN_CAMERAS, by itself, creates a new JOIN_CAMERAS or raises the existing
%      singleton*.
%
%      H = JOIN_CAMERAS returns the handle to a new JOIN_CAMERAS or the handle to
%      the existing singleton*.
%
%      JOIN_CAMERAS('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in JOIN_CAMERAS.M with the given input arguments.
%
%      JOIN_CAMERAS('Property','Value',...) creates a new JOIN_CAMERAS or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before join_cameras_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to join_cameras_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help join_cameras
% Last Modified by GUIDE v2.5 06-Apr-2017 16:03:18
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @join_cameras_OpeningFcn, ...
                   'gui_OutputFcn',  @join_cameras_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before join_cameras is made visible.
function join_cameras_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to join_cameras (see VARARGIN)
% Choose default command line output for join_cameras
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes join_cameras wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = join_cameras_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;

% --- Executes on button press in cmd_browse_1.
function cmd_browse_1_Callback(hObject, eventdata, handles)
% hObject    handle to cmd_browse_1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global matrix_data_1
set(handles.lbl_messages,'String','Loading, please wait');
[filename_data_1,path_data_1]=uigetfile('*.*','Select file');
matrix_data_1=load(strcat(path_data_1,filename_data_1),'ascii');
set(handles.lbl_messages,'String','file 1 loaded');

% --- Executes on button press in cmd_browse_2.
function cmd_browse_2_Callback(hObject, eventdata, handles)
% hObject    handle to cmd_browse_2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global matrix_data_2
set(handles.lbl_messages,'String','Loading, please wait');
[filename_data_2,path_data_2]=uigetfile('*.*','Select file');
matrix_data_2=load(strcat(path_data_2,filename_data_2),'ascii');
set(handles.lbl_messages,'String','file 2 loaded');

% --- Executes on button press in cmd_exit.
function cmd_exit_Callback(hObject, eventdata, handles)
% hObject    handle to cmd_exit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
close

function txt_x_add_Callback(hObject, eventdata, handles)
% hObject    handle to txt_x_add (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of txt_x_add as text
%        str2double(get(hObject,'String')) returns contents of txt_x_add as a double

% --- Executes during object creation, after setting all properties.
function txt_x_add_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txt_x_add (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function txt_y_add_Callback(hObject, eventdata, handles)
% hObject    handle to txt_y_add (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of txt_y_add as text
%        str2double(get(hObject,'String')) returns contents of txt_y_add as a double

% --- Executes during object creation, after setting all properties.
function txt_y_add_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txt_y_add (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function txt_x_min_overlap_Callback(hObject, eventdata, handles)
% hObject    handle to txt_x_min_overlap (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of txt_x_min_overlap as text
%        str2double(get(hObject,'String')) returns contents of txt_x_min_overlap as a double

% --- Executes during object creation, after setting all properties.
function txt_x_min_overlap_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txt_x_min_overlap (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function txt_x_max_overlap_Callback(hObject, eventdata, handles)
% hObject    handle to txt_x_max_overlap (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of txt_x_max_overlap as text
%        str2double(get(hObject,'String')) returns contents of txt_x_max_overlap as a double

% --- Executes during object creation, after setting all properties.
function txt_x_max_overlap_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txt_x_max_overlap (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in cmd_seg_properties.
function cmd_seg_properties_Callback(hObject, eventdata, handles)
% hObject    handle to cmd_seg_properties (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global matrix_data_1
global matrix_data_2
global matrix_seg_properties_1
global matrix_seg_properties_2
% first camera
[segments_found_1,matrix_seg_properties_1]=findproperties(matrix_data_1);
% second camera
[segments_found_2,matrix_seg_properties_2]=findproperties(matrix_data_2);
set(handles.lbl_messages,'String',strcat('done, found ',num2str(segments_found_1),' segments for 1 and ',num2str(segments_found_2),' for 2'));

% --- Executes on button press in cmd_plot_x_y.
function cmd_plot_x_y_Callback(hObject, eventdata, handles)
% hObject    handle to cmd_plot_x_y (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global matrix_data_1
global matrix_data_2
global matrix_seg_properties_1
global matrix_seg_properties_2
set(handles.lbl_messages,'String','Plotting, please wait');
figure(1); % this will display camera 1
hold on
figure(2); % this will display camera 2
hold on
figure(3); % this will display both
hold on
long_segments_1=0;
long_segments_2=0;
threshold_length=str2num(get(handles.txt_plot_longer,'String'));
for index_segment_1=1:size(matrix_seg_properties_1,1)
    if matrix_seg_properties_1(index_segment_1,8)>threshold_length
        long_segments_1=long_segments_1+1;
        x_seg_1=matrix_data_1(matrix_seg_properties_1(index_segment_1,1):matrix_seg_properties_1(index_segment_1,3),2);
        y_seg_1=matrix_data_1(matrix_seg_properties_1(index_segment_1,1):matrix_seg_properties_1(index_segment_1,3),3);
        figure(1),plot(x_seg_1,y_seg_1,'-k'),xlabel('x (mm)'),ylabel('y (mm)');
        figure(3),plot(x_seg_1,y_seg_1,'-k'),xlabel('x (mm)'),ylabel('y (mm)');
    end
end
for index_segment_2=1:size(matrix_seg_properties_2,1)
    if matrix_seg_properties_2(index_segment_2,8)>threshold_length
        long_segments_2=long_segments_2+1;
        x_seg_2=matrix_data_2(matrix_seg_properties_2(index_segment_2,1):matrix_seg_properties_2(index_segment_2,3),2);
        y_seg_2=matrix_data_2(matrix_seg_properties_2(index_segment_2,1):matrix_seg_properties_2(index_segment_2,3),3);
        figure(2),plot(x_seg_2,y_seg_2,'-r'),xlabel('x (mm)'),ylabel('y (mm)');
        figure(3),plot(x_seg_2,y_seg_2,'-r'),xlabel('x (mm)'),ylabel('y (mm)');
    end
end
hold off
hold off
hold off
set(handles.lbl_messages,'String',strcat('done, displayed ',num2str(long_segments_1),' segments for 1 and ',num2str(long_segments_2),' for 2'));

function txt_plot_longer_Callback(hObject, eventdata, handles)
% hObject    handle to txt_plot_longer (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of txt_plot_longer as text
%        str2double(get(hObject,'String')) returns contents of txt_plot_longer as a double

% --- Executes during object creation, after setting all properties.
function txt_plot_longer_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txt_plot_longer (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in cmd_same_system.
function cmd_same_system_Callback(hObject, eventdata, handles)
% hObject    handle to cmd_same_system (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global matrix_data_2
global matrix_seg_properties_2
% will put values of the second camera in the same reference of the first
x_add=str2num(get(handles.txt_x_add,'String'));
y_add=str2num(get(handles.txt_y_add,'String'));
for index=1:size(matrix_data_2,1)
    if matrix_data_2(index,1)~=-1
        matrix_data_2(index,2)=matrix_data_2(index,2)+x_add;
        matrix_data_2(index,3)=matrix_data_2(index,3)+y_add;
    end
end
for index_p=1:size(matrix_seg_properties_2,1)
    matrix_seg_properties_2(index_p,6)=matrix_seg_properties_2(index_p,6)+x_add;
    matrix_seg_properties_2(index_p,7)=matrix_seg_properties_2(index_p,7)+x_add;
    matrix_seg_properties_2(index_p,10)=matrix_seg_properties_2(index_p,10)+y_add;
    matrix_seg_properties_2(index_p,11)=matrix_seg_properties_2(index_p,11)+y_add;
end
set(handles.lbl_messages,'String','done, x-y system is now the same');

function txt_remove_shorter_Callback(hObject, eventdata, handles)
% hObject    handle to txt_remove_shorter (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of txt_remove_shorter as text
%        str2double(get(hObject,'String')) returns contents of txt_remove_shorter as a double

% --- Executes during object creation, after setting all properties.
function txt_remove_shorter_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txt_remove_shorter (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in cmd_remove_short.
function cmd_remove_short_Callback(hObject, eventdata, handles)
% hObject    handle to cmd_remove_short (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global matrix_data_1
global matrix_data_2
global matrix_seg_properties_1
global matrix_seg_properties_2
set(handles.lbl_messages,'String','Removing short, please wait');
threshold_length=str2num(get(handles.txt_remove_shorter,'String'));
% Initializes new matrices for data
matrix_data_1_new=[-1 -1 -1];
matrix_data_2_new=[-1 -1 -1];
% Job for first camera
for index_segment_1=1:size(matrix_seg_properties_1,1)
    length_seg=matrix_seg_properties_1(index_segment_1,8);
    if length_seg>threshold_length % segment must be kept
        pos_start=matrix_seg_properties_1(index_segment_1,1);
        pos_end=matrix_seg_properties_1(index_segment_1,3);
        matrix_extract=matrix_data_1(pos_start:pos_end,:);
        matrix_data_1_new=cat(1,matrix_data_1_new,matrix_extract);
        matrix_data_1_new=cat(1,matrix_data_1_new,[-1 -1 -1]);
    end
end
matrix_data_1=matrix_data_1_new;
[seg_no_1,matrix_seg_properties_1]=findproperties(matrix_data_1);
% Job for second camera
for index_segment_2=1:size(matrix_seg_properties_2,1)
    length_seg=matrix_seg_properties_2(index_segment_2,8);
    if length_seg>threshold_length % segment must be kept
        pos_start=matrix_seg_properties_2(index_segment_2,1);
        pos_end=matrix_seg_properties_2(index_segment_2,3);
        matrix_extract=matrix_data_2(pos_start:pos_end,:);
        matrix_data_2_new=cat(1,matrix_data_2_new,matrix_extract);
        matrix_data_2_new=cat(1,matrix_data_2_new,[-1 -1 -1]);
    end
end
matrix_data_2=matrix_data_2_new;
[seg_no_2,matrix_seg_properties_2]=findproperties(matrix_data_2);
% final message
set(handles.lbl_messages,'String',strcat('done, kept ',num2str(seg_no_1),' segments for 1 and ',num2str(seg_no_2),' for 2'));

% --- Executes on button press in cmd_merge_tables.
function cmd_merge_tables_Callback(hObject, eventdata, handles)
% hObject    handle to cmd_merge_tables (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global matrix_data_1
global matrix_data_2
global matrix_seg_properties_1
global matrix_seg_properties_2
global matrix_data_tot
global matrix_seg_properties_tot
matrix_data_tot=cat(1,matrix_data_1,matrix_data_2); % no need for anything as it is just putting table together
matrix_seg_properties_2_forcat=matrix_seg_properties_2;
matrix_seg_properties_2_forcat(:,1)=matrix_seg_properties_2(:,1)+size(matrix_data_1,1); % changes positions
matrix_seg_properties_2_forcat(:,3)=matrix_seg_properties_2(:,3)+size(matrix_data_1,1); % same as previous line
matrix_seg_properties_tot=cat(1,matrix_seg_properties_1,matrix_seg_properties_2_forcat);
set(handles.lbl_messages,'String','Matrices were merged');

function txt_track_for_props_Callback(hObject, eventdata, handles)
% hObject    handle to txt_track_for_props (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of txt_track_for_props as text
%        str2double(get(hObject,'String')) returns contents of txt_track_for_props as a double

% --- Executes during object creation, after setting all properties.
function txt_track_for_props_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txt_track_for_props (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in cmd_furnish_props.
function cmd_furnish_props_Callback(hObject, eventdata, handles)
% hObject    handle to cmd_furnish_props (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global matrix_seg_properties_tot
% finds which track must be furnished
track_number=str2num(get(handles.txt_track_for_props,'String'));
if track_number>0 && track_number<=size(matrix_seg_properties_tot,1)
    % finds relevant properties
    t_1=matrix_seg_properties_tot(track_number,2);
    t_2=matrix_seg_properties_tot(track_number,4);
    x_1=matrix_seg_properties_tot(track_number,6);
    x_2=matrix_seg_properties_tot(track_number,7);
    y_1=matrix_seg_properties_tot(track_number,10);
    y_2=matrix_seg_properties_tot(track_number,11);
    disp(strcat('track',num2str(track_number),':t_1=',num2str(t_1),';t_2=',num2str(t_2),';x_1=',num2str(x_1),';x_2=',num2str(x_2),...
        ';y_1=',num2str(y_1),';y_2=',num2str(y_2)));
    set(handles.lbl_messages,'String',strcat('Done for segment ',num2str(track_number)));
else
    set(handles.lbl_messages,'String','Wrong segment number');
end    

function txt_tol_x_Callback(hObject, eventdata, handles)
% hObject    handle to txt_tol_x (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of txt_tol_x as text
%        str2double(get(hObject,'String')) returns contents of txt_tol_x as a double

% --- Executes during object creation, after setting all properties.
function txt_tol_x_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txt_tol_x (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function txt_tol_y_Callback(hObject, eventdata, handles)
% hObject    handle to txt_tol_y (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of txt_tol_y as text
%        str2double(get(hObject,'String')) returns contents of txt_tol_y as a double

% --- Executes during object creation, after setting all properties.
function txt_tol_y_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txt_tol_y (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in cmd_join.
function cmd_join_Callback(hObject, eventdata, handles)
% hObject    handle to cmd_join (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global matrix_data_tot
global matrix_seg_properties_tot
% 1) parameters
% edges of the overlapping region
x_min_over=str2num(get(handles.txt_x_min_overlap,'String'));
x_max_over=str2num(get(handles.txt_x_max_overlap,'String'));
% tolerances (in x,y)
x_tolerance=str2num(get(handles.txt_tol_x,'String'));
y_tolerance=str2num(get(handles.txt_tol_y,'String'));
% 2) finds segments with at least an end in the overlapping region, labels accordingly
[matrix_seg_properties_tot,no_ones,no_twos,no_threes,no_zeros]=matrixlabel(matrix_seg_properties_tot,x_min_over,x_max_over);
disp(strcat('segments:',num2str(size(matrix_seg_properties_tot,1))));
disp(strcat('1s:',num2str(no_ones)));
disp(strcat('2s:',num2str(no_twos)));
disp(strcat('3s:',num2str(no_threes)));
disp(strcat('0s:',num2str(no_zeros)));
disp('Segments were labelled');
% 3) now a HUGE loop begins to reconnect; actually multiple nested loops
do_again=1; % will become zero when no link is made during a loop
reconnections=0;
while do_again==1
    reconnections_previous=reconnections; % at the end of the loop it shall check if the value was changed
    index_segment=1; % starts from the first segment
    exit_first_loop=0; % will become 1 if a reconnection is performed
    while index_segment<=size(matrix_seg_properties_tot,1)
        label_segment=matrix_seg_properties_tot(index_segment,14);
        if label_segment==0 || label_segment==2 % useless segment, shall pass to next one
            index_segment=index_segment+1;
        elseif label_segment==1 % segment of type 1, shall find candidates among types 2 and 3
            index_segment_2=1;
            while index_segment_2<=size(matrix_seg_properties_tot,1)
                disp(strcat('segments-',num2str(index_segment),'-',num2str(index_segment_2)));
                label_segment_2=matrix_seg_properties_tot(index_segment_2,14);
                disp(strcat('labels-',num2str(label_segment),'-',num2str(label_segment_2)));
                if label_segment_2==0 || label_segment_2==1 % segment 2 is not suitable, shall pass to next one
                    index_segment_2=index_segment_2+1;
                else % now we have a candidate for inspection;
                    % a type 1 can be linked to a type 2 or to a type 3,
                    % and four cases are possible:
                    % case 1 - 1+2, overlapped completely
                    % case 2 - 1+2, overlapped partially
                    % case 3 - 1+3, 3 ends later
                    % case 4 - 1+3, 3 ends before
                    % 3.1) properties of segments
                    pos_start_1=matrix_seg_properties_tot(index_segment,1);
                    pos_end_1=matrix_seg_properties_tot(index_segment,3);
                    t_1=matrix_data_tot(pos_start_1:pos_end_1,1);
                    x_1=matrix_data_tot(pos_start_1:pos_end_1,2);
                    y_1=matrix_data_tot(pos_start_1:pos_end_1,3);
                    t_start_1=matrix_seg_properties_tot(index_segment,2);
                    t_end_1=matrix_seg_properties_tot(index_segment,4);
                    x_start_1=matrix_seg_properties_tot(index_segment,6);
                    x_end_1=matrix_seg_properties_tot(index_segment,7);
                    y_start_1=matrix_seg_properties_tot(index_segment,10);
                    y_end_1=matrix_seg_properties_tot(index_segment,11);
                    pos_start_2=matrix_seg_properties_tot(index_segment_2,1);
                    pos_end_2=matrix_seg_properties_tot(index_segment_2,3);
                    t_2=matrix_data_tot(pos_start_2:pos_end_2,1);
                    x_2=matrix_data_tot(pos_start_2:pos_end_2,2);
                    y_2=matrix_data_tot(pos_start_2:pos_end_2,3);
                    t_start_2=matrix_seg_properties_tot(index_segment_2,2);
                    t_end_2=matrix_seg_properties_tot(index_segment_2,4);
                    x_start_2=matrix_seg_properties_tot(index_segment_2,6);
                    x_end_2=matrix_seg_properties_tot(index_segment_2,7);
                    y_start_2=matrix_seg_properties_tot(index_segment_2,10);
                    y_end_2=matrix_seg_properties_tot(index_segment_2,11);
                    % 3.2) case identification
                    if label_segment_2==2
                        if x_end_1==x_max_over && x_start_2==x_min_over
                            case_overlap=1;
                        else
                            case_overlap=2;
                        end
                    else %label_segment_2 is 3
                        if x_end_2>x_end_1
                            case_overlap=3;
                        else
                            case_overlap=4;
                        end
                    end
                    % 3.3) check if reconnection is possible
                    switch case_overlap
                        case {1,2,3}
                            if t_start_1<t_start_2 && t_end_1<t_end_2 && t_end_1>t_start_2
                                reconn_possible=1;
                            else
                                reconn_possible=0;
                            end
                        case 4
                            if t_start_1<t_start_2 && t_end_1>t_end_2
                                reconn_possible=1;
                            else
                                reconn_possible=0;
                            end
                    end
                    % 3.4) if reconnection is possible, attempts it
                    if reconn_possible==1
                        % portion_1=find(x_1>=x_min_over && x_1<=x_max_over);
                        % did not work, replaced by what follows
                        service1=find(x_1>=x_min_over);
                        service2=x_1(service1);
                        service3=service1(1)-1+find(service2<=x_max_over);
                        portion_1=service3;
                        % portion_2=find(x_2>=x_min_over && x_2<=x_max_over);
                        % did not work, replaced by what follows
                        service1=find(x_2>=x_min_over);
                        service2=x_2(service1);
                        service3=service1(1)-1+find(service2<=x_max_over);
                        portion_2=service3;
                        % end of replacement
                        t_1_over=t_1(portion_1); % range of time for which segment is in the overlapping region
                        t_2_over=t_2(portion_2);
                        t_in_1=min(t_1_over);
                        t_fin_1=max(t_1_over);
                        t_in_2=min(t_2_over);
                        t_fin_2=max(t_2_over);
                        if t_in_1>t_fin_2 || t_in_2>t_fin_1 % no intersection in time
                            index_segment_2=index_segment_2+1; % will pass to a new segment_2
                        else
                            t_in=max(t_in_1,t_in_2); % time for which spatial overlap will be checked
                            t_fin=min(t_fin_1,t_fin_2);
                            % similar replacement to previous one needed
                            service1=find(t_1>=t_in);
                            service2=t_1(service1);
                            service3=service1(1)-1+find(service2<=t_fin);
                            portion_1=service3;
                            x_1_check_over=x_1(portion_1);
                            y_1_check_over=y_1(portion_1);
                            %
                            service1=find(t_2>=t_in);
                            service2=t_2(service1);
                            service3=service1(1)-1+find(service2<=t_fin);
                            portion_2=service3;
                            x_2_check_over=x_2(portion_2);
                            y_2_check_over=y_2(portion_2);
%                             x_1_check_over=x_1(find(t_1>=t_in && t_1<=t_fin)); % extracts values of x and y
%                             x_2_check_over=x_2(find(t_2>=t_in && t_2<=t_fin));
%                             y_1_check_over=y_1(find(t_1>=t_in && t_1<=t_fin));
%                             y_2_check_over=y_2(find(t_2>=t_in && t_2<=t_fin));
                            % end of replacement
                            rms_x=sqrt(mean((x_2_check_over-x_1_check_over).^2));
                            rms_y=sqrt(mean((y_2_check_over-y_1_check_over).^2));
                            if rms_x>x_tolerance || rms_y>y_tolerance % not a successful match, process aborted
                                index_segment_2=index_segment_2+1; % will pass to a new segment_2
                            else % successful match
                                x_new=0.5*(x_1_check_over+x_2_check_over); % average x-y positions
                                y_new=0.5*(y_1_check_over+y_2_check_over);
                                t_new=t_in:t_fin;
                                t_x_y_new=cat(2,t_new',x_new,y_new);
                                % finds positions in
                                % matrix_data_tot
                                pos_start_over_1=pos_start_1+find(t_1==t_in)-1;
                                pos_end_over_2=pos_start_2+find(t_2==t_fin)-1;
                                % reassembles matrix_data_tot
                                switch case_overlap
                                    case {1,2,3}
                                        matrix_data_tot_2=matrix_data_tot(1:pos_start_over_1-1,:);
                                        matrix_data_tot_2=cat(1,matrix_data_tot_2,t_x_y_new);
                                        matrix_data_tot_2=cat(1,matrix_data_tot_2,matrix_data_tot(pos_end_over_2+1:pos_end_2,:));
                                        matrix_data_tot_2=cat(1,matrix_data_tot_2,matrix_data_tot(pos_end_1+1:pos_start_2-1,:));
                                        matrix_data_tot_2=cat(1,matrix_data_tot_2,matrix_data_tot(pos_end_2+1:size(matrix_data_tot,1),:));
                                    case 4
                                        matrix_data_tot_2=matrix_data_tot(1:pos_start_over_1-1,:);
                                        matrix_data_tot_2=cat(1,matrix_data_tot_2,t_x_y_new);
                                        matrix_data_tot_2=cat(1,matrix_data_tot_2,matrix_data_tot(pos_end_over_1+1:pos_end_1,:));
                                        matrix_data_tot_2=cat(1,matrix_data_tot_2,matrix_data_tot(pos_end_1+1:pos_start_2-1,:));
                                        matrix_data_tot_2=cat(1,matrix_data_tot_2,matrix_data_tot(pos_end_2+1:size(matrix_data_tot,1),:));
                                end
                                % updates number of reconnections
                                reconnections=reconnections+1;
                                disp(strcat('reconnections:',num2str(reconnections),';done'));
                                % updates matrices
                                matrix_data_tot=matrix_data_tot_2;
                                [seg_no,matrix_seg_properties_tot]=findproperties(matrix_data_tot); % invoked function
                                % re-labels
                                [matrix_seg_properties_tot,no_ones,no_twos,no_threes,no_zeros]=matrixlabel(matrix_seg_properties_tot,x_min_over,x_max_over);
                                % changes flag to restart process
                                % from the beginning
                                exit_first_loop=1;
                                break
                            end
                        end
                    else
                        index_segment_2=index_segment_2+1; % if reconnection is not possible, pass to following segment_2
                    end
                end
            end
            if exit_first_loop==1
                break
            else
                index_segment=index_segment+1;
            end
        end
    end
    if reconnections==reconnections_previous
        do_again=0;
    end
end
disp(strcat('Done, total reconnections: ',num2str(reconnections)));
set(handles.lbl_messages,'String',strcat('Done, total reconnections: ',num2str(reconnections)));

% --- Executes on button press in cmd_plot_reconnected.
function cmd_plot_reconnected_Callback(hObject, eventdata, handles)
% hObject    handle to cmd_plot_reconnected (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global matrix_data_tot
global matrix_seg_properties_tot
figure;
hold on;
previous='blue';
for index_segment=1:size(matrix_seg_properties_tot,1)
    x_seg=matrix_data_tot(matrix_seg_properties_tot(index_segment,1):matrix_seg_properties_tot(index_segment,3),2);
    y_seg=matrix_data_tot(matrix_seg_properties_tot(index_segment,1):matrix_seg_properties_tot(index_segment,3),3);
    switch previous
        case 'blue'
            plot(x_seg,y_seg,'-r');
            previous='red';
        case 'red'
            plot(x_seg,y_seg,'-g');
            previous='green';
        case 'green'    
            plot(x_seg,y_seg,'-c');
            previous='cyan';
        case 'cyan'    
            plot(x_seg,y_seg,'-m');
            previous='magenta';
        case 'magenta'    
            plot(x_seg,y_seg,'-b');
            previous='blue';
    end
end
hold off;






function txt_filename_save_Callback(hObject, eventdata, handles)
% hObject    handle to txt_filename_save (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of txt_filename_save as text
%        str2double(get(hObject,'String')) returns contents of txt_filename_save as a double

% --- Executes during object creation, after setting all properties.
function txt_filename_save_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txt_filename_save (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in cmd_save_result.
function cmd_save_result_Callback(hObject, eventdata, handles)
% hObject    handle to cmd_save_result (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global matrix_data_tot
filename=get(handles.txt_filename_save,'String');
save(filename,'matrix_data_tot','-ascii','-tabs');
set(handles.lbl_messages,'String','Reconnected tracks were saved');



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%   INVOKED FUNCTIONS   %%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% --- Invoked function to create matrix of segment properties
function [segments_found,props]=findproperties(data)
matrix_rows=size(data,1); % number of rows
segments_found=0; % initializes segment counter
for index_row=1:matrix_rows-1
    if (data(index_row,1)==-1 && data(index_row+1,1)~=-1) % one starting point has been found
        segments_found=segments_found+1;
        props(segments_found,1)=index_row+1; % column 1 --> start position in data
        props(segments_found,2)=data(index_row+1,1); % column 2 --> time of start
    end
end
for index_segment=1:segments_found
    index_start=props(index_segment,1);
    index_possible_end=index_start+1;
    while (data(index_possible_end,1)~=-1 && data(index_possible_end+1,1)~=-1)
        index_possible_end=index_possible_end+1;
    end % exits while when a segment end has been found
    props(index_segment,3)=index_possible_end; % column 3 --> end position in data
    props(index_segment,4)=data(index_possible_end,1); % column 4 --> time of end
    props(index_segment,5)=...
        props(index_segment,4)-props(index_segment,2); % column 5 --> segment duration
    props(index_segment,6)=data(index_start,2); % column 6 --> x position of start
    props(index_segment,7)=data(index_possible_end,2); % column 7 --> x position of end
    props(index_segment,8)=props(index_segment,7)-props(index_segment,6); % column 8 --> segment length in x
    props(index_segment,9)=props(index_segment,8)/props(index_segment,5); % column 9 --> mean velocity in x
    props(index_segment,10)=data(index_start,3); % column 10 --> y position of start
    props(index_segment,11)=data(index_possible_end,3); % column 11 --> y position of end
    props(index_segment,12)=props(index_segment,11)-props(index_segment,10); % column 12 --> segment length in y
    props(index_segment,13)=props(index_segment,12)/props(index_segment,5); % column 13 --> mean velocity in y
end

% --- Invoked function to label segments for possible overlap
function [matrix_properties,n1,n2,n3,n0]=matrixlabel(matrix_properties,x_min_o,x_max_o)
n1=0;
n2=0;
n3=0;
n0=0;
for index=1:size(matrix_properties,1)
    % segment type 1: ends in the overlapping region
    % segment type 2: begins in the overlapping region
    % segment type 3: begins and ends in the overlapping region
    % segment type 0: no edge in the overlapping region
    if matrix_properties(index,6)<x_min_o && matrix_properties(index,7)>x_min_o && matrix_properties(index,7)<=x_max_o
        matrix_properties(index,14)=1;
        n1=n1+1;
    elseif matrix_properties(index,6)>=x_min_o && matrix_properties(index,6)<x_max_o && matrix_properties(index,7)>x_max_o
        matrix_properties(index,14)=2;
        n2=n2+1;
    elseif matrix_properties(index,6)>=x_min_o && matrix_properties(index,7)<=x_max_o
        matrix_properties(index,14)=3;
        n3=n3+1;
    else
        matrix_properties(index,14)=0;
        n0=n0+1;
    end
end
