function varargout = sodaCalcObjScore(sodaPar,varargin)

%
% <a href="matlab:web(fullfile(sodaroot,'html','calcobjscore.html'),'-helpbrowser')">View HTML documentation for this function in the help browser</a>    
%

iSample = 1;
if size(varargin{1},3)>1
    % 'varargin' is 'propChildren'
    propChildren = varargin{1};
    for iCompl=1:sodaPar.nCompl
        for iOffspring = 1:sodaPar.nOffspringPerCompl

            evalResults(iSample,:) = propChildren(iOffspring,:,iCompl);
            iSample = iSample + 1;            
        end
    end
else
    % 'varargin' is 'evalResults'
    evalResults = varargin{1};
end





evalCol = sodaPar.evalCol;

nWorkers = sodaPar.ssp.nWorkers;
firstUnevalRow = find(~evalResults(:,evalCol),1,'first');
lastUnevalRow = find(~evalResults(:,evalCol),1,'last');
nUnevaluatedJobs = (lastUnevalRow-firstUnevalRow+1);
nJobsPerWorker = ceil(nUnevaluatedJobs/nWorkers);

if sodaPar.verboseOutput        
    % update the progress indicator:
    first = evalResults(firstUnevalRow,sodaPar.iterCol);
    last = evalResults(lastUnevalRow,sodaPar.iterCol);
    numChars = dispprogress(first,last);
    if uioctave
        fflush(1);
    end
end


% assign jobs to workers:
%
for iWorker = 1:nWorkers
    rStart=(iWorker-1)*nJobsPerWorker+1;
    rEnd = min([rStart+nJobsPerWorker-1,lastUnevalRow]);
    
    
    evalResultsPart = evalResults(rStart:rEnd,:);
    
    % set status to 'a': master is writing job
    sodaSspSetStatus(iWorker,'a')
    
    % write the job:
    mConstants = evalin('base','mConstants');
    mStatesNOKFInit = evalin('base','mStatesNOKFInit');
    workerInstruction = 'run';
    jobFile = fullfile(pwd,['worker',sprintf('%03d',iWorker)],'job.mat');
    save(jobFile,'evalResultsPart','sodaPar','mConstants','mStatesNOKFInit','workerInstruction')
    
    % set status to 'b': master has finished writing job/ control is passed
    % to worker:
    sodaSspSetStatus(iWorker,'b')
    
end

% wait until the workers are done:
%
timeSlotWidth = 5; % seconds
workerIsDone = repmat(false,[1,nWorkers]);
while ~all(workerIsDone)
    for iWorker=1:nWorkers
        if ~workerIsDone(iWorker)
            status = sodaSspGetStatus(iWorker);
            if strncmp(status,'d',1)
                workerIsDone(iWorker) = true;
            end
        end
    end

    while true
        tNow = datevec(now);
        tNowSec = tNow(6);
        if mod(tNowSec,2*timeSlotWidth)<timeSlotWidth
            pause(timeSlotWidth)
            break
        else
            pause(1)
        end
    end
end



% read from workers and assign evalResultsPart to the correct rows in
% evalResults:
for iWorker = 1:nWorkers

    jobFile = fullfile(pwd,['worker',sprintf('%03d',iWorker)],'job.mat');
    load(jobFile)

    rStart=(iWorker-1)*nJobsPerWorker+1;
    rEnd = min([rStart+nJobsPerWorker-1,lastUnevalRow]);
    
    evalResults(rStart:rEnd,:) = evalResultsPart;

end


% reshape end result if necessary:
iSample = 1;
if size(varargin{1},3)>1
    % 'varargin' is 'propChildren'
    for iCompl=1:sodaPar.nCompl
        for iOffspring = 1:sodaPar.nOffspringPerCompl

            propChildren(iOffspring,:,iCompl) = evalResults(iSample,:);
            iSample = iSample + 1;
            
        end
    end
    varargout{1} = propChildren;
else
    % 'varargin' is 'evalResults'
    varargout{1} = evalResults;
end



if sodaPar.verboseOutput        
    % update the progress indicator:
    disp(sprintf([repmat('\b',[1,numChars+1]),'\n']))
    if uioctave
        fflush(1);
    end
end



% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% % % % %                                                         % % % % %
% % % % %                     LOCAL FUNCTIONS                     % % % % %
% % % % %                                                         % % % % %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %




function numChars = dispprogress(first,last)

str = sprintf('\nEvaluating parameter sets %d-%d\n',first,last);
disp(str)
numChars = numel(sprintf('%s',str));


