function [newcfg,sd]=rbmeshprep(cfg)
%
% newcfg=rbmeshprep(cfg)
%
% Compute all missing fields from the cfg input sturcture to get 
% ready for forward and inverse modeling
%
% author: Qianqian Fang (q.fang <at> neu.edu)
%
% input:
%     cfg: the initial simulation data structure
%
% output:
%     newcfg: the updated simulation data structure after adding all missing fields
%
% license:
%     GPL version 3, see LICENSE_GPLv3.txt files for details 
%
% -- this function is part of Redbird-m toolbox
%

if(~isfield(cfg,'node') || ~isfield(cfg,'elem'))
    error('cfg.node or cfg.elem is missing');
end

cfg.elem(:,1:4)=meshreorient(cfg.node(:,1:3),cfg.elem(:,1:4));

if((~isfield(cfg,'seg') ||isempty(cfg.seg)) && size(cfg.elem,2)>4)
    cfg.seg=cfg.elem(:,5);
    cfg.elem(:,5)=[];
end
if(~isfield(cfg,'isreoriented') || isempty(cfg.isreoriented) || cfg.isreoriented==0)
    cfg.elem=meshreorient(cfg.node,cfg.elem(:,1:4));
    cfg.isreoriented=1;
end
if(~isfield(cfg,'face') || isempty(cfg.face))
    cfg.face=volface(cfg.elem);
end
if(~isfield(cfg,'area') || isempty(cfg.area))
    cfg.area=elemvolume(cfg.node,cfg.face);
end
if(~isfield(cfg,'evol') || isempty(cfg.evol))
    cfg.evol=elemvolume(cfg.node,cfg.elem);
end
if(~isfield(cfg,'nvol') || isempty(cfg.nvol))
    cfg.nvol=nodevolume(cfg.node,cfg.elem, cfg.evol);
end
if(find(cfg.evol==0))
    fprintf(1,['degenerated elements are detected: [' sprintf('%d ',find(cfg.evol==0)) ']\n']);
    error(['input mesh can not contain degenerated elements, ' ...
        'please double check your input mesh; if you use a ' ...
        'widefield source, please rerun mmcsrcdomain and setting ' ...
        '''Expansion'' option to a larger value (default is 1)']);
end
if(~isfield(cfg,'srcpos'))
    error('cfg.srcpos field is missing');
end
if(~isfield(cfg,'srcdir'))
    error('cfg.srcdir field is missing');
end
if(isfield(cfg,'prop') && isfield(cfg,'param') && ...
        isa(cfg.prop,'containers.Map'))
    wv=cfg.prop.keys;
    if(~isempty(wv))
        cfg.prop=rbupdateprop(cfg);
    end
end
% compute R_eff - effective reflection coeff, and musp0 - background mus'
if(~isfield(cfg,'reff') || isempty(cfg.reff))
    bkprop=rbgetbulk(cfg);
    if(isa(bkprop,'containers.Map'))
        cfg.reff=containers.Map();
        cfg.musp0=containers.Map();
        for waveid=bkprop.keys
            wv=waveid{1};
            prop=bkprop(wv);
            cfg.reff(wv)=rbgetreff(prop(4), 1);
            cfg.musp0(wv)=prop(2)*(1-prop(3));
        end
    else
        cfg.reff=rbgetreff(bkprop(4), 1);
        cfg.musp0=bkprop(2)*(1-bkprop(3));
    end
end
if (((isfield(cfg,'srctype') && ~ismember(cfg.srctype,{'pencil','isotropic'})) || isfield(cfg,'widesrcid')) && ~isfield(cfg,'widesrc'))
    cfg.srcpos0=cfg.srcpos;
%     cfg.srcpos=rbsrc2bc(cfg);
    cfg = rbsrc2bc(cfg);
end
if (((isfield(cfg,'dettype') && ~ismember(cfg.dettype,{'pencil','isotropic'})) || isfield(cfg,'widedetid')) && ~isfield(cfg,'widedet'))
    cfg.detpos0=cfg.detpos;
%     cfg.detpos=rbsrc2bc(cfg,1);
    cfg = rbsrc2bc(cfg,1);
end
if(~isfield(cfg,'cols') || isempty(cfg.cols))
    [cfg.rows,cfg.cols,cfg.idxcount]=rbfemnz(cfg.elem,size(cfg.node,1));
end

if(~isfield(cfg,'idxsum') || isempty(cfg.idxsum))
    cfg.idxsum=cumsum(cfg.idxcount);
end

if(~isfield(cfg,'deldotdel') || isempty(cfg.deldotdel))
    cfg.deldotdel=rbdeldotdel(cfg);
end
if(~isfield(cfg,'omega') || isempty(cfg.omega))
    cfg.omega=0;
end
newcfg=cfg;
sd = rbsdmap(cfg);