function executeCaseSet(caseName)
% execute a case from the database
%
% Syntax: executeCase(caseName)
%
% The case from the database folder is executed and the results are stored 
%   in the data folder for further analysis. No outpot is returned.
%
% See also: 

% The elk-library: convex geometry applied to crystallization modeling.
%   Copyright (C) 2013 Alexander Reinhold
%
% This program is free software: you can redistribute it and/or modify it 
%   under the terms of the GNU General Public License as published by the 
%   Free Software Foundation, either version 3 of the License, or (at your 
%   option) any later version.
%
% This program is distributed in the hope that it will be useful, but 
%   WITHOUT ANY WARRANTY; without even the implied warranty of 
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
%   General Public License for more details.
%
% You should have received a copy of the GNU General Public License along 
%   with this program.  If not, see <http://www.gnu.org/licenses/>.

%% parameters
toleranceDecomposition = 1e-9;
toleranceMeasure = 5e-7;
obtainDecVerbosity = 0;
validateDecVerbosity = 1;
validateMeasVerbosity = 1;
measureList = obtainMeasureList;

%% input handling
if ~exist('caseName', 'var')
    caseName = [];
end
% thats my path:
myPath = fileparts(which(mfilename));
% start time
startTime = now;

%% database handling
if isempty(caseName) || strcmpi(caseName, 'init')
    obtainData(caseName)
    return
else
    thisCaseSet = obtainData(caseName);
end

%% execute cases
for iCase = 1:length(thisCaseSet.keyVector)
    % basic case information
    result.name = thisCaseSet.name;
    result.key = thisCaseSet.keyVector(iCase);
    caseName = [thisCaseSet.name '_' num2str(thisCaseSet.keyVector(iCase))];
    
    
    % load crystal data
    tic
    result.cdef = obtainCrystal(thisCaseSet.obtainCrystalName, ...
                                thisCaseSet.keyVector(iCase));
    result.time.loadCdef = toc;
                            
    % compute decomposition
    fprintf(['Calculating decomposition for ' caseName ' ..\n']);
    result.dec = obtainDec(result.cdef.A, ...
        'mapping', result.cdef.groupMappingMatrix, ...
        'verbose', obtainDecVerbosity, ...
        'allowFixPosition', -1);
    fprintf('  done.\n');
    
    % validate decomposition
    fprintf(['Validating decomposition for ' caseName ' ..\n']);
    result.dec = validateDec(result.dec, ...
        'verbose', validateDecVerbosity, 'output', 'dec', ...
        'zerotol', toleranceDecomposition, ...
        'L1', result.dec.nS <= 20);
    if ~result.dec.validationData.result
        error(['Decomposition for ' caseName ' is NOT VALID']);
    else
        fprintf('  VALID.\n');
    end
    
    % generate measures
    for iMeas = 1:length(measureList)
        % generating measure
        fprintf(['Generating data for measure ''' measureList(iMeas).name ...
                 ''' for ' caseName ' ..\n']);
        result.dec = addMeasureDataDec(result.dec, ...
            measureList(iMeas).name, measureList(iMeas).par);
        fprintf('  done.\n');
    end
    
    % verify measures
    for iMeas = 1:length(measureList)
        % generating measure
        fprintf(['Verify measure data for ''' measureList(iMeas).name ...
                 ''', ' caseName ' ..\n']);
        tic
        result.(measureList(iMeas).name).verifyMatrix = ...
            validateMeasureDataDec(result.dec, ...
              'detailed', 1, ...
              'zerotol', toleranceMeasure, ...
              'measure', measureList(iMeas).name, ...
              'verbose', validateMeasVerbosity);
        result.validateMeasureTime = toc;
        if ~all(result.(measureList(iMeas).name).verifyMatrix(:))
            error(['Measure data ''' measureList(iMeas).name ...
                   ''' for ' caseName ' is NOT VALID.']);
        else
            fprintf('  VALID.\n');
        end
    end
    
    % measure timing
    fprintf(['Obtain measure timing data for ' caseName ' ..\n'])
    result = obtainTimingForMeasureComputation(result, measureList);
    fprintf('  done.\n');
    
    
    
    % save file
    save([myPath filesep 'data' filesep caseName '.mat'], 'result');
    % cleanup result
    result = struct;
end

% update index file
dump = obtainData('init', 'database', [myPath filesep 'data'], 'type', 'mat');

% final timing
disp(['Start: ' datestr(startTime)])
disp(['Start: ' datestr(now)])


