function [elemSlant,hasSlant] = getCDLElementSlant(array)
%   Extract the element slant (polarization) of an antenna array. For PhAST
%   elements other than phased.NRAntennaElement, the returned slant is
%   equal to 0 and hasSlant is equal to 0.
%
%   Note: This is an internal undocumented function and its API and/or
%   functionality may change in subsequent releases.

%   Copyright 2020 The MathWorks, Inc.

%#codegen

    if isstruct(array)
        sz = array.Size;
        zeta = array.PolarizationAngles';
        elemSlant = permute(repmat(zeta,[1 sz([1 2 4 5])]),[2 3 1 4 5]);
        hasSlant = true(sz);
    elseif isa(array,'phased.NRRectangularPanelArray')
        elementSet = array.ElementSet;
        numPol = length(elementSet);
        hasElementSetSlant = false(numPol,1);
        zeta = zeros(numPol,1);
        for el = 1:numPol
            hasElementSetSlant(el) = isa(elementSet{el},'phased.NRAntennaElement');
            if hasElementSetSlant(el)
                zeta(el) = elementSet{el}.PolarizationAngle;
            end
        end
        elemSlant = permute(repmat(zeta,[1 array.Size]),[2 3 1 4 5]);
        hasSlant = permute(repmat(hasElementSetSlant,[1 array.Size]),[2 3 1 4 5]);
    elseif isa(array,'phased.internal.AbstractHomogeneousArray')
        numEl = array.getNumElements;
        isnr = isa(array.Element,'phased.NRAntennaElement');
        hasSlant = repmat(isnr,1,numEl);
        elemSlant = zeros(1,numEl);
        if isnr
            elemSlant(:) = array.Element.PolarizationAngle;
        end
    elseif isa(array,'phased.internal.AbstractHeterogeneousArray')
        elementSet = array.ElementSet;        
        numUniqueElements = length(elementSet);
        elemSetSlant = zeros(1,numUniqueElements);
        hasElemSetSlant = false(1,numUniqueElements);
        for el = 1:numUniqueElements
            if isa(elementSet{el},'phased.NRAntennaElement')
                elemSetSlant(el) = elementSet{el}.PolarizationAngle;
                hasElemSetSlant(el) = isa(elementSet{el},'phased.NRAntennaElement');
            end
        end
        elemSlant = elemSetSlant(array.ElementIndices(:));
        hasSlant = hasElemSetSlant(array.ElementIndices(:)); 
    elseif isa(array,'phased.internal.AbstractSubarray')
        if isa(array, 'phased.PartitionedArray')
            [es,hs] = wireless.internal.channelmodels.getCDLElementSlant(array.Array);
            elemSlant = es(:)';
            hasSlant = hs(:)';
        else % phased.ReplicatedSubarray
            [es,hs] = wireless.internal.channelmodels.getCDLElementSlant(array.Subarray);
            elemSlant = repmat(es(:)',1,array.getNumSubarrays);
            hasSlant = repmat(hs(:)',1,array.getNumSubarrays);
        end
    else
        error('wireless:error','Array must be a struct or PhAST antenna array.');
    end
end