function iconstr = utilGetMaskDisplayString(blk)
% GETMASKDISPLAYSTRING  Generates the Mask display string

%   Copyright 2017-2020 The MathWorks, Inc.

blkH = get_param(blk, 'Object');
dlgSett = pidpack.PIDConfig.utilGetDialogSettings(blk);

% Add image first as we need to layer other details over the image.
fileStr = 'fullfile(matlabroot,''toolbox'',''simulink'',''blocks'',''pid_Images'',''blank.png'')';
imgStr = sprintf('image(imread(%s,''png''),[0 0 1 1]);\n',fileStr);

% Get port information
aPosition = get_param(blk, 'Position'); % Position = [LEFT TOP RIGHT BOTTOM]
LEFT = aPosition(1); BOTTOM = aPosition(4);
aPortCon = get_param(blk,'PortConnectivity');

if dlgSett.isDialogDiscrete
    argstr = '(z)';
else
    argstr = '(s)';
end
dispStr = sprintf('disp(''%s%s'')', dlgSett.Controller, argstr);
iconstr = sprintf('%s%s', imgStr, dispStr);
% Determine minimum number of inports for the block
blkMaskType = blkH.MaskType;
if strcmp(blkMaskType,'PID 1dof')
    MINPORTS = 1;
    iconstr = [iconstr newline 'port_label(''input'', 1, '''');' newline 'port_label(''output'', 1, '''');'];
    isB = false;
    isC = false;
elseif strcmp(blkMaskType,'PID 2dof')
    MINPORTS = 2;
    iconstr = [iconstr newline 'port_label(''input'', 1, ''Ref'');' newline 'port_label(''input'', 2, '''');' newline 'port_label(''output'', 1, '''');'];
    isB = true;
    isC = dlgSett.isDialogDerivative;
else
    error(message('Simulink:blocks:unknownBlockType'));
end

%% Inports
inPorts = find_system(blk,'SearchDepth',1,'LookUnderMasks','on','followlinks','on','BlockType','Inport');
inPortNames = get_param(inPorts,'Name');
aPointer = MINPORTS+1;
if dlgSett.isDialogExternal
    if dlgSett.isDialogProportional && any(strcmp(inPortNames,'P'))
        iconstr = [iconstr newline 'port_label(''input'', ' num2str(aPointer) ', ''\rmP'', ''texmode'', ''on'');'];
        aPointer = aPointer + 1;
    end
    if dlgSett.isDialogIntegral && any(strcmp(inPortNames,'I'))
        iconstr = [iconstr newline 'port_label(''input'', ' num2str(aPointer) ', ''\rmI'', ''texmode'', ''on'');'];
        aPointer = aPointer + 1;
    end
    if dlgSett.isDialogDerivative && any(strcmp(inPortNames,'D'))
        iconstr = [iconstr newline 'port_label(''input'', ' num2str(aPointer) ', ''\rmD'', ''texmode'', ''on'');'];
        aPointer = aPointer + 1;
    end
    if dlgSett.isDialogFilter && any(strcmp(inPortNames,'N'))
        iconstr = [iconstr newline 'port_label(''input'', ' num2str(aPointer) ', ''\rmN'', ''texmode'', ''on'');'];
        aPointer = aPointer + 1;
    end
    if isB && any(strcmp(inPortNames,'b'))
        iconstr = [iconstr newline 'port_label(''input'', ' num2str(aPointer) ', ''\rmb'', ''texmode'', ''on'');'];
        aPointer = aPointer + 1;
    end
    if isC && any(strcmp(inPortNames,'c'))
        iconstr = [iconstr newline 'port_label(''input'', ' num2str(aPointer) ', ''\rmc'', ''texmode'', ''on'');'];
        aPointer = aPointer + 1;
    end
end

% Get ports numbers and positions
if (dlgSett.isDialogIntegral || dlgSett.isDialogDerivative) &&...
        dlgSett.isDialogExtReset &&...
        any(strcmp(inPortNames,'Reset'))
    % Add trigger symbol to the Reset port
    [shiftx,shifty] = getXYofInport(blk,aPortCon,aPointer,LEFT,BOTTOM);
    aPointer = aPointer + 1;
end
if dlgSett.isDialogExtICs
    if dlgSett.isDialogIntegral && any(strcmp(inPortNames,'I0'))
        iconstr = [iconstr newline 'port_label(''input'', ' num2str(aPointer) ', ''\rmI_0'', ''texmode'', ''on'');'];
        aPointer = aPointer + 1;
    end
    if dlgSett.isDialogDerivative && any(strcmp(inPortNames,'D0'))
        iconstr = [iconstr newline 'port_label(''input'', ' num2str(aPointer) ', ''\rmD_0'', ''texmode'', ''on'');'];
        aPointer = aPointer + 1;
    end
end

% External Saturation Limits
if dlgSett.isDialogUseExternalSatLimits
    iconstr = [iconstr newline 'port_label(''input'', ' num2str(aPointer) ', ''   up'', ''texmode'', ''on'');'];
    [satupx,satupy] = getXYofInport(blk,aPortCon,aPointer,LEFT,BOTTOM);
    aPointer = aPointer + 1;
    iconstr = [iconstr newline 'port_label(''input'', ' num2str(aPointer) ', ''   lo'', ''texmode'', ''on'');'];
    [satlox,satloy] = getXYofInport(blk,aPortCon,aPointer,LEFT,BOTTOM);
    aPointer = aPointer + 1;
end

if dlgSett.isDialogTracking && any(strcmp(inPortNames,'TR'))
    if dlgSett.isDialogIntegral
        iconstr = [iconstr newline 'port_label(''input'', ' num2str(aPointer) ', ''TR'', ''texmode'', ''on'');'];
        aPointer = aPointer + 1;
    end
end
if dlgSett.isAddExternalTsPort
    iconstr = [iconstr newline 'port_label(''input'', ' num2str(aPointer) ', ''\rmT_{DTI}'', ''texmode'', ''on'');'];
end

%% Deal with the Outport
OutputX = aPortCon(end).Position(1);
OutputY = aPortCon(end).Position(2);
if strcmp(get_param(blk,'Orientation'),'right')
    satshifty = BOTTOM - OutputY - 4;
    satshiftx = OutputX- LEFT-18;
elseif strcmp(get_param(blk,'Orientation'),'down')
    satshifty = BOTTOM - OutputY + 8;
    satshiftx = OutputX - LEFT - 4;
elseif strcmp(get_param(blk,'Orientation'),'left')
    satshifty = BOTTOM - OutputY - 4;
    satshiftx = 3;
elseif strcmp(get_param(blk,'Orientation'),'up')
    satshifty = BOTTOM - OutputY - 16;
    satshiftx = OutputX- LEFT-4;
end

%% Plot triggering symbols
symbolsString = '';
if ~strcmpi(dlgSett.Controller, 'P') && any(strcmp(inPortNames,'Reset'))
    if dlgSett.ExternalReset == 2 % Rising
        triggerString = [sprintf(['plot([0 4 4 7]+' num2str(shiftx) ', [0 0 8 8]+' num2str(shifty) ');\n']) sprintf(['plot([1 4 6]+' num2str(shiftx) ', [3 6 3]+' num2str(shifty) ');'])
            ];
        symbolsString = [symbolsString newline triggerString];
    elseif dlgSett.ExternalReset == 3 % Falling
        triggerString = [sprintf(['plot([0 4 4 7]+' num2str(shiftx) ', [8 8 0 0]+' num2str(shifty) ');\n']) sprintf(['plot([1 4 6]+' num2str(shiftx) ', [6 3 6]+' num2str(shifty) ');'])
            ];
        symbolsString = [symbolsString newline triggerString];
    elseif dlgSett.ExternalReset == 4 % Either
        triggerString = [sprintf(['plot([0 4 4 7]+' num2str(shiftx) ', [0 0 8 8]+' num2str(shifty) ');\n']) sprintf(['plot([1 4 6]+' num2str(shiftx) ', [3 6 3]+' num2str(shifty) ');\n']) sprintf(['plot([0 4 4 7]+8+' num2str(shiftx) ', [8 8 0 0]+' num2str(shifty) ');\n']) sprintf(['plot([1 4 6]+8+' num2str(shiftx) ', [6 3 6]+' num2str(shifty) ');'])
            ];
        symbolsString = [symbolsString newline triggerString];
    elseif dlgSett.ExternalReset == 5 % Level
        triggerString = sprintf(['plot([0 2 2 5 5 7]+' num2str(shiftx) ', [0 0 8 8 0 0]+' num2str(shifty) ');']);
        symbolsString = [symbolsString newline triggerString];
    end
end

%% Plot saturation symbol
if dlgSett.isDialogLimitOutput
    satString = sprintf(['plot([0 4 6 10]+' num2str(satshiftx) ', [0 0 8 8]+' num2str(satshifty) ');\n']);
    symbolsString = [symbolsString newline satString];
end

%% Plot saturation symbol for external limits
if dlgSett.isDialogUseExternalSatLimits
    satString = sprintf(['plot([0 4 6 10]+' num2str(satupx) ', [0 0 8 8]+' num2str(satupy) ');\n']);
    symbolsString = [symbolsString newline satString];
    satString = sprintf(['plot([0 4 6 10]+' num2str(satlox) ', [0 0 8 8]+' num2str(satloy) ');\n']);
    symbolsString = [symbolsString newline satString];
end

%% Finalize the Mask Display string
iconstr = [iconstr symbolsString];
end

function [x,y] = getXYofInport(blk,aPortCon,portNum,LEFT,BOTTOM)
    RESETPosY = aPortCon(portNum).Position(2);
    RESETPosX = aPortCon(portNum).Position(1);
    if strcmp(get_param(blk,'Orientation'),'right')
        y = BOTTOM - RESETPosY - 4;
        x = LEFT - RESETPosX - 3;
    elseif strcmp(get_param(blk,'Orientation'),'down')
        y = BOTTOM - RESETPosY - 17;
        x = RESETPosX - LEFT - 6;
    elseif strcmp(get_param(blk,'Orientation'),'left')
        y = BOTTOM - RESETPosY - 4;
        x = RESETPosX - LEFT - 22;
    elseif strcmp(get_param(blk,'Orientation'),'up')
        y = RESETPosY - BOTTOM - 2;
        x = RESETPosX - LEFT - 6;
    end
end
