function slicerPopUpAlert(action, arg1, dialogtitle, prefkey)
% SLICERPOPUPALERT Manages and displays the Simulink tip alert window
%
%   SLICERPOPUPALERT('CREATE', MESSAGE, DIALOGTITLE, PREFKEY)
%    Creates the TipAlert dialog:
%      MESSAGE is the message to be shown in the dialog
%      DIALOGTITLE is the dialog title
%      PREFKEY is a unique key for storing the value of the "Do not show again"
%          checkbox.  It must be a valid MATLAB identifier.
%
%   SLICERPOPUPALERT('NEVER', PREFKEY) disables the dialog in future, as if the
%       user had checked the "Do not show again" box in a dialog with this
%       prefkey.
%   SLICERPOPUPALERT('SHOW', PREFKEY) enables the dialog in future, reversing the
%       action of checking the "Do not show again" box.

%   Copyright 2020 The MathWorks, Inc.

narginchk(2,4);

action = lower(action);

switch (action)
  case 'create'
    % We need exactly 4 inputs for creating the dialog.  arg1 is the
    % message string.
    narginchk(4,4);
    
    if i_getpref(prefkey)
        % Launch the TipAlert dialog
        i_create(arg1, dialogtitle, prefkey);
    end
    
  case 'never'
    narginchk(2,2);
    % arg1 is the Preference key
    i_setpref(arg1,false);
    
  case 'show'
    narginchk(2,2);
    % arg1 is the Preference key
    i_setpref(arg1,true);

    otherwise
    DAStudio.error('Simulink:utility:invalidInputArgs',mfilename)

end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function  i_create( strDlgDesc, strTitle, strPrefsKey)

AlertFig=dialog(                                    ...
    'Visible'         ,'off'                       ,...
    'Name'            , strTitle                   ,...
    'Pointer'         ,'arrow'                     ,...
    'Units'           ,'points'                    ,...
    'UserData'        , strPrefsKey                ,...
    'IntegerHandle'   ,'off'                       ,...
    'Resize'          ,'off'                       ,...
    'WindowStyle'     ,'normal'                    ,...
    'HandleVisibility','callback'                  ,...
    'Tag'             ,'TipAlert'                   ...
);
set(AlertFig, 'KeyPressFcn', {@i_keypress,AlertFig});
set(AlertFig, 'DeleteFcn', @(~,~) i_delete(AlertFig));

BtnFontSize=get(0,'FactoryUIControlFontSize');
BtnFontName=get(0,'FactoryUIControlFontName');


% Buttons
OkButtonString=DAStudio.message('Simulink:dialog:DCDOK');
ButtonTag='OK';
ok_btn = uicontrol(AlertFig             ,...
    'Style'              ,'pushbutton'                      ,...
    'Units'              ,'points'                          ,...
    'String'             ,OkButtonString                    ,...
    'HorizontalAlignment','center'                          ,...
    'FontUnits'          ,'points'                          ,...
    'FontSize'           ,BtnFontSize                       ,...
    'FontName'           ,BtnFontName                       ,...
    'Tag'                ,ButtonTag                         ,...
    'Callback'           ,@(~,~) i_ok(AlertFig)              ,...
    'KeyPressFcn'        ,{@i_keypress,AlertFig}             ...
);
OkSize = get(ok_btn,'extent');
        
% Text control for the message
MsgHandle=uicontrol(AlertFig             ,...
    'Style'              ,'text'         ,...
    'Units'              ,'points'       ,...
    'Tag'                ,'strDlgDesc'   ,...
    'FontUnits'          ,'points'       ,...
    'FontSize'           ,BtnFontSize    ,...
    'FontName'           ,BtnFontName    ,...
    'HorizontalAlignment','left'          ...
);

% Checkbox
dontShowAgainStr = DAStudio.message(...
    'Simulink:utility:DoNotShowThisMessageAgain');
checkbox = uicontrol(AlertFig                      ,...
    'Style'              ,'checkbox'               ,...
    'Units'              ,'points'                 ,...
    'String'             , dontShowAgainStr        ,...  
    'Tag'                ,'DontShowAgain'          ,...
    'HorizontalAlignment','left'         , ...    
    'FontUnits'          ,'points'       , ...
    'FontWeight'         ,'bold'         , ...
    'FontSize'           ,BtnFontSize    , ...
    'FontName'           ,BtnFontName     ...
);

% Now calculate positions.  First determine how wide the message will be if
% we allow 65 columns.
[MsgString,MsgSize] = textwrap(MsgHandle,cellstr(strDlgDesc),65);
MsgPos = [10 60 MsgSize(3) MsgSize(4)];
set(MsgHandle,'String',MsgString,'Position',MsgPos);

% Now the button sizes.
% Allow enough columns that the checkbox doesn't try to wrap.
[~,CheckboxSize] = textwrap(checkbox,cellstr(dontShowAgainStr),...
    numel(dontShowAgainStr)+1);

xPadding = 10;
yPadding = 7;

CheckboxWidth = CheckboxSize(3) + 20;
BtnWidth = OkSize(3) + 20;
BtnHeight = OkSize(4) + 3;

% Allow enough space for the wider of the message,the checkbox, or the buttons
FigWidth = max([MsgSize(3),CheckboxWidth, (BtnWidth*3 + xPadding*2)]) + (xPadding*2);

% Position the buttons at the bottom right.
set(ok_btn, 'Position', ...
    [FigWidth - BtnWidth - xPadding, yPadding, BtnWidth, BtnHeight]);

yCounter = yPadding*2 + BtnHeight;
% Position the checkbox above them, at the left hand side.
set(checkbox, 'Position', ...
    [xPadding, yCounter, CheckboxWidth, CheckboxSize(4)]);

yCounter = yCounter + CheckboxSize(4) + yPadding;
% Position the message above that, at the left hand size.
set(MsgHandle, 'Position', ...
    [xPadding, yCounter, MsgSize(3), MsgSize(4)]);

yCounter = yCounter + MsgSize(4) + yPadding;

FigHeight = yCounter;

FigPos=get(0,'DefaultFigurePosition');
FigPos(3:4)=[FigWidth FigHeight];

% Use screen size to position the Figure              
ScreenUnits=get(0,'Units');
set(0,'Units','points');
ScreenSize=get(0,'ScreenSize');
set(0,'Units',ScreenUnits);

FigPos(1)=(ScreenSize(3)-FigWidth)/2;
FigPos(2)=(ScreenSize(4)-FigHeight)/2;

set(AlertFig ,'Position',FigPos);
set(AlertFig ,'Visible','on');
drawnow;

% If we have a model open, attach a callback to it which will close this
% dialog when the model closes.
mdl = bdroot;
if ~isempty(mdl)
    Simulink.addBlockDiagramCallback(mdl,'PreClose',strPrefsKey,@() i_delete(AlertFig));
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_ok(fig)

% Our preferences key is the user data on the figure itself.
handles = guihandles(fig);
strPrefsKey = get(handles.TipAlert,'UserData');
i_setpref(strPrefsKey, ~get(handles.DontShowAgain,'Value'));
delete(fig);
mdl = bdroot;
if ~isempty(mdl)
    try
        Simulink.removeBlockDiagramCallback(mdl,'PreClose',strPrefsKey);
    catch%if callback wasnt created, nothing to be deleted, so ignore error
    end
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_delete(fig)

if ishandle(fig)
    delete(fig);
end

mdl = bdroot;
if ~isempty(mdl)
    try
        Simulink.removeBlockDiagramCallback(mdl,'PreClose',strPrefsKey);
    catch%if callback wasnt created, nothing to be deleted, so ignore error
    end
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Return and space dismiss the dialog as if "OK" was clicked.  Escape
% dismissed the dialog as if the "x" in the top-right was clicked.  This
% means that we ignore the state of the "Don't show again" checkbox.
function i_keypress(~,evd,fig)
switch(evd.Key)
  case {'return','space'}
      i_ok(fig);
  case 'escape'
      i_delete(fig);
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Return true if the dialog should be shown.
function show = i_getpref(prefkey)
show = true;
if exist(SlicerConfiguration.mdl2SCMapFile,'file')
    loadMap = load(SlicerConfiguration.mdl2SCMapFile);
    if isfield(loadMap,prefkey)
        show = loadMap.(prefkey);
    end
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_setpref(prefkey,value)
evalc([prefkey ' = value']);
args = {};
if exist(SlicerConfiguration.mdl2SCMapFile,'file') == 2
    args = {'-append'};
end
save(SlicerConfiguration.mdl2SCMapFile,(prefkey),args{:});
end

% LocalWords:  DIALOGDESC DIALOGTITLE HELPTAG FEATURETIPPRESKEY ATIONSTR
% LocalWords:  ACTIONSTR actionstr mwt UI DCDOK DCD Dlg Dont mapfiles


