function fptoolcallback(event, modelHndl)
    %FPTOOLCALLBACK Responds to engine events in order to save the shortcuts in
    %an external file.
    
    %   Copyright 2011-2020 The MathWorks, Inc.
    
    
    % Update the FPTDatset mapping if saving under a new name which will change
    % the SID.
    bd = get_param(modelHndl,'Object');
    if (isempty(bd) || ~isa(bd, 'Simulink.BlockDiagram')), return; end
    
    switch lower(event)
        case 'presave'
            fptRepositoryInstance = fxptds.FPTRepository.getInstance;
            oldMdlName = fptRepositoryInstance.getModelNameFromHandle(modelHndl);
            
            newFile = get_param(modelHndl,'FileName');
            [~, newMdlName,~] = fileparts(newFile);
            
            if ~isempty(get_param(modelHndl,'MinMaxOverflowArchiveData'))
                sources = fptRepositoryInstance.getAllSources;
                % We need to reconstruct the SID based on new name
                for i = 1:length(sources)
                    curSource = sources{i};
                    idx = regexp(curSource,['^',regexptranslate('escape',oldMdlName),'$'],'once');
                    if isempty(idx)
                        idx = regexp(curSource,['^',regexptranslate('escape',oldMdlName),'\s*:\s*\d+','$'],'once');
                    end
                    % The source needs to be updated
                    if ~isempty(idx)
                        idx1 = regexp(curSource,':','start');
                        if ~isempty(idx1)
                            newSID = [newMdlName curSource(idx1:end)];
                        else
                            newSID = newMdlName;
                        end
                        if ~strcmp(curSource, newSID)
                            fptRepositoryInstance.updateSourceNameForDataset(curSource, newSID);
                            % The new source should match the dataset source
                            % strings. For Model references, the dataset source is the block SID.
                            fxptui.FPTModelSaveAsUtility.updateScopingEngine(curSource, newSID);
                        end
                    else
                        % check if this is a referenced model block that is pointing
                        % to a model that just got renamed.
                        if Simulink.ID.isValid(curSource)
                            blkHndl = Simulink.ID.getHandle(curSource);
                            blkObj = get_param(blkHndl, 'Object');
                            % This additional check only applies to model
                            % reference. All other cases should be resolved in the
                            % above 'if' branch.
                            if isa(blkObj,'Simulink.ModelReference')
                                modelName = get_param(blkHndl,'ModelName');
                                % If the model name points to the one being
                                % renamed, then clear out the results contained.
                                % This gives the same behavior as if the model it
                                % was pointing to was closed (since it it no longer
                                % in memory)
                                idx = regexp(modelName,['^',regexptranslate('escape',oldMdlName),'$'],'once');
                                if ~isempty(idx)
                                    topModel = Simulink.ID.getModel(curSource);
                                    topApplicationData = SimulinkFixedPoint.getApplicationData(topModel);
                                    if topApplicationData.subDatasetMap.isKey(blkHndl)
                                        subDataset = topApplicationData.subDatasetMap(blkHndl);
                                        runNames = subDataset.getAllRunNames();
                                        subDataset.clearResultsInRuns;
                                        
                                        for ridx = 1:numel(runNames)
                                            subDataset.cleanupForRunDeletion(runNames(ridx));
                                        end
                                        
                                    end
                                end
                            end
                        end
                    end
                end
            end
            
            fptInstance = fxptui.FixedPointTool.getExistingInstance;
            if ~isempty(fptInstance)
                topModel = fptInstance.getModelObject;
                shortcutMgr = fptInstance.getShortcutManager;
                % Respond to events only if the FPT object is valid.
                if isequal(topModel, bd)
                    % Update only if the model name is different.
                    if ~strcmpi(newMdlName, oldMdlName)
                        shortcutMgr.updateShortcutsForModelNameChange(bd, oldMdlName);
                    end
                    shortcutMgr.saveShortcuts;
                elseif ~isempty(oldMdlName)
                    % If the model being saved is a referenced model, then just
                    % edit the shortcut maps with the new name.
                    try
                        [refMdls, ~]      = find_mdlrefs(topModel.getFullName);
                        % Update only if the modle name is different.
                        if ~strcmpi(newMdlName, oldMdlName) && any(ismember(refMdls,oldMdlName))
                            shortcutMgr.updateShortcutsForModelNameChange(bd, oldMdlName);
                        end
                    catch mdl_not_found_exception % Model not on path.
                        fxptui.showdialog('modelnotfound',mdl_not_found_exception);
                        return;
                    end
                end
            end
        case 'updatesiglogdata'
        if fixed.internal.utility.featuremanager.FeatureManager.getStatus('fxpoptInFPT') <= 10
            fptInstance = fxptui.FixedPointTool.getExistingInstance;
            if ~isempty(fptInstance) && ~fptInstance.isFPTCallbackSource
                converter = fptInstance.Converter;
                
                % Register the user intent
                % NOTE: for converter workflow through CLI with FPT open
                % this will result in a double registration. Hybrid
                % workflows using CLI with FPT open is not recommended
                % TODO: g2009449 - have all converter events update FPT and
                % do so only once
                currentRunName = get_param(converter.TopModel, 'FPTRunName');
                settings = '';
                
                archiveMode = get_param(converter.TopModel, 'MinMaxOverflowArchiveMode');
                dataLayer = fxptds.DataLayerInterface.getInstance();
                [sdiRunID, fptRunID] = dataLayer.getIdFromRunName(converter.TopModel, currentRunName);
                if strcmp('Merge', archiveMode)
                    % min/max is on and change the intent if it is
                    scenarioRunName = [];
                    [~, scenarioID] = dataLayer.getIdFromRunName(converter.TopModel, scenarioRunName);
                    context = fxptds.WorkflowTopology.WorkflowContextFactory.getContext(fxptds.UserIntent.MergeSimulation, ...
                        'TopModel', converter.TopModel, 'SDIRunID', sdiRunID, ...
                        'FPTRunID', fptRunID, 'Settings', settings, ...
                        'ScenarioFPTRunID', scenarioID, 'ContainerID', 1); % assume 1st workflow for backwards compatability
                else
                    context = fxptds.WorkflowTopology.WorkflowContextFactory.getContext(fxptds.UserIntent.SimpleSimulation, ...
                        'TopModel', converter.TopModel, 'SDIRunID', sdiRunID, ...
                        'FPTRunID', fptRunID, 'Settings', settings, 'ContainerID', 1); % assume 1st workflow for backwards compatability
                end
                
                % get an instance of the registration service
                facade = converter.getWorkflowTopologyFacade();
                facade.register(context);
                
                % post-process the run
                topModel = get_param(fptInstance.getModel,'Object');
                if (isempty(topModel) || ~isa(topModel, 'Simulink.BlockDiagram')), return; end
                
                currHandle = get_param(topModel.getFullName,'Handle');
                if isequal(modelHndl, currHandle)
                    SimulinkFixedPoint.ApplicationData.mergeModelReferenceData(topModel, topModel.FPTRunName);
                    fptInstance.setupCodeView;
                else
                    % FPT root could be a referenced model and the parent was
                    % simulated.
                    try
                        [~, childM] = find_mdlrefs(bd.getFullName);
                    catch mdl_not_found_exception %#ok<NASGU> % Model not on path.
                    end
                    if isempty(childM); return; end % no referenced models
                    try
                        for i = 1:length(childM)
                            childNames = get_param(childM{i}, 'ModelName');
                            if isequal(get_param(childNames,'Handle'),currHandle)
                                SimulinkFixedPoint.ApplicationData.mergeModelReferenceData(topModel, topModel.FPTRunName);
                                fptInstance.setupCodeView;
                                break;
                            end
                        end
                    catch e %#ok<NASGU>
                        disp error% ignore error as model might not be loaded.
                    end
                end
                
                % update FPT View
                fptInstance.updateData('append');
                ed = fxptui.FPTEventDispatcher.getInstance;
                ed.broadcastEvent('DataUpdated',fxptui.UIEventData('done'));
                % This callback is invoked only after InspectLoggedSignals
                % has been processed in
                % DefaultSimulationExecutionInstance.cpp. We will restore
                % the settings here with the assumption that all data has
                % been added.
                fptInstance.notify('SimulationDataCompleteEvent');
            end
        end
        otherwise
            % Do nothing.
    end
end

% [EOF]

% LocalWords:  presave FPT fxptui updatesiglogdata modelnotfound fxpopt
