function [reihe,uewktmat]=engagerandomize(anzahlfaktoren,stufenvec,gradientcell,wiederholungsstatus,anzahlwiederholungen,wiederholungsvec,ausschlussstatus,ausschlussmat,faktorausschlussstatus,faktorausschlussmodus,optimierungsstatus,verteilungsniveau)
%   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.                                                                      

global uewktmat reihe bestreihe bestuewktmat...
    bestdist faktorstring aktiverfaktor relmat...
    wktstatus whlstatus whlspez distmat optimierungsstatus...
    kriterium signallaenge dist meanuewktmat blockcheckstatus blockstocheck
      

%function-syntax
%-------------------
%reihe=engagerandomize(anzahlfaktoren,stufenvec,gradientcell,wiederholungsstatus,anzahlwiederholungen,wiederholungsvec,ausschlussstatus,ausschlussmat,faktorausschlussstatus,faktorausschlussmodus,optimierungsstatus,verteilungsniveau);
%reihe=engagerandomize(2,[3;3],{[30 30 30];[30 30 30]},1,-1,[],0,[],0,2,1,1);
                                                                 
if nargin>0
        if nargin<12;global verteilungsniveau;verteilungsniveau=1;end
        if nargin<11;global optimierungsstatus;optimierungsstatus=1;end
        if nargin<10;global faktorausschlussmodus;faktorausschlussmodus=2;end
		if nargin<9;global faktorausschlussstatus;faktorausschlussstatus=0;end
		if nargin<8;global ausschlussmat;ausschlussmat=[];end
		if nargin<7;global ausschlussstatus;ausschlussstatus=0;end
		if nargin<6;global wiederholungsvec;wiederholungsvec=[];end
		if nargin<5;global anzahlwiederholungen;anzahlwiederholungen=1;end
		if nargin<4;global wiederholungsstatus;wiederholungsstatus=0;end
		if nargin<3;disp('Nicht ausreichend Input-argumente!');return;end
        functionstatus = 1;
else
    
    global anzahlfaktoren stufenvec gradientcell wiederholungsstatus anzahlwiederholungen...
    wiederholungsvec ausschlussstatus ausschlussmat faktorausschlussstatus faktorausschlussmodus...
    optimierungsstatus verteilungsniveau
    functionstatus = 0;
    verteilungsniveau = 1;
    
end

%Variablen
%------------
bestdiff=100;bestreihe=[];distmat=[];kriterium=20;bestdist=1000;
punktzaehler=1;neumat=[];dist=2000;sternzaehler=1;bigpointzaehler=0;
uematzaehler=1;zwischenspeicher=[];avgzaehler=1;gradientidvec=zeros(1);
anzahlelemente=zeros(1); optimierungsstatus=1;



%Faktorausschluss
%---------------------------------------------
faktorausschlussradio=findobj('tag','faktorausschlussradio');
faktorausschlussstatus=get(faktorausschlussradio,'Value');

if isempty(faktorausschlussstatus)
    faktorausschlussstatus=0;
end
if faktorausschlussstatus == 1
    wiederholungsstatus = 0;
    anzahlwiederholungen = 1;
    wiederholungsvec=[];
end

%Optimierungsstatus
%---------------------
optimierungsradio = findobj('tag','uewktradio');
optimierungsstatus = get(optimierungsradio,'Value');
if isempty(optimierungsstatus)
    optimierungsstatus = 1;
end

%ausschlussstatus
%------------------
if isempty(ausschlussstatus)
    ausschlussstatus = 0;
end
if ausschlussstatus == 1
    if isempty(ausschlussmat)
        uiwait(errordlg('Machen Sie bitte Angaben zum Ausschluss!','Fehlende Angabe:'));
        return
    end
end

%faktorausschlussstatus 
%------------------------
if isempty(faktorausschlussstatus)
    faktorausschlussstatus = 0;
end

%wiederholungsstatus
%-------------------------
if isempty(wiederholungsstatus)
    wiederholungsstatus = 0;
end
if wiederholungsstatus == 1
    if isempty(anzahlwiederholungen) & isempty(wiederholungsvec)
        uiwait(errordlg('Machen Sie bitte Angaben zur zugelassenen Anzahl von Wiederholungen!','Fehlende Angabe:'));
        return
    else
        if ~isempty(anzahlwiederholungen)    
            if anzahlwiederholungen == 0
                wiederholungsstatus = 0;
            end
        end
    end
end

%intertrialitemstatus
%---------------------
insertintertrialitemmenuitem=findobj('tag','insertintertrialitemmenuitem');


%Kontrolldialog
%-----------------------------
if functionstatus ~= 1
    
	dlgcell=cell(1);
	dlgcell{1}='Bitte überprüfen Sie die Angaben: ';
	dlgcell{2}='';
	dlgcell{3}=['  Faktoren: ',num2str(anzahlfaktoren)];
	if wiederholungsstatus == 0
        dlgcell{4}=['  Wiederholungen zulassen: n'];
	else 
        if ~isempty(anzahlwiederholungen)
			if anzahlwiederholungen ~= -1
                dlgcell{4}=['  Wiederholungen zulassen: ',num2str(anzahlwiederholungen-1)];
			else
                dlgcell{4}=['  Wiederholungen zulassen: unbegrenzt'];
			end
        else
            dlgcell{4}=['  Wiederholungen zulassen: ',num2str(wiederholungsvec-1)];
        end
	end
	if isempty(ausschlussmat)
        dlgcell{5}='  Ausschluss: n';
	else
        dlgcell{5}=['  Ausschluss: ',whlspez,' :',num2str(ausschlussmat)];
	end
	if optimierungsstatus == 1
        dlgcell{6}=['  Übgwkten: j'];
	else
        dlgcell{6}=['  Übgwkten: n'];
	end
	if faktorausschlussstatus==1
        faktorausschlussstring = 'j';
	else
        faktorausschlussstring = 'n';
	end
	dlgcell{7}=['  Faktorausschluss: ',faktorausschlussstring];
	dlgcell{9}='';
	answer=questdlg(dlgcell,...
        'Gewählte Option:',...
        'korrekt','abbrechen','korrekt');
	if strcmp(answer,'abbrechen')
        return
	end
    
end


%---------------------------------------------------------------------------------------------------
%  Randomizer 
%---------------------------------------------------------------------------------------------------

%Nullstufen
%----------------
if ~isempty(find(stufenvec==0))
    uiwait(errordlg('Es fehlen Angaben zur Stufung der Faktoren! Null Stufen sind nicht zulässig!','Fehler:'));
    return
end

%Elementanzahl bestimmen 
%---------------------------------------------
anzahlelemente=prod(stufenvec);

%Wiederholungsvec
%------------------
if ~isempty(wiederholungsvec)
    if length(wiederholungsvec)<anzahlelemente
        uiwait(errordlg('Wiederholungsvektor muss pro Element die Anzahl der für dieses Element zugelassenen Wiederholungen enthalten!','Achtung:'));
        return
    end
end


%zaehlmat erstellen
%---------------------------------------------

cellanzahl=anzahlelemente;
zielmat=[];
stufenindices=find(stufenvec~=0);
cellhelp=[];;
for j=1:length(stufenindices),
   zielmat=[zielmat,stufenvec(j)];
end   
if isempty(zielmat)
else
  if length(zielmat)>1
            cellhelp=linspace(1,cellanzahl,cellanzahl);
            zaehlmat=reshape(cellhelp,zielmat);
  elseif length(zielmat)<2
            zaehlmat=linspace(1,cellanzahl,cellanzahl);
  end
end

%Stimulianzahl
%------------------------------------------------
if isempty(gradientcell{1})
    errordlg('Machen Sie bitte Angaben zur Stimulianzahl!','Fehler:');
    return
end


%Signallaenge
%----------------
if functionstatus==1
    signallaenge=0;
   signallaenge=signallaenge+sum(gradientcell{1});
end

%Absolute Häufigkeiten
%-----------------------
for d=1:length(gradientcell)
    if length(gradientcell{d})<stufenvec(d)
        uiwait(errordlg('Bitte machen Sie pro Faktor genau so viele Stimulianzahlangaben unter <Stimulianzahl[]:> wie Sie Stufen für diesen Faktor definiert haben! (z.B: bei 3 Stufen: 20 20 20)','Fehler:'));
        return
    end
end
abshfgktmat=calcabshfgktmat(gradientcell,signallaenge,zaehlmat,anzahlelemente);
if isempty(abshfgktmat);return;end




%DesignSchema ausgeben
%---------------------

if functionstatus ~= 1
	for i=1:size(abshfgktmat,1)
        for j=1:size(abshfgktmat,2)
            helpcell{i,j}=abshfgktmat(i,j);
        end
	end
	figurehandle = figure('tag','designplot','Name','Gewähltes Design:','NumberTitle','off','menubar','none','units','normalized','position',[0.1 0.6 0.3 0.3]);
	cellplot(helpcell);
	pause(2);
	close (figurehandle);
end



if isempty(abshfgktmat);return;end
if ~blockcheckstatus
    blockstocheck = 1;
end
    

%Optimierung  
%---------------------------------------------
reihecell = cell(blockstocheck,2);
blockcounter = 1;
blockcheckfollow = 0;
totaluewktmat = [];
meantotaluewktmat = [];
blockcheckruns = 1;
blockcheckoptimize = 0;
totalmat = zeros([anzahlelemente,anzahlelemente,blockstocheck]);
while blockcounter<=blockstocheck
    
	if optimierungsstatus==0
        
        %Reihe schreiben 
        %---------------------------------------------   
        if length(find((abshfgktmat(1)==abshfgktmat)))==prod(size(abshfgktmat))
           zaehlmat = shuffle(zaehlmat);
        end
        [reihe,uewktmat]=reiheschreiben(anzahlfaktoren,stufenvec,anzahlelemente,zaehlmat,signallaenge,...
                                            wiederholungsstatus,anzahlwiederholungen,wiederholungsvec,...
                                            ausschlussstatus,ausschlussmat,faktorausschlussstatus,abshfgktmat,...
                                            faktorausschlussmodus,0);
        if isempty(reihe)
                uiwait(errordlg('Reihe schreiben nicht erfolgreich!'));
                return 
        else     
            bestreihe = reihe;
            bestuewktmat = uewktmat;  
        end
        
        reihecell{blockcounter,1} = reihe;
        reihecell{blockcounter,2} = uewktmat;
        dist = 2000;
        if blockcounter == blockstocheck & blockcheckstatus
            for r=1:blockstocheck
                totalmat(:,:,r)=reihecell{r,2};
            end
            totaluewktmat = sum(totalmat,3)
            if blockcheckruns==1
                meantotaluewktmat = totaluewktmat
            else
                meantotaluewktmat =(( blockcheckruns-1/blockcheckruns).*(meantotaluewktmat) + (1/blockcheckruns).*totaluewktmat)./blockcheckruns
            end
            
            if ~blockcheckoptimize
                answer = questdlg('Are transition probabilities across blocks ok?','Block check:','Yes','No','Optimize','Optimize');
                if strcmp(answer,'No')
                    disp('Starting over....')
                    fprintf(1,'\n');
                    blockcounter = 1;
                    blockcheckfollow = 1;
                    blockcheckruns = blockcheckruns+1
                elseif strcmp(answer,'Optimize')
                    blockcheckoptimize = 1;
                else
                    blockcounter = blockcounter + 1;
                    blockcheckoptimize = 0;
                end
            else
                blockcheckruns = blockcheckruns +1;
            end
            if mod(blockcheckruns,10)==0
                blockcheckoptimize =0 ;
            end
        else
            blockcounter = blockcounter + 1;
        end
        
	elseif optimierungsstatus==1
        
        if blockcounter == 1 & blockcheckfollow==0
            meanuewktmat=[];
            kriterium = 0;
            nichterfolgreichzaehler=1;
            gewicht=1;
        end
        
        while dist>kriterium
            
            %Reihe schreiben 
            %---------------------------------------------
            
            if length(find((abshfgktmat(1)==abshfgktmat)))==prod(size(abshfgktmat))
                zaehlmat = shuffle(zaehlmat);
            end
            [reihe,uewktmat]=reiheschreiben(anzahlfaktoren,stufenvec,anzahlelemente,zaehlmat,signallaenge,wiederholungsstatus,...
                                            anzahlwiederholungen,wiederholungsvec,ausschlussstatus,ausschlussmat,...
                                            faktorausschlussstatus,abshfgktmat,faktorausschlussmodus,1);
            
            
            if isempty(reihe)
               nichterfolgreichzaehler=nichterfolgreichzaehler+1;
               if mod(nichterfolgreichzaehler,30)==0
                   disp('Reihe erstellen wiederholt nicht erfolgreich!')
                   %return
               end
            elseif length(reihe)==1 & reihe(1)==-1  
                %return
            end
            
            %distanz berechnen
            %---------------------
			
            if ~isempty(reihe)
                [meanuewktmat,dist]=calcdist(reihe,uewktmat,meanuewktmat,gewicht,functionstatus);
                gewicht=gewicht+1;
                if dist<bestdist
                    bestdist=dist;
                    bestreihe=reihe;
                    bestuewktmat=uewktmat;
			    end
            end
            
            %progress
            %----------------
            
			fprintf('.');
			sternzaehler=sternzaehler+1;
			if mod(sternzaehler,20)==0
                fprintf('\n');
			end
            
            %abbruch ermöglichen
            %---------------------
            
            if sternzaehler>10+40*verteilungsniveau+10
                
                if mod(sternzaehler,100)==0
                    if functionstatus ~= 1
                        
                        bestdist=bestdist
                        fprintf(['kriterium:',num2str(kriterium),'\n']);
                        bestuewktmat=bestuewktmat
                        antwort=questdlg('Randomizer: Weitersuchen?',...
                                'Optimierung:',...
                                'ja','nein','ja');
                        if strcmp(antwort,'nein')
                            
                            break
                        end
                    else
                        break
                    end
				end
            end
        end  
        
        reihecell{blockcounter,1} = reihe;
        reihecell{blockcounter,2} = uewktmat;
        dist = 2000;
        if blockcounter == blockstocheck & blockcheckstatus
            for r=1:blockstocheck
                totalmat(:,:,r)=reihecell{r,2};
            end
            totaluewktmat = sum(totalmat,3)
            if blockcheckruns==1
                meantotaluewktmat = totaluewktmat
            else
                meantotaluewktmat =(( blockcheckruns-1/blockcheckruns).*(meantotaluewktmat) + (1/blockcheckruns).*totaluewktmat)./blockcheckruns
            end
            
            if ~blockcheckoptimize
                answer = questdlg('Are transition probabilities across blocks ok?','Block check:','Yes','No','Optimize','Optimize');
                if strcmp(answer,'No')
                    disp('Starting over....')
                    fprintf(1,'\n');
                    blockcounter = 1;
                    blockcheckfollow = 1;
                    blockcheckruns = blockcheckruns+1
                elseif strcmp(answer,'Optimize')
                    blockcheckoptimize = 1;
                else
                    blockcounter = blockcounter + 1;
                    blockcheckoptimize = 0;
                end
            else
                blockcheckruns = blockcheckruns +1;
            end
            if mod(blockcheckruns,10)==0
                blockcheckoptimize =0 ;
            end
        else
            blockcounter = blockcounter + 1;
        end
	end
end

%Anzeige der Ergebnisse
%-------------------------
if functionstatus~=1
	if strcmp(get(insertintertrialitemmenuitem,'checked'),'on')
        
        reihetmp=bestreihe;
        intertrialreihe=zeros(length(reihetmp)*2,1);
        indexvec=1:2:length(intertrialreihe);
        intertrialreihe(indexvec)=-1;
        intertrialreihe(indexvec+1)=reihetmp;
        intertrialreihe=intertrialreihe;
        
		bestuewktmat=bestuewktmat
		if optimierungsstatus ==1
            kriterium
            meanuewktmat
            dist
		end
	else 
		bestreihe=bestreihe
		bestuewktmat=bestuewktmat
		if optimierungsstatus ==1
            kriterium
            meanuewktmat
            dist
		end
	end
end
%-----------------------------------------------------------
%wegschreiben
%-----------------------------------------------------------

if functionstatus ~= 1
    
	alwayswriteresultfilemenuitem = findobj('Tag','alwayswriteresultfilemenuitem');
    kriteriumsplot = findobj('tag','kriteriumsplot');
    close(kriteriumsplot);

	if  strcmp(get(alwayswriteresultfilemenuitem,'checked'),'on')
        [savefilename,savefilepath]=uiputfile('*.txt','Zieldatei benennen:');
        if isempty(findstr('.txt',savefilename))
            savefilename=[savefilename,'.txt'];
        end
        savefile=[savefilepath,savefilename];
        fid = fopen(savefile,'wt');
        fprintf(fid,'Randomizer:\n\n');
        fprintf(fid,['Reihe mit ',num2str(signallaenge),' Elementen bestehend aus ',num2str(anzahlelemente),' verschiedenen Zahlen:\n']);  
        if wiederholungsstatus==0
           fprintf(fid,'(keine Wiederholungen');
        else
            if anzahlwiederholungen==-1
                fprintf(fid,['(mit beliebiger Wiederholung']);
            elseif anzahlwiederholungen == 2
                fprintf(fid,['(1 zugelassene Wiederholung']);
            elseif anzahlwiederholungen > 2
                fprintf(fid,['(mit ',num2str(anzahlwiederholungen-1),' zugelassenen Wiederholungen']);
            end
        end
        if ausschlussstatus==1
            fprintf(fid,[', mit Ausschluss der Wiederholung der Elemente ',num2str(ausschlussmat)]);
        end
        
        if faktorausschlussstatus==1
            fprintf(fid,[', mit Faktorausschluss )\n']);
        else 
           fprintf(fid,')\n'); 
        end
        
        if blockcheckstatus
            for i=1:blockstocheck
                if strcmp(get(insertintertrialitemmenuitem,'checked'),'on')
                    
					fprintf(fid,['array <int> reihe',num2str(i),'[',num2str(signallaenge*2),']={']);
					fprintf(fid,'%i',reihecell{i,1}(1));
					fprintf(fid,',-1');
					for j=2:length(reihecell{i,1})
                        fprintf(fid,',');
                        fprintf(fid,'%i',reihecell{i,1}(j));
                        fprintf(fid,',-1');
					end
				else
                    fprintf(fid,['array <int> reihe',num2str(i),'[',num2str(signallaenge),']={']);
					fprintf(fid,'%i',reihecell{i,1}(1));
					for j=2:length(reihecell{i,1})
                        fprintf(fid,',');
                        fprintf(fid,'%i',reihecell{i,1}(j));
					end
				end
                fprintf(fid,'};\n\n');
            end
            fprintf(fid,'\n');
        else
            if strcmp(get(insertintertrialitemmenuitem,'checked'),'on')
                
				fprintf(fid,['array <int> reihe [',num2str(signallaenge*2),']={']);
				fprintf(fid,'%i',bestreihe(1));
				fprintf(fid,',-1');
				for j=2:length(bestreihe)
                    fprintf(fid,',');
                    fprintf(fid,'%i',bestreihe(j));
                    fprintf(fid,',-1');
				end
			else
                fprintf(fid,['array <int> reihe [',num2str(signallaenge),']={']);
				fprintf(fid,'%i',bestreihe(1));
				for j=2:length(bestreihe)
                    fprintf(fid,',');
                    fprintf(fid,'%i',bestreihe(j));
				end
			end
            fprintf(fid,'};\n\n');
        end

        if optimierungsstatus == 1
            fprintf(fid,'Übergangswahrscheinlichkeiten:\n\n');
            if blockcheckstatus==1
                for i=1:blockstocheck
                    for l=1:size(reihecell{i,2},1)
                        for k=1:size(reihecell{i,2},2)
                            fprintf(fid,[num2str(reihecell{i,2}(l,k)),'\t']);
                        end
                        fprintf(fid,'\n');
                    end
                    fprintf(fid,'\n\n');
                end
                fprintf(fid,'Gesamtübergangswahrscheinlichkeiten:\n\n');
                 for l=1:size(totaluewktmat,1)
                    for k=1:size(totaluewktmat,2)
                        fprintf(fid,[num2str(totaluewktmat(l,k)),'\t']);
                    end
                    fprintf(fid,'\n');
                end
                fprintf(fid,'\n\n');
                
            else
                for l=1:size(bestuewktmat,1)
                    for k=1:size(bestuewktmat,2)
                        fprintf(fid,[num2str(bestuewktmat(l,k) ),'\t']);
                    end
                    fprintf(fid,'\n');
                end
            end
        end   
        fclose(fid);
        
        
        answer = questdlg('Do you wish to view the output-file now?','File:','Yes','No','Yes');
        if strcmp(answer,'Yes')
            edit(savefile);
        end
	end
end


