function showHdlBlockParams(varargin)

% Copyright 2013-2018 The MathWorks, Inc.

% showBlockParams(blockname)
% showBlockParams(blockname,separator) shows HDL block property as block 
% annotation after separator strings. Choose subsystem or block as input argument.
% Examples:
% Show HDL block property after separator '--------': showHdlBlockParams(gcb, 'on')
% Remove HDL property only: showHdlBlockParams(gcb,'off')
% Remove all annotations: showHdlBlockParams(gcb,'off','all')

% Target HDL block property to display
targetProps = {'BalanceDelays','Architecture','DistributedPipelining',...
    'ConstrainedOutputPipeline', 'InputPipeline', 'OutputPipeline',...
    'SharingFactor', 'StreamingFactor'};
separator = '----HDL----';

% Get all block name list
blks = find_system(varargin{1},'LookUnderMasks','none','Type','block');

% Add HDL block property values as annotation token
for k = 1:numel(blks)
    propValAll = hdlget_param(blks{k},'all');
    oldBlkAnnotation = get_param(blks{k},'AttributesFormatString');
    
    switch lower(varargin{2})
        case 'on'
            intermBlkAnnotation = oldBlkAnnotation;
            postmp = strfind(intermBlkAnnotation,separator);
            if ~isempty(postmp)
                intermBlkAnnotation(postmp(1):end) = [];
            end
            set_param(blks{k},'AttributesFormatString',intermBlkAnnotation);
            oldBlkAnnotation = get_param(blks{k},'AttributesFormatString');

            % Get HDL property
            HdlBlkAnnotation = [];
            for propLoop = 1:numel(targetProps)
                if any(ismember(propValAll(1:2:end),targetProps{propLoop}))
                    propVal = hdlget_param(blks{k},targetProps{propLoop});
                else
                    continue
                end
                
                % When DP exist,
                if isempty(intermBlkAnnotation)
                    intermBlkAnnotation0 = [targetProps{propLoop} ' = '];
                else
                    intermBlkAnnotation0 = [char(10) targetProps{propLoop} ' = '];
                end
                
                switch targetProps{propLoop},
                    case 'DistributedPipelining'
                        if strcmp(propVal,'on' )
                            HdlBlkAnnotation = [intermBlkAnnotation0 num2str(propVal)];
                        end
                    case 'BalanceDelays'
                        if isempty(hdlget_param(blks{k},'BalanceDelays'))
                            continue
                        end
                        upperBlks = blks{k};
                        slashPosVct = strfind(upperBlks,'/');
                        upperBlks(slashPosVct(end):end) = [];
                        if ~strcmp(hdlget_param(upperBlks,'BalanceDelays'),hdlget_param(blks{k},'BalanceDelays')) && ...
                                ~strcmp(hdlget_param(blks{k},'BalanceDelays'),'inherit')
                            HdlBlkAnnotation = [HdlBlkAnnotation '\n' intermBlkAnnotation0 propVal];
                        end
                    case 'Architecture'
                        if strcmp(propVal,'Tree')
                            if isempty(HdlBlkAnnotation)
                                HdlBlkAnnotation = [intermBlkAnnotation0 propVal];
                            else
                                HdlBlkAnnotation = [HdlBlkAnnotation '\n' intermBlkAnnotation0 propVal];
                            end
                        end
                    otherwise    % for pipeline
                        if propVal > 0
                            if isempty(HdlBlkAnnotation)
                                HdlBlkAnnotation = [intermBlkAnnotation0 num2str(propVal)];
                            else
                                HdlBlkAnnotation = [HdlBlkAnnotation '\n' intermBlkAnnotation0 num2str(propVal)];
                            end
                        end
                end
            end     % end HDL property
            
            % When HDL separator isn't defined
            if ~isempty(HdlBlkAnnotation)
                if ~isempty(oldBlkAnnotation)
                    % There is old block annotation
                    postmp = strfind(oldBlkAnnotation(end-1:end),'\n');
                    if ~isempty(postmp)
                        oldBlkAnnotation(end-1:end) = [];
                    end
                    intermBlkAnnotation = [dupAnnotation(oldBlkAnnotation,...
                        targetProps, separator) HdlBlkAnnotation];
                else
                    intermBlkAnnotation = [dupAnnotation(oldBlkAnnotation,...
                        targetProps, separator) '\n' HdlBlkAnnotation];
                end
            end
            
        case 'off' % When removal flag is set
            % Remove HDL block property from annotation
            if nargin == 2
                % Find first '-' and then erase the following
                intermBlkAnnotation = oldBlkAnnotation;
                postmp = strfind(intermBlkAnnotation, separator);
                if ~isempty(postmp)
                    intermBlkAnnotation(postmp(1):end) = [];
                end
                set_param(blks{k},'AttributesFormatString',intermBlkAnnotation);
                disp(sprintf('HDL block annotations for %s are removed',blks{k}))
            elseif strcmp(varargin{3},'all')
                set_param(blks{k},'AttributesFormatString','');
                disp(sprintf('All block annotations for %s are removed',blks{k}))
            else
                % error('Invalid argument for parameter removel')
            end
            continue
       otherwise
            error('Invalid argument. Use on or off')
            % intermBlkAnnotation = dupAnnotation(oldBlkAnnotation,targetProps,[]);
    end
        
    % When change to default value, it causes error
    if ~isempty(intermBlkAnnotation)
        set_param(blks{k},'AttributesFormatString',intermBlkAnnotation );
        disp(sprintf('Add block annotation for %s. \n %s \n\n',blks{k},intermBlkAnnotation))
    end
end
end

function intermBlkAnnotation = dupAnnotation(oldBlkAnnotation,targetProps,separator)

if isempty(oldBlkAnnotation)
    intermBlkAnnotation = separator;
else
    intermBlkAnnotation = [oldBlkAnnotation '\n' separator];
end
% Remove HDL block property(targetProps) description from old block
% annotation
% tmp = strsplit(oldBlkAnnotation,'\n');
% intermBlkAnnotation = [];
% for n = 1:numel(tmp)
%     flgAnnotation = 0;
%     for nn = 1:numel(targetProps)
%         if ~isempty(strfind(tmp{n},targetProps{nn}))
%             % if there is description of targetProps in oldBlkAnnotation, raise frag
%             flgAnnotation = 1;
%         end
%     end
%     if flgAnnotation==1
%         continue
%     end
%     if isempty(intermBlkAnnotation)
%         intermBlkAnnotation = [intermBlkAnnotation tmp{n}];
%     else
%         intermBlkAnnotation = [intermBlkAnnotation char(10) tmp{n}];
%     end
% end

% if isempty(intermBlkAnnotation)
%     intermBlkAnnotation = [intermBlkAnnotation separator];
% else
%     if  strcmp(intermBlkAnnotation(end-1:end),'\n')
%         intermBlkAnnotation = [intermBlkAnnotation(1:end-2) separator];
%         
%     else
%         intermBlkAnnotation = [intermBlkAnnotation separator];
%     end
% end
end
