function dec = obtainCrystalDec(crystalName, genericCode, flagEnforce, ...
    verbose)
% obtain decomposition of a crystal definition from database
%
% Syntax: dec = obtainCrystalDec(name, code)
%
% This function essentially does:
%   >> cdef = obtainCrystal(crystalName, genericCode);
%   >> dec = obtainDec(cdef.A, 'mapping', cdef.groupMappingMatrix);
% However, the result is stored in the data folder so that a decomposition
%   is calculated only once and loaded from disk for subsequent calls.
%
% Use obtainCrystalDec(name, code, enforce, verbose) with enforce=1 to 
%   recalculate the requested decomposition or to change the verbosity
%   level for calling obtainDec.
%
% For more details on name and code, see obtainCrystal.
%
% See also: obtainCrystal, obtainDec

% 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/>.

%% input handling
if ~exist('crystalName', 'var')
    crystalName = '';
end
if ~exist('genericCode', 'var')
    genericCode = [];
end
if ~exist('flagEnforce', 'var')
    flagEnforce = false;
end
if ~exist('verbose', 'var')
    verbose = 2;
end

%% load crystal
% load crystal
cdef = obtainCrystal(crystalName, genericCode);
% init and empty is not supported for obtainCrystal, but still has proper
%   behavior. Hence, we return warning and return
if isempty(crystalName) || strcmpi(crystalName, 'init')
    warning('elk:decomposition:crystalName', ['Initialization of crystal ' ...
        'database performed even though this function is not supported']);
    return
end
% adjust file name
if isempty(cdef.genericCode)
    fileName = [crystalName '.mat'];
else
    fileName = [crystalName '_' num2str(cdef.genericCode) '.mat'];
end

%% try to load data
if ~flagEnforce
    try
        dec = obtainData(fileName(1:end-4), ...
            'database', ['.' filesep 'data-crystal'], 'type', 'mat');
        % return, if this succeeds
        return
    catch
        % have to calculate decomposition
        flagEnforce = true;
    end
end
if flagEnforce
    dec = obtainDec(cdef.A, 'mapping', cdef.groupMappingMatrix, ...
        'verbose', verbose, 'allowFixPosition', 1);
end

%% store cdef
dec.cdef = cdef;

%% save data
save([fileparts(which('obtainCrystalDec')) filesep 'data-crystal' filesep fileName], ...
    'dec')
dump = obtainData('init', 'database', ['.' filesep 'data-crystal'], 'type', 'mat');