function [nejreseni, celkove_reseni] = DraftAssembler(file,prah_korelace_max, prah_korelace_min, okno, reprezentace)
%Funkce pro sestavení assembly z kontigů na základě numerické reprezentace.
%Vstupem funkce jsou povinná pole: DraftAssembler(file, prah_korelace_max, prah_korelace_min, okno, reprezentace)
% file - ve formátu string, cesta k fasta souboru s kontigy
% prah_korelace_max - numerická hodnota popisující požadovanou hodnotu
% korelačního koeficientu (ideálně 0.75)
% prah_korelace_max - numerická hodnota popisující požadovanou hodnotu
% korelačního koeficientu (ideálně 0.50)
% okno - délka konců kontigů se kterými se počítá
% reprezentace - string 'kumul' nebo 'rozbal' pro reprezentaci kumulovanou
% nebo rozbalenou fází
% Výstupem je vektor nejlepšího řešení a pole celkového řešení s dosaženými
% skóre. 
% příklad volání funkce: DraftAssembler('data.fasta',0.75, 0.50, 1000, 'cumul')
%% načtení fasta souboru

[hlavicka,fasta]=fastaread(file);

N=length (fasta);
kontigy=upper(fasta); %načteni sekvenci do cell na velká písmena

clearvars -except N kontigy okno prah_korelace_max prah_korelace_min reprezentace

%% převod na numerické sekvence
% kontigy jsou celé převedeny do numerické reprezentace kumulovanou fází a
% pak je sestavena knihovna/dataset s jednotlivými konci kontigů
% (prefixy/sufixy) 


a=1+1i;c=-1-1i;g=-1+1i;t=1-1i; % vektory bazí
for i=1:N
    delka_cteni(i)=length(kontigy{1,i});
    zapis=zeros(1,delka_cteni(i),'double');
    zapis(kontigy{i}=='A')=angle(a);
    zapis(kontigy{i}=='C')=angle(c);
    zapis(kontigy{i}=='G')=angle(g);
    zapis(kontigy{i}=='T')=angle(t);
    
    if strcmp('kumul',reprezentace)
        KontigNumS{i,1}=cumsum(zapis);
    elseif strcmp('rozbal',reprezentace)
        KontigNumS{i,1}=unwrap(zapis);
    end

    % promenná numerických prekryvů
    KontigNum{1,i}=KontigNumS{i}(1:okno); % 1. řádek prefixy
    KontigNum{2,i}=KontigNumS{i}(end-okno+1:end); % 2. řádek sufixy
end



%% Hledání překryvů mezi kontigy

celkove_reseni=cell(2*N,3); % cell 1.sloupec - jednotlivé řešení , 2sl. - dosažená skóre, 3sl. - celkové abs. skóre
prom=zeros(2*N); %řada počátečních řešení
prom=ceil((1:size(prom,1))/2);  %řada počátečních řešení - řady 1.Prefix,1.Sufix,2P,2S...
skore_reseni=zeros(2*N,1);

for i=1:(2*N) %různá počáteční řešení, 2*N celkem
    %inicializace proměnných
    KontigNumX=KontigNum; %tabulka numerických sekvencí prefixů a sufixů kontigů
    poc_pozice=prom(i); %počáteční kontig=dle indexu i
    akt_pozice=poc_pozice; %aktuální=počáteční kontig
    cesta_kontigu=zeros(4,N); %1.řádek navázané kontigy,2.ř reverze, 3.ř posun, 4.ř nenavázané kontigy
    cesta_kontigu(1,1)=poc_pozice; %zápis poč. kontigu
    skore=0;    
    
    for j=1:N-1 %navazování kontigů s daným poč. řešení, od prvního po předposlední
        
        %příprava k průběžnému počítání korelačních posloupností
        XXCorelCoefSeq=cell(2,N); %proměnná pro zápis korelačních posloupnosti
        XXCorelCoefOptima=NaN(2,N,'double'); %proměnná pro zápis maxim a minim korelačních posloupnosti
        XXLag=Inf(2,N,'double'); %proměnná pro zápis zpoždění, 1. prefixy, 2ř. sufixy
        
        %volba signálů pro výpočet vzájemné kovariance/korelace v aktuálním
        %kroku
        if j==1 %první kontig
            if mod(i,2)==1 %i je liché -> beru "prefix" jako refenčni signal, dle řady 1Prefix,1Sufix,2P,2S...
                sig1REFER=KontigNumX{1,akt_pozice};
            else %i je sudé -> beru "sufix" jako refenční signal
                sig1REFER=KontigNumX{2,akt_pozice};
            end
        else %další kontigy navazuji od "sufixu" posledního navázaného
            sig1REFER=KontigNumX{2,akt_pozice};
        end
        
        %průběžný výpočet korelační posloupnosti pro aktuální kontig s
        %ostatními konci kontigů
        for b=1:N %všechny kontigy
            for a=1:2 %sufixy,prefixy
                if isnan(KontigNumX{a,b}) %pokud už je kontig zařazen (je NaN)
                    XXCorelCoefSeq{a,b}=NaN;
                    XXLag(a,b)=NaN;
                else %kontig čeká na zařazení
                    if b~=akt_pozice %nepočítám spolu konce stejného kontigu
                        sig2=KontigNumX{a,b};
                        [XXCorelCoefSeq{a,b},lag]=xcov(sig1REFER,sig2,'coeff');
%                         [XXCorelCoefSeq{a,b},lag]=xcov(sig1REFER,sig2,max_lags,'coeff');
                    end
                end
            end
        end
        
        %hledání maxima či minima korelační posloupnosti
        if j==1 %1.kontig
            if mod(i,2)==1 %i je liché -> beru "prefix" jako první refenčni signal
                
                for b=1:N
                    for a=1:2
                        if isnan(XXCorelCoefSeq{a,b})==0 %pokud není kontig zařazen (není NaN)
                            % správně min, max
                            [XXCorelCoefOptima(1,b),index1]=min(XXCorelCoefSeq{1,b});
                            XXLag(1,b)=lag(index1);
                            [XXCorelCoefOptima(2,b),index2]=max(XXCorelCoefSeq{2,b});
                            XXLag(2,b)=lag(index2);
                        end
                    end
                end
                
            else %i je sudé beru -> beru  "sufix" jako první refenčni signal
                for b=1:N
                    for a=1:2
                        if isnan(XXCorelCoefSeq{a,b})==0 %pokud není kontig zařazen (není NaN)
                            %spravně max, min
                            [XXCorelCoefOptima(1,b),index1]=max(XXCorelCoefSeq{1,b});
                            XXLag(1,b)=lag(index1);
                            [XXCorelCoefOptima(2,b),index2]=min(XXCorelCoefSeq{2,b});
                            XXLag(2,b)=lag(index2);
                        end
                    end
                end
                
            end
            
        else %další kontigy navazuji od "sufixu" posledního navázaného
            
            for b=1:N
                for a=1:2
                    if isnan(XXCorelCoefSeq{a,b})==0 %pokud není kontig zařazen (není NaN)
                        [XXCorelCoefOptima(1,b),index1]=max(XXCorelCoefSeq{1,b});
                        XXLag(1,b)=lag(index1);
                        [XXCorelCoefOptima(2,b),index2]=min(XXCorelCoefSeq{2,b});
                        XXLag(2,b)=lag(index2);                     
                    end
                end
            end
            
        end        
    
        % ukládání řešení
        if j==1 % 1. kontig
            % najdu nejlepší korelaci
            [MAX,poziceMAX]=max(max(XXCorelCoefOptima));
            [MIN,poziceMIN]=min(min(XXCorelCoefOptima));
                 
            if mod(i,2)==1 && abs(MAX)<abs(MIN) && abs(MIN)>prah_korelace_min %začínám řešení prefixem a navazuji prefix
                cesta_kontigu(1,j+1)=poziceMIN;
                cesta_kontigu(2,j)=1; %reverze
                
                cesta_kontigu(3,j)=XXLag(1,poziceMIN); %zpoždění
                akt_pozice=poziceMIN;
                skore(end+1)=MIN;
                KontigNumX{1,cesta_kontigu(1,1)}=NaN; % vymazat reverzní předřazený kontig z tabulky kontigů
                KontigNumX{2,cesta_kontigu(1,1)}=NaN; % vymazat reverzní předřazený kontig z tabulky kontigů
                                
            elseif mod(i,2)==0 && abs(MAX)>abs(MIN) && abs(MAX)>prah_korelace_max %začínám sufixem a navazuji prefix
                cesta_kontigu(1,j+1)=poziceMAX;
                
                cesta_kontigu(3,j)=XXLag(1,poziceMAX); 
                akt_pozice=poziceMAX; 
                skore(end+1)=MAX;
                KontigNumX{1,cesta_kontigu(1,1)}=NaN; % vymazat reverzní předřazený kontig z tabulky kontigů
                KontigNumX{2,cesta_kontigu(1,1)}=NaN; % vymazat reverzní předřazený kontig z tabulky kontigů
                
            elseif mod(i,2)==0 && abs(MAX)<abs(MIN) && abs(MIN)>prah_korelace_min %začínám sufixem a navazuji sufix
                cesta_kontigu(1,j+1)=poziceMIN;
                cesta_kontigu(2,j+1)=1; %reverze
                
                cesta_kontigu(3,j)=XXLag(2,poziceMIN);
                akt_pozice=poziceMIN;
                skore(end+1)=MIN;
                KontigNumX{1,cesta_kontigu(1,1)}=NaN; % vymazat reverzní předřazený kontig z tabulky kontigů
                KontigNumX{2,cesta_kontigu(1,1)}=NaN; % vymazat reverzní předřazený kontig z tabulky kontigů
                
                KontigNumX{2,cesta_kontigu(1,j+1)}=fliplr(KontigNumX{1,cesta_kontigu(1,j+1)}); %REVERZE  V TABULCE KONTIGŮ a zařadit jako sufix                
                KontigNumX{1,cesta_kontigu(1,j+1)}=NaN;
            else
                break
                
            end
        
        else % ostatní kontigy
            % najdu nejlepší korelaci
            [MAX,poziceMAX]=max(max(XXCorelCoefOptima));
            [MIN,poziceMIN]=min(min(XXCorelCoefOptima));
                       
            if abs(MAX)>abs(MIN) && abs(MAX)>prah_korelace_max %začínám sufixem a navazuji prefix
                cesta_kontigu(1,j+1)=poziceMAX;
                
                cesta_kontigu(3,j)=XXLag(1,poziceMAX);
                akt_pozice=poziceMAX;
                skore(end+1)=MAX;
                KontigNumX{1,cesta_kontigu(1,j)}=NaN; % vymazat reverzní předřazený kontig z tabulky kontigů
                KontigNumX{2,cesta_kontigu(1,j)}=NaN; % vymazat reverzní předřazený kontig z tabulky kontigů
                
            elseif abs(MAX)<abs(MIN) && abs(MIN)>prah_korelace_min %začínám sufixem a navazuji sufix
                cesta_kontigu(1,j+1)=poziceMIN;
                cesta_kontigu(2,j+1)=1;
                
                cesta_kontigu(3,j)=XXLag(2,poziceMIN);
                akt_pozice=poziceMIN;
                skore(end+1)=MIN;
                KontigNumX{1,cesta_kontigu(1,j)}=NaN; % vymazat reverzní předřazený kontig z tabulky kontigů
                KontigNumX{2,cesta_kontigu(1,j)}=NaN; % vymazat reverzní předřazený kontig z tabulky kontigů
                
                KontigNumX{2,cesta_kontigu(1,j+1)}=fliplr(KontigNumX{1,cesta_kontigu(1,j+1)}); %REVERZE  V TABULCE KONTIGŮ!!!! a zařadit jako sufix 
                KontigNumX{1,cesta_kontigu(1,j+1)}=NaN; %REVERZE  V TABULCE KONTIGŮ (tady už zbytečné)
            else
                break            
            end            
        end
    end
    % uložení řešení a finalizace
    rada = 1:N;
    missingvalues = setdiff(rada,cesta_kontigu(1,:));
    cesta_kontigu(4,1:length(missingvalues))=missingvalues;
    celkove_reseni{i,1}=cesta_kontigu;
    celkove_reseni{i,2}=skore;
    celkove_reseni{i,3}=sum(abs(skore));    
    skore_reseni(i,1)=celkove_reseni{i,3};
end



clearvars -except N kontigy okno prah_korelace_min prah_korelace_max celkove_reseni skore_reseni max_lags
%% Sestavení sekvence

%výběr nejlepšího řešení
[skoremax,indexreseni]=max(skore_reseni);
nejreseni=celkove_reseni{indexreseni,1};
nejreseni(1,:)


end