%makeElementPattern make antenna element pattern for CDL channel model

%   Copyright 2017-2021 The MathWorks, Inc.

%#codegen

function elementPattern = makeElementPattern(antennaArray,CarrierFrequency)
    if isstruct(antennaArray)
        switch (antennaArray.PolarizationModel)
            case 'Model-1'
                polarizationModel = @wireless.internal.channelmodels.polarizationModel1;
            case 'Model-2'
                polarizationModel = @wireless.internal.channelmodels.polarizationModel2;
            otherwise
                error('wireless:error','Polarization model must be ''Model-1'' or ''Model-2''');
        end
        
        switch (antennaArray.Element)
            case {'38.900','38.901','36.873'}
                elementPattern = @(theta_prime,phi_prime,zeta,s)polarizationModel(@wireless.internal.channelmodels.A_BSantenna,theta_prime,phi_prime,zeta);
            case 'isotropic'
                elementPattern = @(theta_prime,phi_prime,zeta,s)polarizationModel(@wireless.internal.channelmodels.A_isotropic,theta_prime,phi_prime,zeta);
            otherwise
                error('wireless:error','Element must be ''38.900'', ''38.901'', ''36.873'' or ''isotropic''');
        end
    elseif isa(antennaArray,'phased.internal.AbstractArray') || isa(antennaArray,'phased.internal.AbstractSubarray') % PhAST mode
        elementPattern = @(theta_prime,phi_prime,zeta,s) customPhasedArrayFields(antennaArray,CarrierFrequency,[phi_prime;90-theta_prime],s);
    else
        error('wireless:error','Array must be a structure or a Phased Array System Toolbox array implementing phased.internal.AbstractArray or phased.internal.AbstractSubarray.');
    end
    
end

function F = customPhasedArrayFields(antennaArray,fc,angles,antNumber)

    persistent c0;
    if isempty(c0)
        c0 = physconst('LightSpeed');
    end

    if coder.target('MATLAB')
        array = clone(antennaArray);
    else
        array = clonecg(antennaArray);
    end
    
    args = {fc,angles,c0};
    
    % Support for ReplicatedSubarray and PartitionedSubarray
    if isa(array,'phased.internal.AbstractSubarray')
        EFields = array.step(args{:});
    else % Abstract array
        EFields = array.step(args{1:2});
    end
    
    if array.isPolarizationCapable
        F = [-EFields.V(antNumber,:); EFields.H(antNumber,:)];
    else
        F = [EFields(antNumber,:); zeros(size(EFields(antNumber,:)))];
    end
    
end
