function [sortedAngle,closingInfo,closingAngle] = CarSort(detectAngleFront,detectAngleLeftFront,detectAngleLeftback,detectAngleRightFront,detectAngleRightBack,detectAngleback) %
 %třídění vozidel dle nejmenší odchylky horizontálního uhlů
storeVal=15;
maxCar=20;
maxClosing=5;
persistent existCar  
    if isempty(existCar)
        existCar = cell(1, maxCar); 
        for i = 1:maxCar
            existCar{1,i} = zeros(storeVal,4); %[1.hor.° 2.vert.° 3.hor.diff.° 4.vert.diff.°] 
        end 
    end

persistent closingCar  
    if isempty(closingCar)
        closingCar=cell(1,maxClosing);
        for i = 1:maxClosing
            closingCar {1,i}=  zeros(storeVal,5);
        end
    end

 %% spojení kamer + přiřazení čísel kamerám
%číslování pro odstranění z kamery na kameru
AngleFront=zeros(size(detectAngleFront,1),7);
AngleFront(:,1:6)=detectAngleFront(:,:);
AngleFront = AngleFront(any(AngleFront,2),:); %odstranění prázdných řádků
AngleFront(:,7)=1;

AngleRightFront=zeros(size(detectAngleRightFront,1),7);
AngleRightFront(:,1:6)=detectAngleRightFront(:,:);
AngleRightFront = AngleRightFront(any(AngleRightFront,2),:);
AngleRightFront(:,7)=2;

AngleRightBack=zeros(size(detectAngleRightBack,1),7);
AngleRightBack(:,1:6)=detectAngleRightBack(:,:);
AngleRightBack = AngleRightBack(any(AngleRightBack,2),:);
AngleRightBack(:,7)=3;

Angleback=zeros(size(detectAngleback,1),7);
Angleback(:,1:6)=detectAngleback(:,:);
Angleback = Angleback(any(Angleback,2),:);
Angleback(:,7)=4;

AngleLeftback=zeros(size(detectAngleLeftback,1),7);
AngleLeftback(:,1:6)=detectAngleLeftback(:,:);
AngleLeftback = AngleLeftback(any(AngleLeftback,2),:);
AngleLeftback(:,7)=5;

AngleLeftFront=zeros(size(detectAngleLeftFront,1),7);
AngleLeftFront(:,1:6)=detectAngleLeftFront(:,:);
AngleLeftFront = AngleLeftFront(any(AngleLeftFront,2),:); 
AngleLeftFront(:,7)=6;


preDetAngles = AngleFront;
preDetAngles = [preDetAngles;AngleRightFront];
preDetAngles = [preDetAngles;AngleRightBack];
preDetAngles = [preDetAngles;Angleback];

preDetAngles = [preDetAngles;AngleLeftback];
preDetAngles = [preDetAngles;AngleLeftFront];

%% spojení auta projíždějícího z kamery do kamery do jednoho pomocí kraju boundary boxu
if size(preDetAngles,2)>=2
    for i = 1 : size(preDetAngles,1)-1
        for j = i+1 : size(preDetAngles,1)
            if (preDetAngles(i,6) > 1870 && ...
                    preDetAngles(j,5) < 50 && ...
                    not(preDetAngles(i,7)==0) && ...
                    ((preDetAngles(i,7)==(preDetAngles(j,7)-1)) || ...
                    (preDetAngles(i,7)==6 && preDetAngles(j,7)==1)))
                %ošetření po směru
                preDetAngles(i,1) = (preDetAngles(i,1)+preDetAngles(j,1))/2;
                preDetAngles(i,2) = (preDetAngles(i,2)+preDetAngles(j,2))/2;
                preDetAngles(i,3) = preDetAngles(i,3)+preDetAngles(j,3);
                preDetAngles(i,4) = (preDetAngles(i,4)+preDetAngles(j,4))/2;
    
                preDetAngles(j,:) = 0;
                break 
            elseif (preDetAngles(i,5) < 50 && ...
                    preDetAngles(j,6) > 1870 && ...
                    not(preDetAngles(i,7)==0) && ...
                    (preDetAngles(i,7)==(preDetAngles(j,7)+1) || ...  
                    (preDetAngles(i,7)==1 && preDetAngles(j,7)==6)))
                %ošetření proti směru
                preDetAngles(i,1) = (preDetAngles(i,1)+preDetAngles(j,1))/2;
                preDetAngles(i,2) = (preDetAngles(i,2)+preDetAngles(i,2))/2; 
                preDetAngles(i,3) = preDetAngles(i,3)+preDetAngles(j,3);
                preDetAngles(i,4) = (preDetAngles(i,4)+preDetAngles(j,4))/2;
    
                preDetAngles(j,:) = 0;
                break
            else
                continue
            end
        end
    end

    %odstranění nepotřebných a vynulovaných hodnot
    preDetAngles = preDetAngles(any(preDetAngles,2),:); 
    data = preDetAngles(:,1:4);
end
%% car sorting
     %přirazování podle minimálního rozdílu v hor. úhlu

%nalezení prvního prázného
firstZeroExistCar = 1;
for i = 1:size(existCar, 2) 
    if mean(existCar{1,i},'all') == 0 % porovnání průměru matice s nulou 
        firstZeroExistCar = i; % uložení indexu sloupce
        break; 
    end
end

firstZeroClosing = 1;
for i = 1:size(closingCar, 2) 
    if mean(closingCar{1,i},'all') == 0 % porovnání průměru matice s nulou 
        firstZeroClosing = i; % uložení indexu sloupce
        break; 
    end
end

previousData=zeros(firstZeroExistCar-1,1);
minDiff=zeros(firstZeroExistCar-1,1);
rowOn=zeros(firstZeroExistCar-1,1);

closingInfo=zeros(20,4); 

%získání hodnot pro třídění
for i = 1:firstZeroExistCar-1
  % pro více než 10 hodnot proveď predikci pro zbytek minulá hodnota
     if size(existCar{1,i}(any(existCar{1,i}(:,1),2),1),1) > 10
          previousData(i,1) = carPrediction.PredictAngleFromMat(existCar{1,i}(:,1));
     else
          previousData(i,1) = existCar{1,i}(1,1);
     end

     if isnan(previousData(i,1))
         previousData(i,1)=existCar{1,i}(1,1);
     end
end

valForClosing=1;

if size(data,1) < size(previousData,1) %_______méně aut______
    %spočítej pro každé auto minDiff a na jakém řádku je
    for i=1:size(previousData,1) 
        if isempty(data) && any(previousData,"all")
            difference=1;
        else
            difference = abs(data(:,1) - previousData(i,1));
        end
        if any(previousData,"all")
            [minDiff(i,1), rowOn(i,1)] = min(difference);
        end
    end 

    % pro auta navíc vlož do closing a vymaž
    for i = 1:(size(previousData,1) - size(data,1)) 
        [~, rowDel] = max(minDiff); 
        
        %pokud má více jak 10 hodnot ulož
        if size(existCar{1,rowDel}(any(existCar{1,rowDel},2),1),1) > 10
            closingCar{1,firstZeroClosing}(:,1:4)=existCar{1,rowDel}(:,1:4);%ulož do closing
            
            closingInfo(valForClosing,1)=rowDel;

            firstZeroClosing=firstZeroClosing+1; % pro více aut posuň dál nulu
            valForClosing=valForClosing+1;
        else
            %nezapisuj a pošli info o přímem mazaní
            closingInfo(valForClosing,4)=rowDel;
            valForClosing=valForClosing+1;
        end
        %vymaž z existujicích
        for j = rowDel:(maxCar-1)
             existCar{1,j} = existCar{1,j+1};
        end
        existCar{1,maxCar}=zeros(storeVal,4); 

        firstZeroExistCar=firstZeroExistCar-1;

        minDiff(rowDel,1)=0;
        minDiff(rowDel:end,1)= circshift(minDiff(rowDel:end,1), [-1, 0]);
        minDiff=minDiff(1:firstZeroExistCar-1,1);

        previousData(rowDel,1)=0;
        previousData(rowDel:end,1)= circshift(previousData(rowDel:end,1), [-1, 0]);
        previousData=previousData(1:firstZeroExistCar-1,1);

        rowOn(rowDel,1)=0;
        rowOn(rowDel:end,1)= circshift(rowOn(rowDel:end,1), [-1, 0]);
        rowOn=rowOn(1:firstZeroExistCar-1,1);
    end
    status=2;

elseif size(data,1) > size(previousData,1)  %__více aut__
    minDiff=zeros(size(data,1),1);
    rowOn=zeros(size(data,1),1);
    %spočítej pro každé auto minDiff a na jakém řádku je
    for i=1:size(data,1)
        if any(data,"all") && isempty(previousData)
            difference=1;
        else
            difference = abs(data(i,1) - previousData(:,1));
        end

        if any(data,"all")
            [minDiff(i,1), rowOn(i,1)] = min(difference);
        end
    end 
    % pro počet aut navíc, najdi největší rozdíl == nové auto + zmizelé
    for i=1:(size(data,1) - size(previousData,1))
        
        [~, rowNew] = max(minDiff); 
        
        rowOn(rowNew,1)=firstZeroExistCar;
        minDiff(rowNew,1)= 0;

        %kontrola zda není v closing
        if firstZeroClosing > 1
            for j=1:firstZeroClosing-1
                if (closingCar{1,j}(1,1) < data(rowNew,1)+5) && (closingCar{1,j}(1,1) > data(rowNew,1)-5)
                    %je to auto z closing + dej ho na poslední místo
                    existCar{1,firstZeroExistCar}(:,1:4)=closingCar{1,j}(:,1:4);

                    %smazat v closing
                    for c = j:(maxClosing-1)
                         closingCar{1,c} =  closingCar{1,c+1};
                    end
                    closingCar{1,maxClosing}=zeros(storeVal,5);

                    closingInfo(valForClosing,2)=j;
                    closingInfo(valForClosing,3)=firstZeroExistCar;

                    valForClosing=valForClosing+1;
                    firstZeroClosing=firstZeroClosing-1;
                    break
                end
            end
        end

        firstZeroExistCar=firstZeroExistCar+1;
    end
    status=3;

else %___________________________stejný počet aut____________________
    for i=1:size(data,1)
        difference = abs(data(i,1) - previousData(:,1));
        if any(difference,"all")
            [minDiff(i,1), rowOn(i,1)] = min(difference);
        end
        if minDiff(i,1)>20
            %pokud je rozdíl uhlu větší než 20 je to nové 
              %pokud má více jak 10 hodnot ulož do closing
            if size(existCar{1,rowOn(i,1)}(any(existCar{1,rowOn(i,1)},2),1),1) > 10
                closingCar{1,firstZeroClosing}(:,1:4)=existCar{1,rowOn(i,1)}(:,1:4);
                
                closingInfo(valForClosing,1)=rowOn(i,1);                
    
                firstZeroClosing=firstZeroClosing+1; % pro více aut posuň dál nulu
                valForClosing=valForClosing+1;
            else
                %nezapisuj a pošli info o přímem mazaní
                closingInfo(valForClosing,4)=rowOn(i,1);
                valForClosing=valForClosing+1;
            end
            
            for j = rowOn(i,1):(maxCar-1)
                 existCar{1,j} = existCar{1,j+1};
            end
            existCar{1,maxCar}=zeros(storeVal,4); %vymaž z existujicích
        end
    end  
    status=3;
end

 %% smyčka closingCar
 if firstZeroClosing > 1
    i=1;
    while i <= (firstZeroClosing-1)
        %pro včechny zmizelé vytvoř predikci
        closingCar{1,i}(1,5)=closingCar{1,i}(2,5)+1;
        if closingCar{1,i}(1,5) > 5
            for c = i:(maxClosing-1)
                 closingCar{1,c} =  closingCar{1,c+1};
            end
            closingCar{1,maxClosing}=zeros(storeVal,5);
            valForClosing=valForClosing+1;
            firstZeroClosing=firstZeroClosing-1; 
        else
            predictAngle= carPrediction.PredictAngleFromMat(closingCar{1,i}(:,1)); 
            closingCar{1,i}= circshift(closingCar{1,i}, [1, 0]);
            closingCar{1,i}(1,:)=closingCar{1,i}(2,:); %zkopíruj všechny hodnoty do 1. řádku
            closingCar{1,i}(1,1)=predictAngle; %přepiš uhel v 1. řádku 1. sloupci predikcí
            i=i+1;
        end
    end
 end
%% zápis
sortedAngle=zeros(firstZeroExistCar-1,4); 

switch status
    case 2
        sortedAngle = data(rowOn,:);%ouput
        for i = 1:firstZeroExistCar-1 
            existCar{1,i}= circshift(existCar{1,i}, [1, 0]);
            existCar{1,i}(1,:)= data(rowOn(i,1),:); %zapis nových hodnot
        end
    case 3
        sortedAngle(rowOn,:) = data;%ouput
        for i = 1:firstZeroExistCar-1 
            existCar{1,rowOn(i,1)}= circshift(existCar{1,rowOn(i,1)}, [1, 0]);
            existCar{1,rowOn(i,1)}(1,:) = data(i,:); %zapis nových hodnot
        end
end

closingAngle=zeros(firstZeroClosing-1,1);
 if firstZeroClosing > 1
    for i = 1: firstZeroClosing-1
        closingAngle(i,1)=closingCar{1,i}(1,1); %ouput
    end
 end

%výstupy: sortedAngle 
%closinginfo[toCloseRow rowInClosed toExistRow deleteRow]

closingInfo=closingInfo(any(closingInfo,2),:);
end