function [outmat]=mergemat(mat1,mat2,ausschlussmat,wiederholungsstatus,anzahlwiederholungen,berichtstatus)

%   mergemat


%   This software is protected by german copyright and international treaties.             
%   Copyright 2004 Markus Junghöfer & Peter Peyk. All Rights Reserved.                     
%                                                                                          
%   THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE        
%   NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO,    
%   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE    
%   OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS,
%   TRADEMARKS OR OTHER RIGHTS. COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT,       
%   INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE      
%   OR DOCUMENTATION.                                                                      

if nargin<6;berichtstatus=0;end
if nargin<5;anzahlwiederholungen=-1;end
if nargin<4;wiederholungsstatus = 1;end
if nargin<3;ausschlussmat = [];end
neuziehenzaehler=1;
sternzaehler=1;
els1=finddiffel(mat1);
els2=finddiffel(mat2);
if size(mat1,1)>size(mat1,2); mat1=mat1';end
if size(mat2,1)>size(mat2,2); mat2=mat2';end
auffuellzaehler=length(mat1);
outmat=zeros(1,length(mat1)+length(mat2));

%ausschluss irrelevant
%----------------------
if isempty(mengenund(els1,ausschlussmat))
    durchgangzaehler=1;
    while 1
        mat1indices=findindforrep(mat1,mat2,outmat,anzahlwiederholungen,0);
        if ~isempty(mat1indices) & isempty(find(finddiffel(mat1indices,1)>1))
            break
        end
        durchgangzaehler=durchgangzaehler+1;
        if mod(durchgangzaehler,10)==0
            if berichtstatus == 1               
                answer = questdlg('Findindforrep wiederholt nicht erfolgreich. Weiter?','Achtung:','ja','nein','debug','nein');
                if strcmp(answer,'debug')
                    dbstop if error
                    asdfadsf
                elseif strcmp(answer,'nein')
                    outmat = [];
                    return
                end
            else
                outmat = [];
                return
            end
        end
    end
    
    outmat(mat1indices)=mat1;
    mat2indices=mengenminus(linspace(1,length(outmat),length(outmat)),mat1indices);
    outmat(mat2indices)=mat2;
    
%ausschluss relevant
%----------------------
else
    while 1
			ausschlussindices=[];
			umrahmungindices=[];
            %outmat erstellen
            outmat=zeros(1,length(mat1)+length(mat2));
            
            if wiederholungsstatus == 0
                if length(mat1)>length(outmat)/2
                    uiwait(errordlg('Mergen ohne Wiederholung nicht möglich!','Fehler in mergemat:'));
                    return
                else
                    durchgangzaehler=1;
                    while 1
                        mat1indices=findindforrep(mat1,mat2,outmat,1,0);
                        if ~isempty(mat1indices) & isempty(find(finddiffel(mat1indices,1)>1))
                            break
                        end
                        durchgangzaehler=durchgangzaehler+1;
                        if mod(durchgangzaehler,200)==0
                            if berichtstatus == 1
                                answer = questdlg('Findindforrep wiederholt nicht erfolgreich. Weiter?','mergemat:','ja','nein','debug','nein');
                                if strcmp(answer,'debug')
                                    dbstop if error
                                    asdfadsf
                                elseif strcmp(answer,'nein')
                                    outmat = [];
                                    return
                                end
                            else
                                outmat = [];
                                return
                            end
                        end
                    end 
                    mat2indices=mengenminus(linspace(1,length(outmat),length(outmat)),mat1indices);
                    outmat(mat2indices)=mat2;
                end
                    
            elseif wiederholungsstatus == 1
                if anzahlwiederholungen == -1
                    %mat2 auf outmat verteilen
                    indices=randperm(length(outmat));
                    mat2indices=find(indices<=length(mat2));
			        outmat(1,mat2indices)=shuffle(mat2);
                    %verbliebene indices
                    mat1indices=find(indices>length(mat2));
                else
                    if length(mat1)/length(outmat)>(anzahlwiederholungen+1)/(anzahlwiederholungen+2)
                        uiwait(errordlg('Mergen mit angegebene Anzahl zugelassener Wiederholungen nicht möglich!','Fehler in mergemat:'));
                        return
                    else
                        durchgangzaehler=1;
                        while 1
                            mat1indices=findindforrep(mat1,mat2,outmat,anzahlwiederholungen,0);
                            if ~isempty(mat1indices) & isempty(find(finddiffel(mat1indices,1)>1))
                                break
                            end
                            durchgangzaehler=durchgangzaehler+1;
                            if mod(durchgangzaehler,200)==0
                                if berichtstatus == 1
                                    answer = questdlg('Findindforrep wiederholt nicht erfolgreich. Weiter?','Achtung:','ja','nein','debug','nein');
                                    if strcmp(answer,'debug')
                                        dbstop if error
                                        asdfadsf
                                    elseif strcmp(answer,'nein')
                                        outmat = [];
                                        return
                                    end
                                else
                                    outmat = [];
                                    return
                                end
                            end
                        end 
                        mat2indices=mengenminus(linspace(1,length(outmat),length(outmat)),mat1indices);
                        outmat(mat2indices)=mat2;
                    end
                end
            end
            
            ausschlussindices_outmat=[];
            %indices von ausschlusselementen
            for t=1:length(ausschlussmat)
                ausschlussindices_outmat=mengenoder(ausschlussindices_outmat,find(outmat==ausschlussmat(t)));
            end
            %umrahmende positionen
            umrahmungsindices=mengenoder(ausschlussindices_outmat+1,ausschlussindices_outmat-1);
            %safe-positionen für ausschlusselement
            safepositionen=mengenminus(mat1indices,umrahmungsindices);
            %unsafe-positionen für ausschlusselemente
            unsafepositionen=mengenminus(mat1indices,safepositionen);
            %auszuschließende elemente in mat1 finden
            ausschlussindices_mat1=[];
            for t=1:length(ausschlussmat)
                ausschlussindices_mat1=mengenoder(ausschlussindices_mat1,find(mat1==ausschlussmat(t)));
            end
            %ausschlusselemente in mat1
            ausschlusselemente_mat1=mat1(ausschlussindices_mat1);
            %restelemente in mat1
            restelemente_mat1=mat1(mengenminus(linspace(1,length(mat1),length(mat1)),ausschlussindices_mat1));
           
            %progress
            %------------------
            if berichtstatus == 1
                fprintf(['Anzahl ausschlussrelevanter Elemente in mat1:',num2str(length(ausschlusselemente_mat1)),'\n']);
                fprintf(['Anzahl sicherer Positionen:',num2str(length(safepositionen)),'\n']);
                pause(0.0005)
            end
            if length(ausschlusselemente_mat1)>length(safepositionen)
                neuziehenzaehler=neuziehenzaehler+1;
                if mod(neuziehenzaehler,10)==0
                    fprintf('.');
                end
                if mod(neuziehenzaehler,50)==0
                    answer=questdlg('Mergemat unter gegebenem Ausschluss schwierig wenn nicht unmöglich! Weitersuchen?',...
                    'Achtung:',...
                    'ja','nein','debug','nein');
                    if strcmp(answer,'debug')
                        mat1
                        mat2
                        ausschlussmat
                        dbstop if error
                        awerwerwasdfa
                    elseif strcmp(answer,'nein')
                        outmat=[];
                        return
                    end
                    fprintf('\n');
                end
            else
                neuziehenzaehler=1;
                break
            end
    end
    
    %auffüllen
    %------------
    unsafezaehler=1;
    restzaehler=1;
    for x=1:auffuellzaehler
        if x<=length(ausschlusselemente_mat1)
            outmat(safepositionen(x))=ausschlusselemente_mat1(x);
        elseif x <= length(safepositionen)
           outmat(safepositionen(x))=restelemente_mat1(restzaehler);
           restzaehler=restzaehler+1;
        else
           outmat(unsafepositionen(unsafezaehler))=mat1(restzaehler);
           restzaehler=restzaehler+1;
           unsafezaehler=unsafezaehler+1;
        end
    end
end

%bericht
%------------
if berichtstatus==1    
	els_outmat=finddiffel(outmat)';
	fprintf(['Elemente: ',num2str(els_outmat),'\n']);
	for u=1:length(els_outmat)
	fprintf(['Anzahl ',num2str(els_outmat(u)),': ',num2str(sum(outmat==els_outmat(u))),'\n']);
	end
end

return

