% APE 7 feb 14

function idMatcher(relaciones)

h.fig=figure('Name','idMatcher','Toolbar','none','Menubar','none','NumberTitle','off');
h.listavideos=uicontrol('Units','normalized','Position',[.05 .3 .9 .65],'Style','listbox');
h.push_addvideo=uicontrol('Units','normalized','Position',[.05 .2 .2 .08],'Style','pushbutton','String','Add video');
h.push_removevideo=uicontrol('Units','normalized','Position',[.3 .2 .2 .08],'Style','pushbutton','String','Remove video');
h.push_start=uicontrol('Units','normalized','Position',[.55 .2 .2 .08],'Style','pushbutton','String','Start');
% h.push_onedir=uicontrol('Units','normalized','Position',[.05 .2 .2 .08],'Style','pushbutton','String','Add all videos in folder');

%% Callbacks
set(h.push_addvideo,'Callback',@(uno,dos) addvideo(uno,dos,h))
set(h.push_removevideo,'Callback',@(uno,dos) removevideo(uno,dos,h))
set(h.push_start,'Callback',@(uno,dos) start(uno,dos,h))

%% Save data
datos.datosegm={};
guidata(h.fig,datos)
if nargin>=1
    datos.relaciones=relaciones;
    guidata(h.fig,datos)
    start([],[],h)
end

%% Funciones
function addvideo(uno,dos,h)

datos=guidata(h.fig);
try
    directorio=ultimodir;
catch
    directorio=[];
end
[archivo,directorio]=uigetfile('datosegm.mat','Select datosegm.mat of the video',directorio);
if directorio(end)~='\'
    directorio(end+1)='\';
end
try
    ultimodir(directorio);
catch
end
load([directorio archivo])
if ~isempty(whos('variable'))
    if isstruct(variable)
        datosegm=variable;
    else
        datosegm=load_encrypt([directorio archivo],1);
    end
end
datosegm.directorio=directorio; % Por si acaso ha cambiado la ruta
datos.datosegm{end+1}=datosegm;
guidata(h.fig,datos)
actualizalista([],[],h)

function removevideo(uno,dos,h)

datos=guidata(h.fig);
video_act=get(h.listavideos,'Value');
datos.datosegm(video_act)=[];
guidata(h.fig,datos)
actualizalista([],[],h)

function actualizalista(uno,dos,h)
datos=guidata(h.fig);
contador=0;
datos.incompatibles=false([length(datos.datosegm) length(datos.datosegm) 4]);
for c_videos=length(datos.datosegm):-1:1
    for c2_videos=1:c_videos-1
        if strcmpi(datos.datosegm{c_videos}.directorio,datos.datosegm{c2_videos}.directorio)
            msgbox(['Video ' datos.datosegm{c_videos}.directorio datos.datosegm{c_videos}.raizarchivo ' is already in the list'],'Repeated video')
            datos.datosegm(c_videos)=[];
        end
    end % c2_videos
end % c_videos
nombres=cell(1,length(datos.datosegm));
for c_videos=1:length(datos.datosegm)
%     nombres{c_videos}=[datos.datosegm{c_videos}.directorio ' (' datos.datosegm{c_videos}.raizarchivo_videos ')'];
    for c2_videos=1:c_videos-1
        % Comprobaciones de los parámetros
        if datos.datosegm{c_videos}.n_peces~=datos.datosegm{c2_videos}.n_peces
            datos.incompatibles(c_videos,c2_videos,1)=true;
        end
        if datos.datosegm{c_videos}.umbral~=datos.datosegm{c2_videos}.umbral
            datos.incompatibles(c_videos,c2_videos,2)=true;
        end
        if any(datos.datosegm{c_videos}.tam~=datos.datosegm{c2_videos}.tam)
            datos.incompatibles(c_videos,c2_videos,3)=true;
        else
            mascaraintensmed1=datos.datosegm{c_videos}.mascara_intensmed;
            if isempty(mascaraintensmed1)
                mascaraintensmed1=datos.datosegm{c_videos}.mascara;
            end
            mascaraintensmed2=datos.datosegm{c2_videos}.mascara_intensmed;
            if isempty(mascaraintensmed2)
                mascaraintensmed2=datos.datosegm{c2_videos}.mascara;
            end
            if any(mascaraintensmed1(:)~=mascaraintensmed2(:))
                datos.incompatibles(c_videos,c2_videos,4)=true;
            end
        end
    end % c2_videos
end % c_videos
descripcionerrores={'- Different number of individuals\n','- Different segmentation threshold','- Different video resolution','- Different image region for normalization of intensity'};
if any(datos.incompatibles(:))
    cadena='Warning! To relate identities, all videos must be recorded and tracked in identical conditions.\n\nThere are incompatibilities in the tracking parameters:\n';
    for c1_videos=1:length(datos.datosegm)
        for c2_videos=1:c1_videos-1
            errores_act=false(1,4);
            for tipoerror=1:4
                if datos.incompatibles(c_videos,c2_videos,tipoerror) || datos.incompatibles(c2_videos,c1_videos,tipoerror)
                    errores_act(tipoerror)=true;
                end
            end
            if any(errores_act)
                nombre1=[datos.datosegm{c1_videos}.directorio ' (' datos.datosegm{c1_videos}.raizarchivo_videos ')'];
                nombre2=[datos.datosegm{c2_videos}.directorio ' (' datos.datosegm{c2_videos}.raizarchivo_videos ')'];
                for c=length(nombre1):-1:1
                    if nombre1(c)=='\'
                        nombre1=[nombre1(1:c) '\' nombre1(c+1:end)];
                    end
                end
                for c=length(nombre2):-1:1
                    if nombre2(c)=='\'
                        nombre2=[nombre2(1:c) '\' nombre2(c+1:end)];
                    end
                end
                cadena=[cadena '\nVideos\n' nombre1 '\nand\n' nombre2 '\n'];
            end
            for tipoerror=find(errores_act)
                cadena=[cadena descripcionerrores{tipoerror}];
            end
        end
    end
    msgbox(sprintf(cadena),'Incompatible parameters')
end

set(h.listavideos,'String',nombres,'Value',1)
guidata(h.fig,datos)

function start(uno,dos,h)
datos=guidata(h.fig);
if isfield(datos,'relaciones')
    relaciones=datos.relaciones;
else
    relaciones.datosegm=datos.datosegm;
    relaciones.matrel=cell(length(datos.datosegm));
end
ahora=datestr(now,30);
archivo=['idMatcher_backup' ahora];
save(archivo,'relaciones')
n_videos=length(relaciones.datosegm);
nframes_compara=200;
for c1_videos=1:n_videos
    if isfield(relaciones.datosegm{c1_videos},'encriptar')
        refs_act=load_encrypt([relaciones.datosegm{c1_videos}.directorio 'referencias.mat'],relaciones.datosegm{c1_videos}.encriptar);
        refs{1}=refs_act.referencias;
        clear refs_act
    else
        load([relaciones.datosegm{c1_videos}.directorio 'referencias.mat'],'referencias')
        refs{1}=referencias;
        clear referencias
    end
    nframes(1)=size(refs{1}{1},4);
    for c2_videos=c1_videos+1:n_videos
        disp(['Comparing videos ' num2str(c1_videos) ' and ' num2str(c2_videos) '...'])
        if isempty(relaciones.matrel{c1_videos,c2_videos}) && isempty(relaciones.matrel{c2_videos,c1_videos})
            if isfield(relaciones.datosegm{c2_videos},'encriptar')
                refs_act=load_encrypt([relaciones.datosegm{c2_videos}.directorio 'referencias.mat'],relaciones.datosegm{c2_videos}.encriptar);
                refs{2}=refs_act.referencias;
                clear refs_act
            else
                load([relaciones.datosegm{c2_videos}.directorio 'referencias.mat'],'referencias')
                refs{2}=referencias;
                clear referencias
            end
            nframes(2)=size(refs{2}{1},4);
            [m,masframes]=max(nframes);
            menosframes=3-masframes;
            errores=cell(relaciones.datosegm{c1_videos}.n_peces);
            for c_peces=1:length(refs{menosframes})
                disp(['Individual ' num2str(c_peces)])
                [menores_act,errores(c_peces,:)]=comparamapas(refs{menosframes}{c_peces}(:,:,:,equiespaciados(nframes_compara,size(refs{menosframes}{c_peces},4))),refs{masframes});
            end
            a=[c1_videos c2_videos];
            relaciones.matrel{a(menosframes),a(masframes)}=errores2matrel(errores);
            save(archivo,'relaciones')
        end
    end % c2_videos
end % c1_videos

% Ahora reordena
n_peces=relaciones.datosegm{1}.n_peces;
n_videos=length(relaciones.datosegm);
matrel=NaN(n_peces,n_peces,n_videos,n_videos);
for c1_videos=1:n_videos
    for c2_videos=1:n_videos
        if ~isempty(relaciones.matrel{c1_videos,c2_videos})
            matrel(:,:,c1_videos,c2_videos)=relaciones.matrel{c1_videos,c2_videos}(1:n_peces,1:n_peces);
        end
    end
end
[relaciones.names,relaciones.proberror,buenos,P3_mat,P3,principal]=matrel_mat2nombres(matrel);
save(archivo,'relaciones')
% Pinta los resultados
n_refsbuenas=size(matrel,3);
figure
umbral_proberror=10^-10;
nombres=relaciones.names;
proberror=relaciones.proberror;
for c1=1:n_refsbuenas
    [s,orden1]=sort(nombres(c1,:));
    for c2=1:n_refsbuenas
        [s,orden2]=sort(nombres(c2,:));
        subplot_fill(n_refsbuenas,n_refsbuenas,(c1-1)*n_refsbuenas+c2)
        imagesc(P3(orden1,orden2,c1,c2))
        if proberror(c1)>umbral_proberror || proberror(c2)>umbral_proberror
            hold on
            plot([1 n_peces],[1 n_peces],'r','LineWidth',2)
            plot([n_peces 1],[1 n_peces],'r','LineWidth',2)
        end
    end % c2
end % c1

% Reordena las trayectorias
for c_videos=1:n_videos
    try
        load([relaciones.datosegm{c_videos}.directorio 'trajectories.mat'])
        trajectories(:,nombres(c_videos),:)=trajectories;    
        probtrajectories(:,nombres(c_videos))=probtrajectories;
        probability_of_wrong_order=proberror(c_videos);
        ahora_act=ahora;
        if proberror(c_videos)>umbral_proberror
            ahora_act=[ahora_act '_WarningHighErrorProb'];
        end
        save([relaciones.datosegm{c_videos}.directorio 'trajectories_sorted' ahora_act '.mat'],'trajectories','probtrajectories','probability_of_wrong_order')        
    catch
        disp(['Could not find trajectories for ' relaciones.datosegm{c_videos}.directorio])
    end
end

% 25-Sep-2017 20:22:32 Make it robust to not having ultimodir