function writeCdefToDatabase(crystalName, cdef)
% write crystal definition to database folder
%
% Syntax: writeCdefToDatabase(crystalName, cdef)
%
% See also: editCrystal, vieCrystal, loadCrystal

% The elk-library: convex geometry applied to crystallization modeling.
%   Copyright (C) 2014 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/>.

%% ensure crystal does not exist
myPath = fileparts(which('writeCdefToDatabase'));
if exist([myPath filesep 'database' filesep crystalName '.m'], 'file')
    error('elk:crystal:wrongInput', ['The crystal definition already ' ...
        'exists in the database.']);
end

%% ensure cdef is complete
if ~exist('cdef', 'var') || isempty(cdef)
    cdef = struct();
end

if ~isfield(cdef, 'name')
    cdef.name = crystalName;end
if ~isfield(cdef, 'source')
    cdef.source = '';end
if ~isfield(cdef, 'isGeneric')
    cdef.isGeneric = 0;end
if ~isfield(cdef, 'sym')
    cdef.sym.defined = 0;end
if ~isfield(cdef, 'lat')
    cdef.lat = [];end
if ~isfield(cdef, 'millerDefined')
    cdef.millerDefined = [];end
if ~isfield(cdef, 'millerGeneric')
    cdef.millerGeneric = [];end

%% open file
fileHandle = fopen([myPath filesep 'database' filesep crystalName '.m'], 'w');
if fileHandle == -1
    error('elk:crystal:fileOpen', 'Cannot open file for writing');
end

%% write header
fprintf(fileHandle, ['function cdef = ' crystalName '()\n\n']);

fprintf(fileHandle, '%%%% common information\n');
fprintf(fileHandle, 'cdef.name = ''%s'';\n', cdef.name);
if ~isstruct(cdef.source)
    fprintf(fileHandle, 'cdef.source = ''%s'';\n', cdef.source);
else
    fieldList = fieldnames(cdef.source);
    for iField = 1:length(fieldList)
        fprintf(fileHandle, ...
            ['cdef.source.' fieldList{iField} ' = ''%s'';\n'], ...
            cdef.source.(fieldList{iField}));
    end
end
fprintf(fileHandle, '%% isGeneric is 1 when Miller indices can be choosen from cdef.millerGeneric:\n');
fprintf(fileHandle, 'cdef.isGeneric = %i;\n\n', cdef.isGeneric);

fprintf(fileHandle, '%%%% symmetry information\n');
sprintf('cdef.sym.defined = %i;\n', cdef.sym.defined);
fprintf(fileHandle, 'cdef.sym.defined = %i;\n', cdef.sym.defined);
if isfield(cdef.sym, 'system')
    fprintf(fileHandle, '%% system: %s\n', cdef.sym.system);end
if isfield(cdef.sym, 'Schoenflies')
    fprintf(fileHandle, '%% Schoenflies: %s\n', cdef.sym.Schoenflies);end
if isfield(cdef.sym, 'HermanMauguin')
    fprintf(fileHandle, '%% Herman-Mauguin: %s\n', cdef.sym.HermanMauguin);end
if isfield(cdef.sym, 'Laue')
    fprintf(fileHandle, '%% Laue: %s\n', cdef.sym.Laue);end

fprintf(fileHandle, '\n');
fprintf(fileHandle, '%%%% lattice information\n');
if ~isempty(cdef.lat)
    % enforce degree writing
    if strcmpi(cdef.lat.unit_angle, 'radian')
        angleFactor = 180/pi;
    else
        angleFactor = 1;
    end
    fprintf(fileHandle, 'cdef.lat.unit_angle = ''%s'';\n', 'degree');
    fprintf(fileHandle, 'cdef.lat.unit_length = ''%s'';\n', cdef.lat.unit_length);
    fprintf(fileHandle, 'cdef.lat.a = %.10g;\n', cdef.lat.a);
    fprintf(fileHandle, 'cdef.lat.b = %.10g;\n', cdef.lat.b);
    fprintf(fileHandle, 'cdef.lat.c = %.10g;\n', cdef.lat.c);
    fprintf(fileHandle, 'cdef.lat.alpha = %.10g;\n', angleFactor*cdef.lat.alpha);
    fprintf(fileHandle, 'cdef.lat.beta = %.10g;\n', angleFactor*cdef.lat.beta);
    fprintf(fileHandle, 'cdef.lat.gamma = %.10g;\n', angleFactor*cdef.lat.gamma);
else
    fprintf(fileHandle, 'cdef.lat.unit_angle = ''%s'';\n', 'degree');
    fprintf(fileHandle, 'cdef.lat.unit_length = ''%s'';\n', 'angstroem');
    fprintf(fileHandle, 'cdef.lat.a     = %.10g;\n', 1);
    fprintf(fileHandle, 'cdef.lat.b     = %.10g;\n', 1);
    fprintf(fileHandle, 'cdef.lat.c     = %.10g;\n', 1);
    fprintf(fileHandle, 'cdef.lat.alpha = %.10g;\n', 90);
    fprintf(fileHandle, 'cdef.lat.beta  = %.10g;\n', 90);
    fprintf(fileHandle, 'cdef.lat.gamma = %.10g;\n', 90);
end

fprintf(fileHandle, '\n');
fprintf(fileHandle, '%%%% Miller indices\n');

fprintf(fileHandle, 'cdef.millerDefined = [');
for iRow = 1:size(cdef.millerDefined, 1)
    % set pre string
    if iRow == 1
        pre = '';
    else
        pre = '                      ';
    end
    % set post
    if iRow == size(cdef.millerDefined, 1)
        post = '];\n';
    else
        post = '; ...\n';
    end
    % write line
    fprintf(fileHandle, [pre '%g, %g, %g' post]', ...
        cdef.millerDefined(iRow, 1), ...
        cdef.millerDefined(iRow, 2), ...
        cdef.millerDefined(iRow, 3));
end
if size(cdef.millerDefined, 1) == 0
    fprintf(fileHandle, '];\n');end

if ~isempty(cdef.millerGeneric)
fprintf(fileHandle, 'cdef.millerGeneric = [');
for iRow = 1:size(cdef.millerGeneric, 1)
    % set pre string
    if iRow == 1
        pre = '';
    else
        pre = '                      ';
    end
    % set post
    if iRow == size(cdef.millerGeneric, 1)
        post = '];\n';
    else
        post = '; ...\n';
    end
    % write line
    fprintf(fileHandle, [pre '%g, %g, %g' post]', ...
        cdef.millerGeneric(iRow, 1), ...
        cdef.millerGeneric(iRow, 2), ...
        cdef.millerGeneric(iRow, 3));
end
end

%% close file
fclose(fileHandle);
dump = obtainCrystal('init');
