function toMCode(hRoutine,hText,options,isFirst)
% Generates code based on input coderoutine object

% Copyright 2006-2015 The MathWorks, Inc.

if nargin == 2
    isFirst = false;
    options.MFileName = '';
end

% If this is not the first, add a separator:
if ~isFirst
    hText.addln('%-------------------------------------------------------------------------%');
end

% Determine file name
if ~isFirst || isempty(options.MFileName)
    function_name = hRoutine.String;
else
    name = options.MFileName;
    function_name = name;
end

% Generate output variables
hArgOut = hRoutine.Argout;

% Add function name 
if ~isempty(hArgOut)
    if isa(hArgOut{1},'codegen.codeargument');
        argStr = hArgOut{1}.String;
    else
        argStr = hArgOut{1};
    end
    str = ['function [',argStr];
    for i = 2:length(hArgOut)
        if isa(hArgOut{i},'codegen.codeargument')
            argStr = hArgOut{i}.String;
        else
            argStr = hArgOut{i};
        end
        str = [str ', ' argStr];
    end
    str = [str '] = ',function_name];
else 
    str = ['function ',function_name];
end

hText.addln(str);

% Get the number of input arguments
hArgIn = hRoutine.Argin;

% Add function input arguments
str = '';
argStr = {};
if ~isempty(hArgIn)
    if isa(hArgIn{1},'codegen.codeargument')
        argStr{end+1} = hArgIn{1}.String;
    else
        argStr{end+1} = hArgIn{1};
    end
    str = [str '(' argStr{end}];
    for i = 2:length(hArgIn)
        if isa(hArgIn{i},'codegen.codeargument')
            argStr{end+1} = hArgIn{i}.String;
        else
            argStr{end+1} = hArgIn{i};
        end
        str = [str ', ' argStr{end}];
    end
    str = [str ')'];
end
hText.add(str);

% Standard H1 line
str = sprintf('%%%s',upper(function_name));
hText.addln(str);

% Add input variables to H1 line
len = length(hArgIn);
for n = 1:len
    if(n==1)
        hText.add('(');
    end
    str = argStr{n};
    hText.add(upper(str));
    if (n==len)
        hText.add(')');
    else
        hText.add(',');
    end
end

% Add comment for the subfunction
comment = get(hRoutine,'Comment');
if isa(comment, 'message')
    comment = getString(comment);
end
comment = strrep(comment,char(10),[char(10) '%  ']);
if ~isempty(comment)
    hText.addln(['%  ',comment]);
end

% Create comments for each input argument
for n = 1:len
    hVar = hArgIn{n};
    if isa(hVar,'codegen.codeargument')
        hText.addln(['%  ', hVar.getCommentString()]);
    end
end

% If this is the first function in the file, add the internal comment as
% well as the "See Also" line
if isFirst
    % See Also line
    otherFuns = hRoutine.SeeAlsoList;
    if ~isempty(otherFuns)
        % Define the maximum line length for the buffer in order to automatically
        % determine where to separate lines of code.
        if desktop('-inuse')
            settingsObj = settings;
            maxTextLine = settingsObj.matlab.editor.displaysettings.linelimit.LineColumn.ActiveValue;
        else
            maxTextLine = 75;
        end
        strSeeAlso = getString(message('MATLAB:codetools:codegen:coderoutine:toMCode:SeeAlso'));
        hText.addln('%');
        hText.addln(sprintf('%%  %s ',strSeeAlso));
        funLength = length(otherFuns);
        for i = 1:length(otherFuns)
            nextString = otherFuns{i};
            if (length(nextString) + hText.getLineLength) > maxTextLine
                hText.addln('%  ');
            end
            hText.add(upper(nextString));
            if i<funLength
                hText.add(', ');
            else
                hText.add('.');
            end
        end
    end
    % Internal comment
    hText.addln(' ');
    currentDate = datestr(now);
    strAutogeneratedByMATLAB = getString(message('MATLAB:codetools:codegen:coderoutine:toMCode:AutogeneratedByMATLAB',currentDate));
    hText.addln(sprintf('%%  %s',strAutogeneratedByMATLAB));
    hText.addln(' ');
else
    hText.addln(' ');
end

% Go through the function list and generate text for each:
hFuncList = get(hRoutine,'Functions');
for i = 1:length(hFuncList)
    hFuncList(i).toMCode(hText);
end

hText.addln('');

% Go through the subfunction list and generate text for each
hSubFunc = get(hRoutine,'SubFunctionList');
for i = 1:length(hSubFunc)
    hSubFunc(i).toMCode(hText,options,false);
end
