%findModelBlocks Search for the Model blocks included in the model
%modelName. Do not return Model Blocks with ProtectedModel set to
%'on'
function mdlBlks = findModelBlocks(modelName, skipUnderInactiveVariants, allLevels)

%   Copyright 2009-2020 The MathWorks, Inc.

    if nargin<3
        allLevels = false;
    end
    
    if nargin<2
        skipUnderInactiveVariants = false;
    end
   
    % find model ActivePlusCodeVariants blocks under VSS.
    % find_mdlrefs returns ActivePlusCodeVariants blocks by default.
    % (refer doc). Using edit-time MatchFilter to retain consistency.
    % @todo : revisit the API. Post FindSystemVariantsRemoval,
    % find_mdlrefs returns all the model blocks (change in default
    % behaviour). Also we can use MatchFilter (post compilation) to
    % skip inactive model blocks.
    [~, mdlBlks] = find_mdlrefs(modelName, 'AllLevels', allLevels, ...
        'MatchFilter', @Simulink.match.internal.filterOutCodeInactiveVariantSubsystemChoices);

    if ~isempty(mdlBlks)                
        I = strncmp('on',get_param(mdlBlks,'ProtectedModel'),3);
        mdlBlks(I) = [];             
        if skipUnderInactiveVariants && ~isempty(mdlBlks)
            idxToSkip = [];
            for idx=1:length(mdlBlks)
                parentSubsystem = get_param(mdlBlks{idx},'Parent');
                while ~isempty(parentSubsystem) && ~isempty(get_param(parentSubsystem,'Parent'))
                    variantControl = get_param(parentSubsystem,'VariantControl');
                    if ~isempty(variantControl)
                        % SL Test harness/SLDV harness/sldvextract models may not have parameter 'ActiveVariant'.
                        % However harness creation/extraction process eliminates inactive variants.
                        grandParent = get_param(parentSubsystem,'Parent');
                        grandParentHandle = get_param(grandParent, 'Handle');
                        propValStruct = get(grandParentHandle);
                        if isfield(propValStruct, 'ActiveVariant')
                            parentvariantObj = propValStruct.ActiveVariant;
                        else
                            parentvariantObj = '';
                        end
                        if ~isempty(parentvariantObj) && ...
                                ~strcmp(parentvariantObj,variantControl)
                            % This is inactive variant
                            idxToSkip(end+1) = idx; %#ok<AGROW>
                            break;
                        end
                    end
                    parentSubsystem = get_param(parentSubsystem,'Parent');
                end
            end            
            mdlBlks(idxToSkip) = [];
        end
    end
end    

% LocalWords:  VSS mdlrefs
