function dataVars = validateDataVariables(T,dataVarsIn,eid)
%MATLAB Code Generation Library Function

% Validate data variables input for a table
% Check that dataVars are an appropriate type and match variables in T
% Outputs data variables. The output will be the same as the input unless
% the input was a character array - in that case it will be placed in
% a cell array
%
% Input arguments:
% T - table input that will be used for validating the data variables
% dataVarsIn - data variables input. Must be a cell array, logical, char, string, or numeric
% eid - a string with the name of the calling function to populate error messages.
%       Calling function must have error messages that match the formulas:
%       ['MATLAB:' eid ':DataVarsMustBeUnique'] and ['MATLAB:',eid,':DataVariablesTableSubscript']

%   Copyright 2019-2020 The MathWorks, Inc.
%#codegen
coder.internal.prefer_const(dataVarsIn,eid)

coder.internal.assert(coder.internal.isConst(dataVarsIn), ...
    'Coder:toolbox:DataVarsMustBeConstant');

validateattributes(dataVarsIn,{'cell','logical','char','string','numeric'},{});
validateattributes(T,{'table','timetable'},{});

totalNumVars = coder.const(coder.internal.indexInt(width(T)));

if isnumeric(dataVarsIn)
    % Check for flints
    dataVarsReshaped = reshape(dataVarsIn,[],1);
    ISFLINT = coder.const(round(dataVarsReshaped)==dataVarsReshaped);
    ALLFLINT = coder.const(feval('all',ISFLINT));
    ISPOSITIVE = dataVarsReshaped>0;
    ALLPOSITIVE = coder.const(feval('all',ISPOSITIVE));
    coder.internal.assert(ALLFLINT && ALLPOSITIVE,...
        'MATLAB:table:IllegalVarIndex');
    dataVarsTmp = coder.const(coder.internal.indexInt(dataVarsReshaped));
    % Check that index is within range
    ISINRANGE = coder.const(dataVarsTmp<=totalNumVars);
    ALLINRANGE = coder.const(feval('all',ISINRANGE));
    coder.internal.assert(ALLINRANGE,['MATLAB:',eid,':DataVariablesTableSubscript'])
    % Remove duplicates
    dataVars = coder.const(feval('unique',dataVarsTmp));
elseif islogical(dataVarsIn)
    dataVars = coder.const(dataVarsIn);
    % Check that data variables are in range
    % Note that 'false' values do not need to be in range
    HIGHESTINDEX = coder.const(feval('find',dataVars,1,'last'));
    coder.internal.assert(HIGHESTINDEX<=totalNumVars,['MATLAB:',eid,':DataVariablesTableSubscript']);
elseif isstring(dataVarsIn)
    % Strings are handled separately because they won't be processed
    % correctly if they are in a cell array
    dataVars = coder.const(dataVarsIn);
    % Check that variable exists
    VAREXISTS = coder.const(feval('strcmp',T.Properties.VariableNames,dataVars));
    ANYVAREXISTS = coder.const(feval('any',VAREXISTS));
    coder.internal.assert(ANYVAREXISTS,['MATLAB:',eid,':DataVariablesTableSubscript']);
    % Because string arrays are not supported in codegen, no duplicate
    % check is necessary
else
    if ischar(dataVarsIn)
        % Package single variable input as a cell array
        dataVarsTmp = coder.const({dataVarsIn});
    else
        dataVarsTmp = coder.const(dataVarsIn);
    end
    % Remove duplicates
    dataVars = coder.const(feval('unique',dataVarsTmp));
    %numVarsIn = numel(dataVars);
    
    ISVALIDVAR = coder.const(feval('ismember',dataVars,T.Properties.VariableNames));
    ALLVALIDVAR = coder.const(feval('all',ISVALIDVAR));
    coder.internal.assert(ALLVALIDVAR,['MATLAB:',eid,':DataVariablesTableSubscript']);
end
