function [hdlblkinfo, defImpl, deprInfo, hdlblkInfoHide, helpInfo] = getSLBlkImplInfo(~, slbh)
%   Returns an array of structures, one for each implementation available
%   for the object with the following information
%
%   SLBH : simulink block handle (gcbh)

%   Copyright 2009-2019 The MathWorks, Inc.

hdlblkinfo = [];
defImpl = [];
deprInfo = [];
hdlblkInfoHide = [];
helpInfo = [];

mdlName = get_param(bdroot(slbh), 'Name');
lockstatus = get_param(bdroot(slbh), 'lock');
if strcmpi(lockstatus, 'on')
    fprintf('HDL Properties cannot be displayed for a locked model\n');
    return;
end

% get a unique tag for the slbh
[blkTag, fail] = hdlgetblocklibpath(slbh);
if fail
    fprintf('HDL Properties cannot be displayed for the unsupported block ''%s''', getfullname(slbh));
    return;
end

hD = hdlmodeldriver(mdlName);
db = hD.getImplDatabase;
configMgr = hD.getConfigManager(mdlName);
if isempty(configMgr.DefaultTable.Sets)
    % If this is called before checkhdl/makehdl is run we need to populate the
    % ConfigMgr.
    configMgr.parseConfiguration(db, '');
end

defImpl = configMgr.getDefaultImplementation(blkTag);
[hdlblkinfo, deprInfo, hdlblkInfoHide, helpInfo] = db.getImplementationInfoForBlock(blkTag, true, '', slbh);

blkType = get_param(slbh, 'BlockType');

if isempty(defImpl)
    % handle unsupported blocks
    defImpl = handleUnsupportedBlks(blkType);    
    if isempty(hdlblkinfo) && strcmpi(blkType, 'subsystem')
        % may be a user written library subsystem
        hdlblkinfo = db.getImplementationInfoForBlock('built-in/SubSystem', true);
    end
end

if isRootSubsystem(mdlName, slbh)
    % Limit subsystems at the top of the top model to only support Subsystem
    % (Module) implementation. No BlackBoxes, etc.
    hdlblkinfo = db.getSubsystemImplInfo;
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [impl] = handleUnsupportedBlks(blkType)
impl = [];
switch lower(blkType)
    case {'inport', 'outport', 'terminator', 'ground' }
        impl = hdldefaults.NoHDL;
    case {'subsystem'}
        % didn't find Impl for this block or subsystem
        % must be user written library subsystem
        impl = hdldefaults.Subsystem;   
end
end

function isrootSS = isRootSubsystem(mdlName, slbh)
isrootSS = false;
isSSBlk = strcmpi(hdlgetblocklibpath(slbh), 'built-in/subsystem');

if isSSBlk    
    parent = get_param(slbh, 'Parent');
    
    % skip referenced models. default to false.
    parent_obj = get_param(parent,'Object');
    if ( isa(parent_obj,'Simulink.BlockDiagram') )
        parent_cfg = parent_obj.getActiveConfigSet();
        % If the config set name is 'ModelReferencing' with or without any
        % trailing numbers, then this subsystem is actually at the top
        % level of a referenced model and not the root model.
        isRefModel = ~isempty(regexp(parent_cfg.Name, 'ModelReferencing\d*$', 'once'));
    else
        isRefModel = false;
    end
    
    if ~isRefModel && strcmpi(mdlName, parent)
        isrootSS = true;
    end    
end
end

% LocalWords:  slbh
