function schema = hdlContextMenu(fcnname, callbackInfo)
%HDLCONTEXTMENU - Handles HDL coder context menu

%   Copyright 2012-2023 The MathWorks, Inc.

if ~isempty(fcnname)
    if isa(fcnname, 'SLM3I.CallbackInfo')
        callbackInfo = fcnname;
    else
        fnc = str2func(fcnname);
        if strcmp(fcnname(end-1:end), 'CB')
            % Callbacks come here only when called from the SL toolstrip; the
            % callbacks have no return value.
            fnc(callbackInfo);
        end
    end
end

model = callbackInfo.model;
modelName = model.Name;
blockType = get_param(modelName, 'BlockDiagramType');
import matlab.internal.capability.Capability;

% Do not add HDL item if HDL is not available.
if hdlcoderui.isslhdlcinstalled 
    if strcmpi(blockType, 'model') % otherwise, it can be a library block!
        schema = DAStudio.ContainerSchema;
        schema.label = DAStudio.message( 'HDLShared:hdldialog:hdlccHDLCodermenuname' );
        
        schema.tag = 'Simulink:ContextHDLMenu';
        hdlcc = gethdlcc(modelName);
        if ~isempty(hdlcc)
            schema.childrenFcns = ...
                {...
                @HDLModelChecker, ...
                @CheckHDL, ...                
                'SEPARATOR', ...
                @GenerateHDL, ...
                'SEPARATOR', ...
                @HDLCoderOptions, ...
                @HDLCoderBlockProps, ...
                'SEPARATOR' ...
                };
            if Capability.isSupported(Capability.LocalClient)
                % Desktop client
                schema.childrenFcns = [schema.childrenFcns, ...
                    {@HDLWorkflowAdvisor, ...
                    'SEPARATOR', ...
                    @HDLCodeTrace, ...
                    }];
            else
                % Online client - WorkFlow Advisor not listing
                schema.childrenFcns = [schema.childrenFcns, ...
                    {@HDLCodeTrace, ...
                    }];
            end
        else
            schema.childrenFcns = ...
                {...
                @AddHDLCoderCC,...
                };
        end
    else
        schema = HDLCoderBlockProps(callbackInfo);
    end
    % The default is 'Locked'. The other possible value is 'Never'.  This is
    % described in the shipping documentation; search for 'autodisableWhen'.
    schema.autodisableWhen = 'Busy';
else
    schema = DAStudio.ContainerSchema;
    schema.state = 'Hidden';
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function schema = AddHDLCoderCC(~)
schema = DAStudio.ActionSchema;
schema.tag = 'Simulink:HDLC_AddHDLCoder';
schema.label = DAStudio.message('HDLShared:hdldialog:menuitemAddHDLCoder');
schema.callback = @AddHDLCoderCCCallback;

if hdlcoderui.isslhdlcinstalled
    schema.state = 'Enabled';
else
    schema.state = 'Disabled';
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function AddHDLCoderCCCallback( callbackInfo )
attachhdlcconfig( callbackInfo.model.Name );
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function schema = HDLCodeTrace( callbackInfo )
schema = DAStudio.ActionSchema;
schema.tag = 'Simulink:HighlightHDLCode';
schema.label = DAStudio.message('HDLShared:hdldialog:menuitemNavigateToCode');
schema.callback = @HighlightHDLCodeTraceCB;
schema.autodisableWhen = 'Busy';

% Add check for availability of generated traceability file.
schema.state = 'Disabled';

model = callbackInfo.model;
modelName = model.Name;
enabled = coder.internal.slcoderReport('enableHighlightHDLCodeMenu', modelName);
if(enabled)
    schema.state = 'Enabled';
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function HighlightHDLCodeTraceCB( callbackInfo )
rtwtrace(callbackInfo.getSelection.handle, 'hdl');
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function schema = HDLModelChecker(~)

schema = DAStudio.ActionSchema;
schema.tag = 'Simulink:HDLModelChecker';
schema.label = DAStudio.message('HDLShared:hdldialog:menuitemHDLModelChecker');
schema.callback = @HDLModelCheckerCallback;
schema.autodisableWhen = 'Busy';

if hdlcoderui.isslhdlcinstalled
    schema.state = 'Enabled';
else
    schema.state = 'Disabled';
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function HDLModelCheckerCallback( callbackInfo )
blkH = callbackInfo.getSelection.handle;
hdlmodelchecker(getfullname(blkH));
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function schema = CheckHDL(callbackInfo)

schema = DAStudio.ActionSchema;
schema.tag = 'Simulink:CheckHDL';
schema.label = DAStudio.message('HDLShared:hdldialog:menuitemCheckHDL');
schema.callback = @CheckHDLCB;
schema.autodisableWhen = 'Busy';

blkH = callbackInfo.getSelection.handle;
if hdlcoderui.isslhdlcinstalled && isBlkSupportedForDut(blkH)
    schema.state = 'Enabled';
else
    schema.state = 'Disabled';
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function CheckHDLCB( callbackInfo )
blkH = callbackInfo.getSelection.handle;
checkhdl(getfullname(blkH));
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function isSupported = isBlkSupportedForDut(blkH)
isSupported = strcmpi(get_param(blkH, 'BlockType'), 'SubSystem') ||...
    strcmpi(get_param(blkH, 'BlockType'), 'ModelReference');
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function schema = GenerateHDL( callbackInfo )

schema = DAStudio.ActionSchema;
schema.tag = 'Simulink:MakeHDL';
schema.label = DAStudio.message('HDLShared:hdldialog:menuitemMakeHDL');
schema.callback = @GenerateHDLCB;
schema.autodisableWhen = 'Busy';

blkH = callbackInfo.getSelection.handle;
if hdlcoderui.isslhdlcinstalled && isBlkSupportedForDut(blkH)
    schema.state = 'Enabled';
else
    schema.state = 'Disabled';
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function GenerateHDLCB( callbackInfo )
% open HDL toolstrip if it is not already open
callbackInfo.studio.getToolStrip.getActionService().executeActionSync('hdlCoderAppAction', true)
% run makehdl
blkH = callbackInfo.getSelection.handle;
makehdl(getfullname(blkH));
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function schema = HDLWorkflowAdvisor( callbackInfo )

schema = DAStudio.ActionSchema;
schema.tag = 'Simulink:HDLWA';
schema.label = DAStudio.message('HDLShared:hdldialog:menuitemHDLWA');
schema.callback = @HDLWorkflowAdvisorCB;
schema.autodisableWhen = 'Busy';

blkH = callbackInfo.getSelection.handle;
if hdlcoderui.isslhdlcinstalled && isBlkSupportedForDut(blkH)
    schema.state = 'Enabled';
else
    schema.state = 'Disabled';
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function HDLWorkflowAdvisorCB( callbackInfo )
blkH = callbackInfo.getSelection.handle;
hdladvisor(getfullname(blkH));
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function schema = HDLCoderBlockProps( callbackInfo ) %#ok<INUSD>
schema = DAStudio.ActionSchema;
schema.tag = 'Simulink:HDLCoderBlockProps';
schema.label = DAStudio.message('HDLShared:hdldialog:menuitemHDLBlockProperties');
schema.callback = @OpenHDLCoderBlockPropsCB;
schema.autoDisableWhen = 'Busy';

if hdlcoderui.isslhdlcinstalled
    schema.state = 'Enabled';
else
    schema.state = 'Disabled';
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function OpenHDLCoderBlockPropsCB( callbackInfo )
blkH = callbackInfo.getSelection.handle;
mdlH = get_param(bdroot,'Handle');
% persistent obj; %Created a persistent object so that the listeners are not affected
% if isempty(obj)
%     obj = {};
% elseif isa(obj,'HDLPropertyInspector')&& strcmpi(hdlfeature('HDLBlockPropertyInspector'),'off')
%     %Deleting the property inspector, once the feature is turned off
%     studio = obj.HDLPropertyInspectorComponent.getStudio;
%     studio.destroyComponent(obj.hpi);
%     obj = {};
% end

if strcmpi(hdlfeature('HDLBlockPropertyInspector'),'off')
    HDLPropertyInspector.clear(mdlH,blkH,true);
    StandaloneHDLPI.clear(blkH,true);
    x = slprops.hdlblkdlg(blkH,true);
    DAStudio.Dialog(x);
else
    StandaloneHDLPI.create(blkH);
end
    
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function schema = HDLCoderOptions( ~ )
schema = DAStudio.ActionSchema;
schema.tag = 'Simulink:HDLCoderOptions';
schema.label = DAStudio.message('HDLShared:hdldialog:menuitemHDLCoderProperties');
schema.callback = @OpenHDLCoderOptionsCB;
schema.autodisableWhen = 'Busy';

if hdlcoderui.isslhdlcinstalled
    schema.state = 'Enabled';
else
    schema.state = 'Disabled';
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function OpenHDLCoderOptionsCB( callbackInfo )
selection = callbackInfo.getSelection;
if ~isempty(selection)
    blkH = callbackInfo.getSelection.handle;
    blkPath = getfullname(blkH);
    mdlName = bdroot(blkPath);
else
    mdlName = bdroot;
end

hcc = gethdlcc(mdlName);
if ~isempty(hcc)
    hcc.createCLI;
    configset.showParameterGroup(mdlName, {DAStudio.message('HDLShared:hdldialog:hdlccHDLCodername')});
end
end

% LocalWords:  Codermenuname autodisable SLM
