function createFun(pname,sdesc,fdesc,auth,cdate,mode,debug)
% creatFun Create a functions with header

% revision history:
% 01/04/1994 Mark D. Shattuck <mds> createFun.m from createFun.c
% 07/22/1996 mds add auth,sdesc,fdesc
% 04/03/1997 mds add default args
% 07/07/2001 mds add vars, change order
% 11/30/2002 mds add defs
% 12/24/2005 mds add cdate
% 01/21/2006 mds add %%
% 04/22/2014 mds add mode for update[u] add[a] create[c] 
% 04/19/2016 mds convert to pname='[o1,o2,...]=name(i1[def1],i2[def2],...)'
% 04/21/2016 mds move parsing to parseUsage.m
% 01/03/2017 mds add numeric cdate
% 01/30/2020 mds add case for optional iargs funName(a,[b]) nb: may be no
%                use case.
%                add mode for debug[d] prints to screen


%% Parse Inputs
if(~exist('auth','var') || isempty(auth))
  auth='Mark D. Shattuck';
end

if(~exist('sdesc','var') || isempty(sdesc))
  sdesc='Description here.';
end

if(~exist('fdesc','var') || isempty(fdesc))
  fdesc='';
end

if(~exist('cdate','var') || isempty(cdate))
  cdate=datestr(now, 'mm/dd/yy');
else
  if(isnumeric(cdate))
    cdate=datestr(cdate, 'mm/dd/yy');
  end
end

if(~exist('mode','var') || isempty(mode))
  mode='c';
end

if(~exist('debug','var') || isempty(debug))
  debug=false;
end

%%  Main

S=parseUsage(pname);
cap=find(lower(S.fn)-S.fn);
Ncap=length(cap);
name=strSplit(S.fn,cap);
name=[name;num2cell(repmat(' ',1,Ncap+1))];
name=strtrim([name{:}]);
vars=S.iarg;
defs=S.iopt;
ovars=S.oarg;
isdefs=~cellfun('isempty',defs);


base=camelcase(name,true,false);  % compress camelcase first word lower
fn=[base '.m'];

acode=lower(auth(auth>='A' & auth<='Z'));

Nv=length(vars);
No=length(ovars);

if(mode=='d') % debug
  fid=1;
else
  fom='w';
  if(exist(fn,'file'))
    switch mode
      case 'c'
        fprintf(1,'%s exists.\n',fn);
        fprintf(1,'Rerun with mode ''o'' to over-write.\n');
        fprintf(1,'Rerun with mode ''a'' to add.\n');
        fprintf(1,'Rerun with mode ''u'' to update.\n');
        return;
      case 'o'
        fom='w';
        dr=dir(fn);
        delete(dr.name);
      case 'a'
        fom='a+';
      case 'u'
        fom='a+';
    end
  end
  
  fid=fopen(fn,fom);
  fseek(fid, 0, 'bof'); % begining
  
end
% Function declarations
fprintf(fid,'function ');
switch No
  case 0
    fprintf(fid,'%s(',base);
  case 1
    fprintf(fid,'%s=%s(',ovars{1},base);
  otherwise
    fprintf(fid,'[');
    fprintf(fid,'%s,',ovars{1:end-1});
    fprintf(fid,'%s',ovars{end});
    fprintf(fid,']=%s(',base);
end
fprintf(fid,'%s,',vars{1:end-1});
fprintf(fid,'%s',vars{end});
fprintf(fid,')\n');

% Short description
fprintf(fid,'%% %s <%s>\n',base,sdesc);

% Usage
fprintf(fid,'%% Usage:: %s=%s\n%%\n',S.out,S.in);

% Long description
ifprintf(~isempty(fdesc),fid,'%% %s\n',fdesc);
fprintf(fid,'\n');
fprintf(fid,'%% revision history:\n');
fprintf(fid,'%% %s %s <%s> %s\n',cdate,auth,acode,fn);
fprintf(fid,'\n');

% Parse Inputs
if(any(isdefs))
  fprintf(fid,'%%%% Parse Input\n');
  for nv=find(isdefs);
    fprintf(fid,'if(~exist(''%s'',''var'') || isempty(%s))\n',vars{nv},vars{nv});
    fprintf(fid,'\t%s=%s;\n',vars{nv},defs{nv});
    fprintf(fid,'end\n\n');
  end
end

% Parse outputs
if(any(S.oopt))
  fprintf(fid,'%%%% Parse Ouput\n');
  fprintf(fid,'%% <Add output parser here.>\n\n');
end

if(debug)
  fprintf(fid,'%%%% Debug <Delete if not needed.>\n');
  fprintf(fid,'debug=true;\n');
  fprintf(fid,'if(debug)\n');
  if(Nv>0)
    fprintf(fid,'\tdisp([');
    fprintf(fid,'%s,',vars{1:end-1});
    fprintf(fid,'%s]);\n',vars{end});
  end
  ifprintf(No>0,fid,'%s=1;\n',ovars{:});
  fprintf(fid,'end\n\n');
end

fprintf(fid,'%%%% Main\n\n\n');

if(mode~='d')
  fclose(fid);
  edit(fn);
end
