function [outmat]=optimizerepandausschluss(target,reihe,ausschlussmat,anzahlwiederholungen,berichtstatus,forcesonderresourcenstatus)


%   optimizerepandausschluss

%   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; forcesonderresourcenstatus = 0; end
erfolg = 0;erfolgloszaehler=0;
indssort=[];
neuziehenzaehler=1;sternzaehler=1;
if nargin<5; berichtstatus=0;end
if nargin<4;anzahlwiederholungen=1;end
if nargin<3;ausschlussmat = [];end
if length(anzahlwiederholungen)>1;wiederholungsvec=anzahlwiederholungen;else wiederholungsvec=[];end
outmat=zeros(1,length(reihe));
inds=find(reihe==target);
repstatusmat=zeros(1);
targetini=target;
while erfolg == 0 
    
	%indices des targets
	%-----------------
    if ~isempty(find(repstatusmat==1))
        targetvec=shuffle(find(repstatusmat==1));
        target=targetvec(1);
    end
    
	inds=find(reihe==target);  
    indsini=inds;
    
    
    %wiederholungsvec
    %----------------
    if ~isempty(wiederholungsvec)
        anzahlwiederholungen=wiederholungsvec(target);
    end
    
	%problempos finden
	%---------------------
	problemstellenvec=[];
	problemstellenzaehler=1;
	resourcestellenvec=[];
	resourcestellenzaehler=1;
	check=[];
	diffs = diff(inds);
	for i=1:length(inds)
        diffmat=zeros(anzahlwiederholungen+(anzahlwiederholungen-2),1);
        groessediffmat = anzahlwiederholungen+(anzahlwiederholungen-2);
        if anzahlwiederholungen == 1
            if i<=length(diffs)
                diffmat=diffs(i);
            else
                diffmat=0;
            end
        end
        for j=1:anzahlwiederholungen-1
            %upper
            if i+j-1<length(diffs)
                if groessediffmat/2+j<=length(diffmat)
                    diffmat(groessediffmat/2+j)=diffs(i+j-1);
                end
            end
            %lower
            if i-j>0
                if groessediffmat/2+1-j>0
                    diffmat(groessediffmat/2+1-j)=diffs(i-j*1);
                end
            end  
        end
        evalstring='diffmat==1';
        for t=1:anzahlwiederholungen-1
            evalstring=['diff(find(',evalstring,'))==1'];
        end
        evalstring=['if ~isempty(find(',evalstring,'));',...
                'problemstellenvec(problemstellenzaehler)=i;problemstellenzaehler=problemstellenzaehler+1;end'];
        if sum(1==diffmat)>=anzahlwiederholungen-1
             warning off
             eval(evalstring);
             warning on
        end
	end
    
	%resourcenpos finden
	%--------------------
	resourcenstellenvec=[];
	indshelp=inds;
	if inds(1)~=1;indshelp=[1,indshelp];end
	if inds(end)~=length(outmat);indshelp=[indshelp,length(outmat)];end
	diffinds=diff(indshelp);
	resourcenzaehler=1;
	naechsteserie=1;
	resourcenstellen=find(diffinds>3);
    sonderresourcen=find(diffinds==3);
    for q=1:length(sonderresourcen)
        sonderresourcenstellenvec(q)=indshelp(sonderresourcen(q));
    end
	for i=1:length(resourcenstellen)
        naechsteserie = 1;
        serienabschnitte = 0;
        while naechsteserie == 1
            naechsteserie = 0;
            serienzaehler = 1;
            while serienzaehler<=anzahlwiederholungen & serienzaehler<diffinds(resourcenstellen(i))-2
                resourcenstellenvec(resourcenzaehler)=indshelp(resourcenstellen(i))+1+serienzaehler+serienabschnitte;
                resourcenzaehler=resourcenzaehler+1;
                serienzaehler = serienzaehler + 1; 
            end
            if indshelp(resourcenstellen(i))+1+serienabschnitte + serienzaehler + 1 < indshelp(resourcenstellen(i)+1)-1
                naechsteserie = 1;
                serienabschnitte=serienabschnitte + serienzaehler;
            end
        end
	end
    
    %ausschlussmat berücksichtigen
    %---------------------------
    
    if ~isempty(ausschlussmat)
        denyresourcenstellenvec=zeros(1,length(resourcenstellen));
        for y=1:length(ausschlussmat)
            for u=1:length(resourcenstellenvec)
                if reihe(resourcenstellenvec(u)-1)==ausschlussmat(y) | reihe(resourcenstellenvec(u)+1)==ausschlussmat(y) 
                    denyresourcenstellenvec(u)=1;
                end
            end
        end
    resourcenstellenvec(find(denyresourcenstellenvec==1))=[];
    end
    
    
    
	%abbruch
	%-------
	if ~isempty(problemstellenvec)
        if isempty(resourcenstellenvec) & isempty(sonderresourcen)
            othertarget=finddiffel(reihe);
            othertarget=othertarget(find(othertarget~=target));
            if length(othertarget)>1
                uiwait(errordlg('Peter hat sich geirrt! Dieser Fall kommt nicht nur bei zwei Elementen vor!','Achtung:'));
                return
            elseif isempty(othertarget)
               uiwait(errordlg('Beschränkte Wiederholung bei nur einem Element unmöglich!','Achtung:'));
               outmat=-1;
               return
           else 
               if length(find(reihe==target))==length(find(reihe==othertarget))
                   if rand>0.5
                       outmat(1:2:length(outmat)-1)=target;
                       outmat(2:2:length(outmat))=othertarget;
                   else
                       outmat(1:2:length(outmat)-1)=othertarget;
                       outmat(2:2:length(outmat))=target;
                   end
                   return
               elseif length(find(reihe==target))-length(find(reihe==othertarget))<-1
                   uiwait(errordlg('Keine Wiederholung bei angegebener Stimulianzahl unmöglich!','Achtung:'));
                   outmat=[];
                   return
               elseif length(find(reihe==target))-length(find(reihe==othertarget))<0
                   outmat(1:2:length(outmat))=othertarget;
                   outmat(2:2:length(outmat)-1)=target;
                   return
               elseif length(find(reihe==target))-length(find(reihe==othertarget))<2
                   outmat(1:2:length(outmat))=target;
                   outmat(2:2:length(outmat)-1)=othertarget;
                   return
               else
                    uiwait(errordlg('Keine Wiederholung bei angegebener Stimulianzahl unmöglich!','Achtung:'));
                   outmat=[];
                   return
               end
            end
        end
    else
        if berichtstatus ==1
            uiwait(msgbox('Alles klar in optimizerepandfaktorausschluss.m!','Gute Nachricht:'));
        end
        outmat=reihe;
        return
    end
        
	if berichtstatus == 1
		length(problemstellenvec)
		indini=inds
	end       
    
    %resourcenstellenvec mischen
    %------------------
    resourcenstellenvec=shuffle(resourcenstellenvec);
    problemstellenvec=shuffle(problemstellenvec);
    
	%problempos auf resourcenpos verteilen
	%------------------------------------
	anzahloptimierungsdurchgaenge=1;
	if berichtstatus == 1
        disp([num2str(length(problemstellenvec)),' verbleibende Problemstellen...']);
	end
	problemstellenvectmp=problemstellenvec;
    tryagain = 0;
    trysonderresourcenstatus = 0;
    
    %Optimierung
	%-----------------
	while length(problemstellenvectmp)>0
        
		indstmp=inds;
        anzahlresourcenstellen = length(resourcenstellenvec);
        anzahlproblemstellen = length(problemstellenvec);
        
        %Normale Resourcen
        %---------------------
        if anzahlresourcenstellen~=0
            if tryagain==0
                anzahlresourcenstellen = length(resourcenstellenvec);
                anzahlproblemstellen = length(problemstellenvec);
                tryagainzaehler=1;
                indstmp(problemstellenvec(tryagainzaehler))=resourcenstellenvec(tryagainzaehler);
            elseif tryagain==1
                tryagainzaehler=tryagainzaehler+1;
                if floor(tryagainzaehler/anzahlresourcenstellen)+1>anzahlproblemstellen
                    trysonderresourcenstatus = 1;
                end
                if trysonderresourcenstatus ==0
                    indstmp(problemstellenvec(floor(tryagainzaehler/anzahlresourcenstellen)+1))=resourcenstellenvec(mod(tryagainzaehler,anzahlresourcenstellen)+1)
                end 
            end
        else
           trysonderresourcenstatus = 1;
        end
       
        %Sonderresourcen
        %----------------
        if trysonderresourcenstatus == 1
            if berichtstatus == 1
                fprintf('Sonderresourcen...');
            end
            for sonderresourcenzaehler=1:length(sonderresourcen)-1
                indstmp(sonderresourcen(sonderresourcenzaehler)+1:end)=indstmp(sonderresourcen(sonderresourcenzaehler)+1:end)-1;
            end
        end
        
        indssort=sort(indstmp);
        diffs = diff(indssort);
        
		%problemposveränderung testen
		%----------------------------
		problemstellenvectmp=[];
		problemstellenzaehlertmp=1;
		for i=1:length(inds)
            diffmat=zeros(anzahlwiederholungen+(anzahlwiederholungen-2),1);
            groessediffmat = anzahlwiederholungen+(anzahlwiederholungen-2);
            if anzahlwiederholungen == 1
                if i<=length(diffs)
                    diffmat=diffs(i);
                else
                    diffmat=0;
                end
            end
            for j=1:anzahlwiederholungen-1
                %upper
                if i+j-1<length(diffs)
                    if groessediffmat/2+j<=length(diffmat)
                        diffmat(groessediffmat/2+j)=diffs(i+j-1);
                    end
                end
                %lower
                if i-j>0
                    if groessediffmat/2+1-j>0
                        diffmat(groessediffmat/2+1-j)=diffs(i-j*1);
                    end
                end  
            end
            evalstring='diffmat==1';
            for t=1:anzahlwiederholungen-1
                evalstring=['diff(find(',evalstring,'))==1'];
            end
            evalstring=['if ~isempty(find(',evalstring,'));',...
            'problemstellenvectmp(problemstellenzaehlertmp)=i;problemstellenzaehlertmp=problemstellenzaehlertmp+1;end'];
          if sum(1==diffmat)>=anzahlwiederholungen-1
                 warning off
                 eval(evalstring);
                 warning on
            end
		end
        
		%Progress
		%-------------------
		if length(problemstellenvectmp)<length(problemstellenvec) | trysonderresourcenstatus == 1
            problemstellenvec=problemstellenvectmp;
            inds=indssort;
            anzahloptimierungsdurchgaenge=anzahloptimierungsdurchgaenge+1;
            updateresourcenstatus =1;
            tryagain = 0;
            trysonderresourcenstatus = 0;
            if berichtstatus == 1
                disp([num2str(length(problemstellenvectmp)),' verbleibende Problemstellen...']);
            end
		else
            tryagain=1;
            updateresourcenstatus=0;
		end
        
        %resourcen updaten
        %-------------------
        if updateresourcenstatus==1
            
			resourcenstellenvec=[];
			indshelp=inds;
			if inds(1)~=1;indshelp=[-1,indshelp];end
			if inds(end)~=length(outmat);indshelp=[indshelp,length(outmat)+2];end
			diffinds=diff(indshelp);
			resourcenzaehler=1;
			naechsteserie=1;
			resourcenstellen=find(diffinds>3);
            sonderresourcen=find(diffinds==3);
            for q=1:length(sonderresourcen)
                sonderresourcenstellenvec(q)=indshelp(sonderresourcen(q));
            end
			for i=1:length(resourcenstellen)
                naechsteserie = 1;
                serienabschnitte = 0;
                while naechsteserie == 1
                    naechsteserie = 0;
                    serienzaehler = 1;
                    while serienzaehler<=anzahlwiederholungen & serienzaehler<diffinds(resourcenstellen(i))-2
                        resourcenstellenvec(resourcenzaehler)=indshelp(resourcenstellen(i))+1+serienzaehler+serienabschnitte;
                        resourcenzaehler=resourcenzaehler+1;
                        serienzaehler = serienzaehler + 1; 
                    end
                    if indshelp(resourcenstellen(i))+1+serienabschnitte + serienzaehler + 1 < indshelp(resourcenstellen(i)+1)-1
                        naechsteserie = 1;
                        serienabschnitte=serienabschnitte + serienzaehler;
                    end
                end
			end
        end
	end

	% indsini;
	% inds;
	
	%Fehlermeldung
	%-------------
	if length(indsini)~=length(inds)
        if berichtstatus == 1
            uiwait(errordlg('Wiedersprüchliche Längen von initialen und transformierten Indicies in <optimizerep.m>!','Achtung:'));
        end
        outmat = [];
        return
	end
    
	%reihe umschreiben
	%-----------------
    reihetmp=reihe;
	reihetmp(indsini)=[];
    
    for j=1:length(inds)
        reihetmp(end+1)=0;
        reihetmp(inds(j)+1:end)=reihetmp(inds(j):end-1);
        reihetmp(inds(j))=target;
    end
	reihe=reihetmp;
    
	%ausschluss und wiederholung überprüfen
	%-----------------------------------------
    repstatusmat=zeros(length(finddiffel(reihe)),1);
    erfolg=1;
	ausschlussindmat=[];
	if ~isempty(ausschlussmat)
        for z=1:length(ausschlussmat)
            ausschlussindmat=[ausschlussindmat,find(reihetmp==ausschlussmat(z))];
        end
        ausschlussindmat=sort(ausschlussindmat);
        if ~isempty(find(diff(ausschlussindmat)==1))
            erfolg=0;
        end
        
       
        %wiederholung
        %----------------
        for o=1:length(finddiffel(reihe))
            if isempty(wiederholungsvec)
                
                if anzahlwiederholungen == -1
                    
                elseif anzahlwiederholungen == 1
                    if ~isempty(find(diff(find(reihetmp==o))==1))
                        erfolg=0; 
                        repstatusmat(o)=1;
                    end
                elseif anzahlwiederholungen > 1
                    
                    %problempos finden
					%---------------------
                    checktarget = 0;
                    checkinds=find(reihe==target); 
					checkproblemstellenvec=[];
					checkproblemstellenzaehler=1;
					checkresourcestellenvec=[];
					checkresourcestellenzaehler=1;
					checkdiffs = diff(checkinds);
					for i=1:length(inds)
                        checkdiffmat=zeros(anzahlwiederholungen+(anzahlwiederholungen-2),1);
                        checkgroessediffmat = anzahlwiederholungen+(anzahlwiederholungen-2);
                        if anzahlwiederholungen == 1
                            if i<=length(checkdiffs)
                                checkdiffmat=diffs(i);
                            else
                                checkdiffmat=0;
                            end
                        end
                        for j=1:anzahlwiederholungen-1
                            %upper
                            if i+j-1<length(checkdiffs)
                                if checkgroessediffmat/2+j<=length(checkdiffmat)
                                    checkdiffmat(checkgroessediffmat/2+j)=checkdiffs(i+j-1);
                                end
                            end
                            %lower
                            if i-j>0
                                if checkgroessediffmat/2+1-j>0
                                    checkdiffmat(checkgroessediffmat/2+1-j)=checkdiffs(i-j*1);
                                end
                            end  
                        end
                        evalstring='checkdiffmat==1';
                        for t=1:anzahlwiederholungen-1
                            evalstring=['diff(find(',evalstring,'))==1'];
                        end
                        evalstring=['if ~isempty(find(',evalstring,'));',...
                                'checkproblemstellenvec(checkproblemstellenzaehler)=i;checkproblemstellenzaehler=checkproblemstellenzaehler+1;end'];
                        if sum(1==checkdiffmat)>=anzahlwiederholungen-1
                             warning off
                             eval(evalstring);
                             warning on
                        end
					end
                    
                    if ~isempty(checkproblemstellenvec)
                        repstatusmat(o)=1;
                        erfolg = 0;
                    end
                end
                
            elseif ~isempty(wiederholungsvec)
                
                anzahlwiederholungen = wiederholungsvec(o);
                if anzahlwiederholungen == -1
                    
                elseif anzahlwiederholungen == 1
                    if ~isempty(find(diff(find(reihetmp==o))==1))
                        erfolg=0; 
                        repstatusmat(o)=1;
                    end
                elseif anzahlwiederholungen > 1
                    
                    %problempos finden
					%---------------------
                    checktarget = 0;
                    checkinds=find(reihe==target); 
					checkproblemstellenvec=[];
					checkproblemstellenzaehler=1;
					checkresourcestellenvec=[];
					checkresourcestellenzaehler=1;
					checkdiffs = diff(checkinds);
					for i=1:length(inds)
                        checkdiffmat=zeros(anzahlwiederholungen+(anzahlwiederholungen-2),1);
                        checkgroessediffmat = anzahlwiederholungen+(anzahlwiederholungen-2);
                        if anzahlwiederholungen == 1
                            if i<=length(checkdiffs)
                                checkdiffmat=diffs(i);
                            else
                                checkdiffmat=0;
                            end
                        end
                        for j=1:anzahlwiederholungen-1
                            %upper
                            if i+j-1<length(checkdiffs)
                                if checkgroessediffmat/2+j<=length(checkdiffmat)
                                    checkdiffmat(checkgroessediffmat/2+j)=checkdiffs(i+j-1);
                                end
                            end
                            %lower
                            if i-j>0
                                if checkgroessediffmat/2+1-j>0
                                    checkdiffmat(checkgroessediffmat/2+1-j)=checkdiffs(i-j*1);
                                end
                            end  
                        end
                        evalstring='checkdiffmat==1';
                        for t=1:anzahlwiederholungen-1
                            evalstring=['diff(find(',evalstring,'))==1'];
                        end
                        evalstring=['if ~isempty(find(',evalstring,'));',...
                                'checkproblemstellenvec(checkproblemstellenzaehler)=i;checkproblemstellenzaehler=checkproblemstellenzaehler+1;end'];
                        if sum(1==checkdiffmat)>=anzahlwiederholungen-1
                             warning off
                             eval(evalstring);
                             warning on
                        end
					end
                    
                    if ~isempty(checkproblemstellenvec)
                        repstatusmat(o)=1;
                        erfolg = 0;
                    end
                end
            end
        end
    else
        %wiederholung
        %----------------
        for o=1:length(finddiffel(reihe))
            
            if isempty(wiederholungsvec)
                
                if anzahlwiederholungen == -1
                elseif anzahlwiederholungen == 1
                    if ~isempty(find(diff(find(reihetmp==o))==1))
                        repstatusmat(o)=1;
                        erfolg=0; 
                    end
                elseif anzahlwiederholungen > 1
                    
                    %problempos finden
					%---------------------
                    checktarget = 0;
                    checkinds=find(reihe==target); 
					checkproblemstellenvec=[];
					checkproblemstellenzaehler=1;
					checkresourcestellenvec=[];
					checkresourcestellenzaehler=1;
					checkdiffs = diff(checkinds);
					for i=1:length(inds)
                        checkdiffmat=zeros(anzahlwiederholungen+(anzahlwiederholungen-2),1);
                        checkgroessediffmat = anzahlwiederholungen+(anzahlwiederholungen-2);
                        if anzahlwiederholungen == 1
                            if i<=length(checkdiffs)
                                checkdiffmat=diffs(i);
                            else
                                checkdiffmat=0;
                            end
                        end
                        for j=1:anzahlwiederholungen-1
                            %upper
                            if i+j-1<length(checkdiffs)
                                if checkgroessediffmat/2+j<=length(checkdiffmat)
                                    checkdiffmat(checkgroessediffmat/2+j)=checkdiffs(i+j-1);
                                end
                            end
                            %lower
                            if i-j>0
                                if checkgroessediffmat/2+1-j>0
                                    checkdiffmat(checkgroessediffmat/2+1-j)=checkdiffs(i-j*1);
                                end
                            end  
                        end
                        evalstring='checkdiffmat==1';
                        for t=1:anzahlwiederholungen-1
                            evalstring=['diff(find(',evalstring,'))==1'];
                        end
                        
                        evalstring=['if ~isempty(find(',evalstring,'));',...
                                'checkproblemstellenvec(checkproblemstellenzaehler)=i;checkproblemstellenzaehler=checkproblemstellenzaehler+1;end'];
                        if sum(1==checkdiffmat)>=anzahlwiederholungen-1
                             warning off
                             eval(evalstring);
                             warning on
                        end
					end
                    
                    if ~isempty(checkproblemstellenvec)
                        erfolg = 0;
                        repstatusmat(o)=1;
                    end
                end
                
            elseif ~isempty(wiederholungsvec)
                
                anzahlwiederholungen = wiederholungsvec(o);
                
                if anzahlwiederholungen == -1
                elseif anzahlwiederholungen == 1
                    if ~isempty(find(diff(find(reihetmp==o))==1))
                        repstatusmat(o)=1;
                        erfolg=0; 
                    end
                elseif anzahlwiederholungen > 1
                    
                    %problempos finden
					%---------------------
                    checktarget = 0;
                    checkinds=find(reihe==target); 
					checkproblemstellenvec=[];
					checkproblemstellenzaehler=1;
					checkresourcestellenvec=[];
					checkresourcestellenzaehler=1;
					checkdiffs = diff(checkinds);
					for i=1:length(inds)
                        checkdiffmat=zeros(anzahlwiederholungen+(anzahlwiederholungen-2),1);
                        checkgroessediffmat = anzahlwiederholungen+(anzahlwiederholungen-2);
                        if anzahlwiederholungen == 1
                            if i<=length(checkdiffs)
                                checkdiffmat=diffs(i);
                            else
                                checkdiffmat=0;
                            end
                        end
                        for j=1:anzahlwiederholungen-1
                            %upper
                            if i+j-1<length(checkdiffs)
                                if checkgroessediffmat/2+j<=length(checkdiffmat)
                                    checkdiffmat(checkgroessediffmat/2+j)=checkdiffs(i+j-1);
                                end
                            end
                            %lower
                            if i-j>0
                                if checkgroessediffmat/2+1-j>0
                                    checkdiffmat(checkgroessediffmat/2+1-j)=checkdiffs(i-j*1);
                                end
                            end  
                        end
                        evalstring='checkdiffmat==1';
                        for t=1:anzahlwiederholungen-1
                            evalstring=['diff(find(',evalstring,'))==1'];
                        end
                        
                        evalstring=['if ~isempty(find(',evalstring,'));',...
                                'checkproblemstellenvec(checkproblemstellenzaehler)=i;checkproblemstellenzaehler=checkproblemstellenzaehler+1;end'];
                        if sum(1==checkdiffmat)>=anzahlwiederholungen-1
                             warning off
                             eval(evalstring);
                             warning on
                        end
					end
                    
                    if ~isempty(checkproblemstellenvec)
                        erfolg = 0;
                        repstatusmat(o)=1;
                    end
                end
            end
        end
	end
    
    
    
    %Progress
    %----------
	erfolgloszaehler=erfolgloszaehler+1;
	if mod(erfolgloszaehler,60)==0
%         answer = questdlg('optimizerepandausschluss wiederholt nicht erfolgreich! Weitersuchen?','Optimierung:','ja','nein','debug','ja');
%         if strcmp(answer,'debug')
%            dbstop if error
%            asdfadsfsaf
%         elseif strcmp(answer,'nein')
            outmat=[];
            return
            % end   
	end

end


outmat = reihetmp;
return