function printToFile(h,varargin)
% PRINTTOFILE - this method prints the contents of the BuildInfo
% to a text file specified by the first argument.  The second,optional,
% argument is used for restricting the output to entries that have a Group
% id matching the argument.
%
% example calls:
%  RTW.BuildInfo.printToFile('file.txt')
%  RTW.BuildInfo.printToFile('file.txt','GROUP_ID')

% Copyright 2004-2019 The MathWorks, Inc.

switch nargin
  case 2
    filename = varargin{1};
    group    = '';
  case 3
    filename = varargin{1};
    group    = varargin{2};    
  otherwise
    DAStudio.error('RTW:buildInfo:printToFileUsage');
end


% all of the print niceties such as separator strings, indent strings and
% other things are set up here.  Additionally this call attempts to open
% the file for writing.
pinfo = locSetPrintInfo(filename);
if isempty(pinfo)
    DAStudio.error('RTW:utility:fileIOError',filename,'open');
end

fprintf(pinfo.fid,'%s\n',pinfo.hsep{1});
% Should the output be restricted to a specific group?
if ~isempty(group)
    fprintf(pinfo.fid,'BuildInfo contents (Group ''%s'' only)\n',...
            group);
else
    fprintf(pinfo.fid,'BuildInfo contents\n');
end

% start with the build options
locDumpOptions(h,group,pinfo,2);

% output all the include files & paths
locDumpIncludeFiles(h,group,pinfo,2)
locDumpIncludePaths(h,group,pinfo,2);

% output all the source files & paths
locDumpSourceFiles(h,group,pinfo,2)
locDumpSourcePaths(h,group,pinfo,2)

% last thing to do is print out the libraries
locDumpLibraries(h,group,pinfo,2)

fclose(pinfo.fid);

function pinfo = locSetPrintInfo(filename)
pinfo = [];
pinfo.fid = fopen(filename,'w');
if (pinfo.fid == -1)
    pinfo = [];
    return;
end

pinfo.indent = '   ';
pinfo.hsep{1} = '===============================================================================';
pinfo.hsep{2} = '----------------------------------------------------------------------------';
pinfo.hsep{3} = '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~';
pinfo.hsep{4} = '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++';

function locDumpOptions(h, group, pinfo, lvl)
% build up the indent string to the appropriate level
indent = ''; 
for i=2:lvl
    indent = [indent pinfo.indent];
end

% if there are defines, loop through and print them out
if ~isempty(h.Options.Defines)
    fprintf(pinfo.fid,'%s%s\n',indent,pinfo.hsep{lvl});
    fprintf(pinfo.fid,'%sPreprocessor defines\n',indent);
    defs = h.getDefines();
    for i=1:length(defs)
        if (isempty(group) || strcmp(group,h.Options.Defines(i).Group))
            fprintf(pinfo.fid,'%s%s(%-10.10s)   %s\n',indent, pinfo.indent,...
                    h.Options.Defines(i).Group, defs{i});
        end
    end
end

% if there are Compile Flags, loop through and print them out
if ~isempty(h.Options.CompileFlags)
    fprintf(pinfo.fid,'%s%s\n',indent,pinfo.hsep{lvl});
    fprintf(pinfo.fid,'%sCompile Flags\n',indent);
    for i=1:length(h.Options.CompileFlags)
        if (isempty(group) || strcmp(group,h.Options.CompileFlags(i).Group))
            fprintf(pinfo.fid,'%s%s(%-10.10s)   %s\n',indent, pinfo.indent,...
                    h.Options.CompileFlags(i).Group, h.Options.CompileFlags(i).Value);
        end
    end
end

% if there are Link Flags, loop through and print them out
if ~isempty(h.Options.LinkFlags)
    fprintf(pinfo.fid,'%s%s\n',indent,pinfo.hsep{lvl});
    fprintf(pinfo.fid,'%sLink Flags\n',indent);
    for i=1:length(h.Options.LinkFlags)
        if (isempty(group) || strcmp(group,h.Options.LinkFlags(i).Group))
            fprintf(pinfo.fid,'%s%s(%-10.10s)   %s\n',indent,  pinfo.indent,...
                    h.Options.LinkFlags(i).Group, h.Options.LinkFlags(i).Value);
        end
    end
end

function locDumpIncludeFiles(h, group, pinfo, lvl)

% build up the indent string to the appropriate level
indent = ''; 
title_indent = '';
for i=2:lvl
    % the title indent is one level out
    title_indent = indent;
    indent = [indent pinfo.indent];
end

if ~isempty(h.Src.Files)
    fprintf(pinfo.fid,'%s%s\n',title_indent,pinfo.hsep{lvl-1});
    fprintf(pinfo.fid,'%sInclude Files\n',title_indent);
    for i=1:length(h.Inc.Files)
        if (isempty(group) || strcmp(group,h.Inc.Files(i).Group))
            fprintf(pinfo.fid,'%s%s\n',indent,pinfo.hsep{lvl});
            fprintf(pinfo.fid,'%s(%-10.10s)   %s/%s\n',indent,...
                    h.Inc.Files(i).Group, h.Inc.Files(i).Path,...
                    h.Inc.Files(i).FileName);
        end
    end
end

function locDumpIncludePaths(h, group, pinfo, lvl)

% build up the indent string to the appropriate level
indent = ''; 
title_indent = '';
for i=2:lvl
    % the title indent is one level out
    title_indent = indent;
    indent = [indent pinfo.indent];
end

if ~isempty(h.Inc.Paths)
    fprintf(pinfo.fid,'%s%s\n',title_indent,pinfo.hsep{lvl-1});
    fprintf(pinfo.fid,'%sInclude Paths\n',title_indent);
    for i=1:length(h.Inc.Paths)
        if (isempty(group) || strcmp(group,h.Inc.Paths(i).Group))
            fprintf(pinfo.fid,'%s%s\n',indent,pinfo.hsep{lvl});
            fprintf(pinfo.fid,'%s(%-10.10s)   %s\n',indent,...
                    h.Inc.Paths(i).Group, h.Inc.Paths(i).Value);
        end
    end
end

function locDumpSourceFiles(h, group, pinfo, lvl)

% build up the indent string to the appropriate level
indent = ''; 
title_indent = '';
for i=2:lvl
    % the title indent is one level out
    title_indent = indent;
    indent = [indent pinfo.indent];
end

if ~isempty(h.Src.Files)
    fprintf(pinfo.fid,'%s%s\n',title_indent,pinfo.hsep{lvl-1});
    fprintf(pinfo.fid,'%sSource Files\n',title_indent);
    for i=1:length(h.Src.Files)
        if (isempty(group) || strcmp(group,h.Src.Files(i).Group))
            fprintf(pinfo.fid,'%s%s\n',indent,pinfo.hsep{lvl});
            fprintf(pinfo.fid,'%s(%-10.10s)   %s/%s\n',indent,...
                    h.Src.Files(i).Group, h.Src.Files(i).Path,...
                    h.Src.Files(i).FileName);
        end
    end
end

function locDumpSourcePaths(h, group, pinfo, lvl)

% build up the indent string to the appropriate level
indent = ''; 
title_indent = '';
for i=2:lvl
    % the title indent is one level out
    title_indent = indent;
    indent = [indent pinfo.indent];
end

if ~isempty(h.Src.Paths)
    fprintf(pinfo.fid,'%s%s\n',title_indent,pinfo.hsep{lvl-1});
    fprintf(pinfo.fid,'%sSource Paths\n',title_indent);
    for i=1:length(h.Src.Paths)
        if (isempty(group) || strcmp(group,h.Src.Paths(i).Group))
            fprintf(pinfo.fid,'%s%s\n',indent,pinfo.hsep{lvl});
            fprintf(pinfo.fid,'%s(%-10.10s)   %s\n',indent,...
                    h.Src.Paths(i).Group, h.Src.Paths(i).Value);
        end
    end
end

function locDumpLibraries(h, group, pinfo, lvl)

% build up the indent string to the appropriate level
indent = ''; 
for i=2:lvl
    % the title indent is one level out
    indent = [indent pinfo.indent];
end

if isempty(h.LinkObj)
    return;
end


fprintf(pinfo.fid,'%s\nLibraries\n',pinfo.hsep{lvl-1});
for i = 1:length(h.LinkObj)
    
    fprintf(pinfo.fid,'%s%s\n',indent,pinfo.hsep{lvl});
    fprintf(pinfo.fid,'%s(%-10.10s)   %s/%s\n',indent, h.LinkObj(i).Group,...
            h.LinkObj(i).Path, h.LinkObj(i).Name);
    
    % start with the build options
    locDumpOptions(h.LinkObj(i),group,pinfo,lvl+1);
    
    % output all the include files & paths
    locDumpIncludeFiles(h.LinkObj(i),group,pinfo,lvl+1)
    locDumpIncludePaths(h.LinkObj(i),group,pinfo,lvl+1);
    
    % output all the source files & paths
    locDumpSourceFiles(h.LinkObj(i),group,pinfo,lvl+1)
    locDumpSourcePaths(h.LinkObj(i),group,pinfo,lvl+1)
end
