function [simi, simis,Interval_mids,L]=calc_similarities(signals,initial_beats,exp_bbi, plotten)
% TODO: 2-stufig machen 
% zuerst große Intervalle, dann etwas kleinere, sowie erneute
% shapes-Berechnung aus erster "stufe"

                % calc mean Shapes --------------------
                md=exp_bbi;
                anfang=round(md*2/4);
                ende=round(md*3/4);
                window=-anfang:ende;
               
                  numChan=size(signals,1);
                  ishapes=zeros(numChan, size(window,2), size(initial_beats,2)); 
                for k=1:(size(initial_beats,2))
                    ishapes(:,:,k)=signals(1:numChan,initial_beats(k)+window); % shapes of each and every single potential beat
                end

L=round(7*md); % Intervals of length L  miliSekunden
lw=2*L+1;
Interval_mids=(1+L):L:(size(signals,2)-L); % devide Signal into lots of intervals with same length
Interval_mids=[Interval_mids,size(signals,2)-L];
           if(plotten==1)     f1=figure; hold on; for k=1:numChan, plot(signals(k,:)-k*8,'Color',[0.6 0.6 0.6]); end ; color=false;end



%% mean-shape over all so far detected beats
immshape=mean(ishapes,3);
stdmshape=std(immshape,1,2);
good=stdmshape>0.5*max(stdmshape);

immshape=immshape(good,:);
ishapes=ishapes(good,:,:);
signals=signals(good,:);
numChan=size(immshape,1);

simis=zeros(numChan,size(signals,2)); 

fenster=[-round(md/3):round(md/3)];
shapes=zeros(numChan,size(fenster,2), size(initial_beats,2)); 
mloc=fenster(1,end)+1; 
 % initial alignement ------------
 % initiales Verschieben des diff-maximas, sodass es bei mloc ist
 %[maxanstieg, mimas, flanken]=calc_flanks(immshape);
for n=1:numChan
    [maxanstieg(n,1), mimas(n,1)]=max(abs(immshape(n,:)));
     if(mimas(n,1)>size(window,2)-fenster(1,end))
         mimas(n,1)=size(window,2)-fenster(1,end);
         
     elseif(mimas(n,1)+fenster(1,1)<1)
        mimas(n,1)=-fenster(1,1)+1; 
       
     end
             shapes(n,:,:)=ishapes(n,mimas(n,1)+fenster,:);
             mmshape(n,:)=immshape(n,mimas(n,1)+fenster); 
     
   initial_versatz(n,1)=mimas(n,1)-(anfang+1);   
end

% #######################################################
% #######  LOOP through Intervals #############################

for T=Interval_mids
    Interv=T+[-L:L];
    % pick out the shapes of those beats which ly within the current interval
   
    
time_diff=abs(T-initial_beats);
those=time_diff<L;
those_shapes=shapes(:,:,those); % those shapes ly within the current interval , they will be averaged !
%% exclude the ugly ones
for n=1:numChan
    mshape(n,:)=mean(those_shapes(n,:,:),3) ; 
    if(std(mshape(n,:))<std(mmshape(n,:)))
        %shapes=reshape(those_shapes(n,:,:),[size(those_shapes,3),size(those_shapes,2), 1]); 
         [mshape(n,:)]=robust_mean_shape_TH(those_shapes(n,:,:));
         if(sum(mshape(n,:),2)==0)
             mshape(n,:)=mmshape(n,:); 
         end
    end
      
end


% % % %% exclude the ugly ones 
% % % IMA=zeros(numChan, size(those_shapes,3));
% % % for n=1:numChan
% % %     for th=1:size(those_shapes,3)
% % %         shape=those_shapes(n,:,th); 
% % %         anstieg=conv(shape, [-ones(1,3),  0 , ones(1,3)],'same');
% % %         anstieg(1,1:3)=0; anstieg(1,end+(-2:0))=0;  
% % %          [maxan,  imas]=max(abs( anstieg));
% % %         if(maxan>maxanstieg(n,1))
% % %          IMA(n,th)=imas;
% % %         else
% % %             IMA(n,th)=0;
% % %         end
% % %       
% % %     end    
% % % end
% % % %% Compare the diff-maxima-indices ( IMA ) with mloc
% % % mIMA=zeros(numChan, size(IMA,2));
% % % for n=1:numChan
% % %     if(sum(IMA(n,:),2)>0)
% % %     medIMA=median(IMA(n,IMA(n,:)>0),2); 
% % %     else
% % %         medIMA=1000000;
% % %     end
% % %     
% % %     if(abs(medIMA-mloc)/mloc>0.5) % mloc zeigt auf mitte des Intervalls, da diff-maxima bereits geschoben wurde
% % %           mIMA(n,:)=mloc*ones(1,size(IMA,2));  % if too diffrent from location within mmshape, mIMA becomes mloc
% % %        
% % %     else
% % %        mIMA(n,:)=medIMA*ones(1,size(IMA,2)); % else the median
% % %     end
% % % end
% % % good=abs(IMA-mIMA)./mIMA<0.5; % good are those shapes within the current interval which dont differ to much
% % % mshape=mmshape; 
% % % for n=1:numChan
% % %     if(sum(good(n,:),2)>4)
% % %         mshape(n,:)=mean(those_shapes(n,:,good(n,:)),3);
% % %    end
% % % end
% % % stdmshape=std(mshape,1,2);
% % % good=stdmshape>0.5;
% % % good(1,1)=1==1; % JUST FOR CINC2014
% % % 
% % % if(stdmshape(1,1)<0.5)
% % %     nix=0; 
% % % end
%--------------------------------------------------------

% +++++++ calc Similarities for the current Interval +++++++++++
for n=1:numChan
  % [~,m]=max(abs(diff(mshape(n,:))));
  anstieg=abs(conv(mshape(n,:), [-ones(1,3),0,ones(1,3)],'same') );
  anstieg(1,1:3)=0; anstieg(1,end+(-2:0))=0; 
    [~,m]=max(anstieg );
    if(m<=round(md/7)||m>(size(mshape,2)-round(md/7)))
        m=-fenster(1,1);
    end
    subpatt=mshape(n,m+[-round(md/7):round(md/7)]); 
        cov=(conv2(signals(n,Interv),subpatt(1,end:-1:1),'same')); %covariance
        sig_var=conv2(signals(n,Interv).^2,ones(1,size(subpatt,2)),'same');% signal variance
        mshape_var=sum(mshape(n,:).^2,2); % shape- variance
    rel_var_diff=(sig_var-mshape_var)/mshape_var;
    b=(0.5+3*(rel_var_diff>0));
    EnKF=exp(-0.5*(rel_var_diff./b).^2); % Energie-Korrektur-Faktor
    new_simis=cov./(0.0001+sqrt(sig_var.*mshape_var)).*EnKF;
    %--- Schieben der Simi-kurve
    versatz=m+fenster(1,1)+initial_versatz(n,1); 
    if(versatz>0) % links schieben
        new_simis=[new_simis(1,(1+versatz):end),zeros(1,versatz)];
    else % rechts schieben
         new_simis=[zeros(1,-versatz), new_simis(1,1:(end+versatz))];
    end
    simis(n,Interv)=max(simis(n,Interv),new_simis);% max() wird genutzt, weil "Interv" ueberlappen, somit werden Bereiche mit geringen Werten überschrieben % Similarities !!!
end % Ende Channel-Loop

%% +++++++++++++++++++++++++++++++++++++++++++++

 %% plotten
 if(plotten==1)
 figure(f1);hold on; 
  color=double(~color);
 for k=1:numChan
    plot(Interv,simis(k,Interv)*10-10*k,'Color',[color 0 1-color]); 
   plot(T+[10*fenster(1,1):10:10*fenster(1,end)],10+mshape(k,:)-10*k,'linewidth',2);
 end
 end
end % #####              Ende - Interval -Loop            ###################
% #######################################################
simi=-0.05+1.05./(1+exp(-4*(sum(simis,1)-0.5)));

end

function [mshape]=robust_mean_shape_TH(shapes)
N=size(shapes,3); 
numGood=0; counter=0;err=zeros(1,N); 
%figure; hold on; for k=1:N,  plot(shapes(1,:,k)-k*5);end
while(numGood<round(N/2)&&counter<N)
    counter=counter+1; 
    for kk=1:N
        err(1,kk)=sum(abs(shapes(1,:,kk)-shapes(1,:,counter)),2); 
        
    end
    good=err<0.5*sum(abs(shapes(1,:,counter)),2);
    numGood=sum(good,2); 
    
end
if(counter<N)
mshape=mean(shapes(1,:,good),3); 
else
    mshape=zeros(1,size(shapes,2));
end
   
end
% % % function [maxanstieg, mimas, flanken]=calc_flanks(x) % der immshape
% % % d=diff(x,1,2); 
% % % for n=1:size(x,1)
% % %     [maxanstieg(n,1), mimas(n,1)]=max(abs(d(n,:))); 
% % %     counter=0; temp=0; 
% % %     while(d(1,mimas(n,1))*temp>=0&&counter<(size(d,2)-mimas(n,1))) % diff-Nulldurchgang zur Rechten
% % %         counter=counter+1; 
% % %         temp=d(1,mimas(n,1)+counter); 
% % %     end
% % %     rechts=mimas(n,1)+counter; 
% % %       counter=0; temp=0; 
% % %     while(d(1,mimas(n,1))*temp>=0&&counter<(mimas(n,1))) % diff-Nulldurchgang zur Linken
% % %         counter=counter+1; 
% % %         temp=d(1,mimas(n,1)-counter); 
% % %     end
% % %     links=mimas(n,1)-counter; 
% % %     flanke{1,n}=x(n,links:rechts); 
% % % end
% % % 
% % % 
% % % end

