function y = eml_pad_array(x,ysize,padval)
%MATLAB Code Generation Private Function

%   Pads or truncates each dimension of X to produce an array Y with size
%   YSIZE. If dimensions are increased, the extra elements are filled with
%   PADVAL. The default value of PADVAL is EML_SCALAR_EG(X) (which is
%   usually zero, depending on the type of X).

%   Copyright 2010-2017 The MathWorks, Inc.
%#codegen

coder.internal.allowEnumInputs;
eml_invariant(nargin >= 2, ...
    'MATLAB:minrhs');
coder.internal.prefer_const(ysize);
coder.internal.assertValidSizeArg(ysize);
if nargin < 3
    padval = coder.internal.scalarEg(x);
else
    eml_invariant(isscalar(padval), ...
        'Coder:toolbox:eml_pad_array_2', ...
        'IfNotConst','Fail');
end
ZERO = zeros(coder.internal.indexIntClass);
ONE = ones(coder.internal.indexIntClass);
y = coder.nullcopy(eml_expand(coder.internal.scalarEg(x),ysize));
y(:) = padval;
ndimsy = cast(coder.internal.ndims(y),coder.internal.indexIntClass);
if isempty(y)
elseif ndimsy <= 2 % streamlined code for 2-D output
    mx = cast(size(x,1),coder.internal.indexIntClass);
    my = cast(size(y,1),coder.internal.indexIntClass);
    nx = cast(size(x,2),coder.internal.indexIntClass);
    ny = cast(size(y,2),coder.internal.indexIntClass);
    m = eml_min(mx,my);
    n = eml_min(nx,ny);
    for j = 1:n
        for i = 1:m
            y(i,j) = x(i,j);
        end
    end
elseif ndimsy == 3 % streamlined code for 3-D output
    mx = cast(size(x,1),coder.internal.indexIntClass);
    my = cast(size(y,1),coder.internal.indexIntClass);
    nx = cast(size(x,2),coder.internal.indexIntClass);
    ny = cast(size(y,2),coder.internal.indexIntClass);
    ox = cast(size(x,3),coder.internal.indexIntClass);
    oy = cast(size(y,3),coder.internal.indexIntClass);
    m = eml_min(mx,my);
    n = eml_min(nx,ny);
    o = eml_min(ox,oy);
    for k = 1:o
        for j = 1:n
            for i = 1:m
                y(i,j,k) = x(i,j,k);
            end
        end
    end
else
    % Copies one 2-D matrix "pane" at a time.
    [ndm2,nmatrices,nvectors,vlen,lims,xskip,yskip] = calc_parameters(x,y);
    % Decrement the loop limit variables and start loops from zero instead
    % of one. This suppresses some of the -1 clutter on indexing in the
    % generated code.
    nmatrices = coder.internal.indexMinus(nmatrices,1);
    nvectors = coder.internal.indexMinus(nvectors,1);
    vlen = coder.internal.indexMinus(vlen,1);
    % SUBS is a zero-based subscript vector for dimensions 3 and up.
    subs = zeros(1,ndm2,coder.internal.indexIntClass);
    % Copy the data from X to Y.
    xvtop = ZERO;
    yvtop = ZERO;
    for k = 0:nmatrices
        % Copy this matrix.
        for j = 0:nvectors
            % Copy this vector.
            for i = 0:vlen
                y(coder.internal.indexPlus(coder.internal.indexPlus(yvtop,i),1)) = ...
                    x(coder.internal.indexPlus(coder.internal.indexPlus(xvtop,i),1));
            end
            % Move to the top of the next column.
            xvtop = coder.internal.indexPlus(xvtop,size(x,1));
            yvtop = coder.internal.indexPlus(yvtop,size(y,1));
        end
        if ndimsy > 2 && k < nmatrices
            j = ONE;
            if ndimsy > 3
                % There is at least one matrix left to copy, so the
                % following loop must terminate with j < ndm2.
                while subs(j) == lims(j)
                    subs(j) = ZERO;
                    j = coder.internal.indexPlus(j,1);
                end
            end
            subs(j) = coder.internal.indexPlus(subs(j),1);
            % Skip over padded or omitted entries, if any.
            xvtop = coder.internal.indexPlus(xvtop,xskip(j));
            yvtop = coder.internal.indexPlus(yvtop,yskip(j));
        end
    end
end

%--------------------------------------------------------------------------

function [ndm2,nmatrices,nvectors,vlen,lims,xskip,yskip] =  ...
    calc_parameters(x,y)
% Calculate parameters needed for copying:
% NDM2 = number of dimensions minus 2.
% NMATRICES = number of matrix "panes" to copy.
% NVECTORS = number of vectors (columns) per matrix pane.
% VLEN = length of each vector to copy.
% LIMS = zero-based subscript limits for dimensions 3 and up.
% XSKIP = skip-forward vector for X.
% YSKIP = skip-forward vector for Y.
ndimsx = cast(coder.internal.ndims(x),coder.internal.indexIntClass);
ndimsy = cast(coder.internal.ndims(y),coder.internal.indexIntClass);
nd = eml_min(ndimsx,ndimsy);
ndm2 = coder.internal.indexMinus(nd,2);
% VLEN is the length of each vector.
vlen = eml_min( ...
    cast(size(x,1),coder.internal.indexIntClass), ...
    cast(size(y,1),coder.internal.indexIntClass));
% LIMS holds the corresponding maximum values for each element of SUBS.
lims = coder.nullcopy(zeros(1,ndm2,coder.internal.indexIntClass));
nvectors = eml_min( ... % number of vectors (columns) to copy per matrix
    cast(size(x,2),coder.internal.indexIntClass), ...
    cast(size(y,2),coder.internal.indexIntClass));
nmatrices = ones(coder.internal.indexIntClass);
for k = 3:nd
    nx = cast(size(x,k),coder.internal.indexIntClass);
    ny = cast(size(y,k),coder.internal.indexIntClass);
    minxy = eml_min(nx,ny);
    nmatrices = coder.internal.indexTimes(nmatrices,minxy);
    lims(coder.internal.indexMinus(k,2)) = coder.internal.indexMinus(minxy,1);
end
% Compute the "skip forward" vectors. When the subscript for dimension j
% has just been incremented, xskip(j) is the amount to skip forward to get
% to the top of the next column of x to be copied.  Likewise yskip(j) is
% the amount to skip forward over padding in y to the position where the
% next vector should be copied. Let
%     cx = cumprod(size(x));
%     cy = cumprod(size(y));
%     m = min(size(x),size(y)) - 1;
% then
%     xskip(j) = cx(j+1) - dot(m(2:j+1),cx(1:j)) - size(x,1);
%     yskip(j) = cy(j+1) - dot(m(2:j+1),cy(1:j)) - size(y,1);
xskip = coder.nullcopy(zeros(1,ndm2,coder.internal.indexIntClass));
yskip = coder.nullcopy(zeros(1,ndm2,coder.internal.indexIntClass));
if ndm2 > 0
    xszprod = coder.internal.indexTimes(size(x,1),size(x,2));
    yszprod = coder.internal.indexTimes(size(y,1),size(y,2));
    sx = coder.internal.indexTimes(nvectors,size(x,1));
    sy = coder.internal.indexTimes(nvectors,size(y,1));
    for k = 1:coder.internal.indexMinus(ndm2,1)
        xskip(k) = coder.internal.indexMinus(xszprod,sx);
        sx = coder.internal.indexPlus(sx,coder.internal.indexTimes(lims(k),xszprod));
        xszprod = coder.internal.indexTimes(xszprod,size(x,coder.internal.indexPlus(k,2)));
        yskip(k) = coder.internal.indexMinus(yszprod,sy);
        sy = coder.internal.indexPlus(sy,coder.internal.indexTimes(lims(k),yszprod));
        yszprod = coder.internal.indexTimes(yszprod,size(y,coder.internal.indexPlus(k,2)));
    end
    xskip(ndm2) = coder.internal.indexMinus(xszprod,sx);
    yskip(ndm2) = coder.internal.indexMinus(yszprod,sy);
end

%--------------------------------------------------------------------------
