function allNames = generateColumnNames(terms,vi)
% Inputs are a terms matrix and a VariableInfo structure, as computed in
% tall/fitlm and tall/fitglm. Output is an array of names for the
% coefficient estimates.

%   Copyright 2017 The MathWorks, Inc.

% First generate names for each main effect, whether used in this
% model or not

nvars = size(vi,1);
mainNames = cell(1,nvars);
for j=1:nvars
    varname = vi.Properties.RowNames{j};
    if ~vi.IsCategorical(j)
        mainNames{j} = {varname};
    else
        vals = vi.Range{j};
        [~,gn] = grp2idx(vals);
        mainNames{j} = strcat(varname,'_',gn);
    end
end

% Generate names for terms in the model
nterms = size(terms,1);
termNames = cell(1,nterms);
for j=1:nterms
    tm = terms(j,:);
    if all(tm==0)
        termNames{j} = {'(Intercept)'};
    else
        idx = find(tm);
        pwrs = tm(idx);
        tm = mainNames{idx(1)};
        if pwrs(1)>1
            tm = strcat(tm,'^',num2str(pwrs(1)));
        end
        for k=2:length(idx)
            tm2 = mainNames{idx(k)};
            if pwrs(k)>1
                tm2 = strcat(tm2,'^',num2str(pwrs(k)));
            end
            tm = combine2terms(tm,tm2);
        end
        termNames{j} = tm;
    end
end

% Combine all term names
allNames = termNames{1}(:)';
for k=2:nterms
    tm2 = termNames{k}(:)';
    allNames = [allNames,tm2]; %#ok<AGROW>
end
end

%%
function tm = combine2terms(tm1,tm2)
n1 = length(tm1);
n2 = length(tm2);
tm = cell(1,n1*n2);
for j=1:n2
    base = n1*(j-1);
    tm(base+(1:n1)) = strcat(tm1,':',tm2{j});
end
end