function B = hSubsrefParensImpl(distA, A, aidx, varargin)
% hSubsrefParensImpl implements subsref for parens indexing providing a
% single index or multiple indices for arrays using codistributor2dbc scheme.
%
% Using a single index:
% B = A(X)
% X can be: scalar numeric (replicated)
% X cannot be: ':'
%
% Using multiple indices:
% B = A(X1, X2, ...)
% each X1, X2 can be: ':'or scalar numeric (replicated)
% all X3, X4, ... can be: ':' or 1 (replicated)

%   Copyright 2019 The MathWorks, Inc.

colonLiteralIdx = cellfun(@parallel.internal.indexing.isColonLiteral, aidx.subs);
numericScalarIdx = cellfun(@(x)(isnumeric(x) && isscalar(x)), aidx.subs);

[aidx, numericScalarIdx, colonLiteralIdx] = iValidateIdxFor2dbc(distA, aidx, ...
    numericScalarIdx, colonLiteralIdx);

% Cases A(), A(:), A(:,:) have been dealt in subsrefParens. Now we
% distinguish between A(:,idx)/A(idx,:) or A(idx1,idx2)/A(idx)
if any(colonLiteralIdx) && any(numericScalarIdx)
    % If one subscript is a ColonLiteral and the other one is a numeric
    % scalar, we use subsrefParensWholeRowOrColumn to return a whole
    % row or column.
    scalarDim = find(numericScalarIdx);
    scalarIdx = aidx.subs{scalarDim};
    
    B = distA.subsrefParensWholeRowOrColumn(A, scalarDim, scalarIdx);
    return;
elseif all(numericScalarIdx)
    % If all subscripts are numeric scalars, we use hSubsrefParensScalar
    % to extract the correct scalar.
    B = distA.subsrefParensScalar(A, aidx);
    return;
else
    error(message('parallel:distributed:Subsref2dbcNotSupportedSyntax'));
end
end

function [aidx, numericScalarIdx, colonLiteralIdx] = iValidateIdxFor2dbc(...
    distA, aidx, numericScalarIdx, colonLiteralIdx)
% For 2d inputs, only the first two numeric subscripts can be larger
% than 1. Additional subscripts must be 1 or ':'.
if length(numericScalarIdx)>2
    % Check additional subscripts by calling subsref with ':' for the
    % first 2 subscripts on a scalar variable.
    subsref(1, substruct('()', [':', ':', aidx.subs(3:end)]));
    % Remove additional subscripts
    colonLiteralIdx = colonLiteralIdx(1:2);
    numericScalarIdx = numericScalarIdx(1:2);
    aidx.subs = aidx.subs(1:2);
end

% Switch from linear index to subscripts if necessary
if numel(aidx.subs)==1
    if isa(aidx.subs{1}, "matlab.internal.ColonDescriptor")
        % We must expand colon descriptors in order to force 2D indexing.
        aidx.subs{1} = aidx.subs{1}(:);
    end
    [aidx.subs{1}, aidx.subs{2}] = ind2sub(distA.Cached.GlobalSize, ...
        aidx.subs{1});
end
end
