function tt = array2timetable(x,varargin)  %#codegen
%ARRAY2TIMETABLE Convert homogeneous array to timetable.
%   TT = ARRAY2TIMETABLE(X,'RowTimes',ROWTIMES) converts the M-by-N array X and
%   the M-by-1 datetime or duration vector ROWTIMES to an M-by-N timetable TT. Each
%   column of X becomes a variable in TT, and ROWTIMES becomes TT's time vector.
%
%   Note: to convert a table to a timetable, use TABLE2TIMETABLE.
%
%   TT = ARRAY2TIMETABLE(X,'RowTimes',ROWTIMES,'VariableNames',VARNAMES)
%   creates TT using VARNAMES for TT's variable names. The names must be
%   valid MATLAB identifiers, and must be unique.
%
%   TT = ARRAY2TIMETABLE(X,'SampleRate',FS,'StartTime',T0) creates a timetable
%   using the specified sample rate FS and start time T0 to implicitly define
%   TT's time vector. FS is a positive numeric scalar specifying the number of
%   samples per second (Hz). T0 is a scalar datetime or duration, and determines
%   whether TT's row times are absolute (T0 is a datetime) or relative (T0 is a
%   duration). The default is SECONDS(0).
%
%   TT = ARRAY2TIMETABLE(X,'TimeStep',DT,'StartTime',T0) creates a timetable
%   using the specified time step DT and start time T0 to implicitly define TT's
%   time vector. DT is a scalar duration or calendarDuration specifying the
%   inter-sample time step. T0 is a scalar datetime or duration, and determines
%   whether TT's row times are absolute (T0 is a datetime) or relative (T0 is a
%   duration). T0 must be a datetime if DT is a calendarDuration. The default is
%   SECONDS(0).
%
%   See also TIMETABLE, TABLE2TIMETABLE, ARRAY2TABLE, CELL2TABLE, STRUCT2TABLE.

%   Copyright 2016-2019 The MathWorks, Inc.

if ~isempty(coder.target)
    % codegen, redirect to codegen specific function and return
    tt = matlab.internal.coder.array2timetable(x, varargin{:});
    return
end

if ~ismatrix(x)
    error(message('MATLAB:array2timetable:NDArray'));
end
[nrows,nvars] = size(x);

pnames = {'VariableNames' 'RowTimes'  'SampleRate'  'SamplingRate'  'TimeStep'  'StartTime'};
dflts =  {            []         []            []              []          []   seconds(0) };
[varnames,rowtimes,sampleRate,legacySamplingRate,timeStep,startTime,supplied] ...
    = matlab.internal.datatypes.parseArgs(pnames, dflts, varargin{:}); 
[sampleRate,supplied] = matlab.internal.tabular.acceptLegacySamplingRateParam(...
    supplied,sampleRate,legacySamplingRate);

[rowtimesDefined,rowtimes,startTime,timeStep,sampleRate] ...
    = matlab.internal.tabular.validateTimeVectorParams(supplied,rowtimes,startTime,timeStep,sampleRate);
if ~rowtimesDefined % neither RowTimes, TimeStep, nor SampleRate was specified
    error(message('MATLAB:timetable:NoTimeVector'));
end

if ~supplied.VariableNames
    if nvars > 0 % skip nvars==0 for performance
        baseName = inputname(1);
        if isempty(baseName)
            varnames = matlab.internal.tabular.defaultVariableNames(1:nvars);
        else
            if nvars == 1
                varnames = {baseName};
            else
                varnames = matlab.internal.datatypes.numberedNames(baseName,1:nvars);
            end
        end
    else
        varnames = cell(1,0);
    end
end

% Each column of X becomes a variable in TT. No need to check if they are all the
% same height, they are all columns in one array.
vars = mat2cell(x,nrows,ones(1,nvars));
if supplied.RowTimes
    % The input matrix defines the size of the output timetable. The time
    % vector must have the same length as the matrix has rows, even if
    % the matrix has no columns.
    if numel(rowtimes) ~= nrows
        error(message('MATLAB:array2timetable:IncorrectNumberOfRowTimes'));
    end

    % No special case to create an Nx0 empty, assigning row times outweighs
    % advantage of using timetable.empty.
    tt = timetable.init(vars,nrows,rowtimes,nvars,varnames);
else % supplied.TimeStep || supplied.SampleRate
    tt = timetable.initRegular(vars,nrows,startTime,timeStep,sampleRate,nvars,varnames);
end
