%% Managing Requirements Without Modifying Simulink Model Files
% Simulink Requirements supports two different ways to store link data for
% Simulink models: you can either embed link data in the |.slx| file, or you
% can store links in an external |.slmx| file (external |.req| file for
% R2017a and earlier releases).
%
% For older Simulink models in |.mdl| format, embedded storage is not
% possible beginning R2017b, you must either store link data externally (in
% a separate |.slmx| file, or you need to upgrade the Simulink model file
% to |.slx| format. You will be prompted to upgrade your data when you load
% such a model for the first time after upgrading to R2017b.
%
% Embedded storage makes it easier to share your work - you do not need to
% keep track of the extra |*.slmx| file, but this has the disadvantage that
% model file is modified every time you add, edit, or delete a requirements
% link. Additionally, when using external |*.slmx| files, you can manage
% multiple sets of requirements links for same model, by configuring your
% session to load one or the other |.slmx| file.

% Copyright 2011-2017 The MathWorks, Inc.

%% Open Example Model
% This example will use the Power Window Controller model to demonstrate how to
% work with externally stored RMI links. 
% <matlab:open_system('slvnvdemo_powerwindowController') Open the model.>
% In case you have experimented with this model before, use 
% |rmimap.map(MODEL,'clear')| command to discard any known |.slmx| file
% mapping before opening the model:

rmimap.map('slvnvdemo_powerwindowController', 'clear'); 
open_system('slvnvdemo_powerwindowController');

%% Configure RMI to Store Links Externally
% Select *Analysis > Requirements Traceability > Settings* and 
% <matlab:rmidemo_callback('settings',0) open the Settings dialog box to
% Storage tab>.
% Click *Store externally* option button. 
%
% <<settings_external.png>>
%
% The default file name for saving requirements links data
% is _ModelName_ |.slmx|. If the file is not present in the model folder, the
% model is assumed to have no links to requirements, as you can verify by
% <matlab:rmidemo_callback('highlight','slvnvdemo_powerwindowController')
% highlighting the model>.

rmipref('StoreDataExternally', true);
rmi('highlightModel', 'slvnvdemo_powerwindowController');

%% Creating and Managing RMI Links
% You create and manage links in exactly same way you do with _internal_
% storage. As an example, create one new link from model to document:
%
% * Open the 
% <matlab:rmidemo_callback('doc','powerwin_reqs\PowerWindowSpecification.docx') |PowerWindowSpecification.docx|> 
% * Find the subheader _passenger input consists of a vector with three elements_ under
% <matlab:rmidemo_callback('doc','powerwin_reqs\PowerWindowSpecification.docx','bookmark','Simulink_requirement_item_1') High Level Discrete Event Control Specification section>,
% * Select the subheader with the mouse
% * Right-click the corresponding 
% <matlab:rmidemo_callback('locate','slvnvdemo_powerwindowController/Mux4') Mux block>
% * Click *Requirements Traceability > Link to Selection in Word*. 
%
% <<PowerWindow_contextMenu.png>>
%
% If the model is still highlighted, the Mux block highlights
% to indicate associated requirements data. Note that the title bar
% does not indicate unsaved changes. New link information is stored
% separately from the model. Simulink warns you that links will be saved in
% a separate file.
%
% <<PowerWindow_model_with_req.png>>
%

testReqLink = rmi('createEmpty');
testReqLink.description = 'testReqLink';
testReqLink.doc = 'powerwin_reqs\PowerWindowSpecification.slreqx';
testReqLink.id = '?passenger input consists of a vector with three elements';
rmi('set', 'slvnvdemo_powerwindowController/Mux4', testReqLink);

%% Saving Requirements Links Data to External Files
% While working with a model that stores RMI data externally,
% changes to requirement links are saved when you:
%
% * *Save* or *Save As* the Simulink model, even if the title bar does not indicate unsaved changes.
% * *Close* the model. You will be prompted to save links changes if any.
% * Use *Save Links...* or *Save Links As...* shortcuts under
% *Analysis > Requirements > Link File* submenu.
% 
% <<PowerWindow_model_menu.png>>
%
% <matlab:close_system('slvnvdemo_powerwindowController') Close the model>.
% You will be prompted about the link that you just created. You may save the links
% file with the default _ModelName_ |.slmx| name in the model directory, or choose
% a different file name and/or location.
% 
% <<PowerWindow_onClose.png>>
%

close_system('slvnvdemo_powerwindowController', 0);

%% Loading Requirements Links from External Files
% When you open a model, RMI will try to load requirements links data from
% the recently used location for this model. You may also select 
% *Analysis > Requirements > Links File > Load links...* to choose a
% different |.slmx| (or an older |.req|) file. This allows
% to use several sets of links with the same model, for example, links to
% design change descriptions that are different from links to original
% design specifications.
% 
% * <matlab:open_system('slvnvdemo_powerwindowController') Reopen the model>,
% select *Analysis > Requirements > Links File > Load links...* to open a file browser and
% point to |slvnvdemo_powerwindowRequirements.slmx| in the 
% <matlab:rmidemo_callback('folder','powerwin_reqs') |toolbox/slrequirements/slrequirementsdemos/powerwin_reqs| folder>.
% 
% * <matlab:rmidemo_callback('highlight','slvnvdemo_powerwindowController') Highlight requirements in the model>
% to confirm that an alternative set of links is now associated with the
% model.  You can navigate and modify these links in the same way you would
% work with _embedded_ (in-model) links.

open_system('slvnvdemo_powerwindowController');
otherReqFile = fullfile(matlabroot, 'toolbox', 'slrequirements', 'slrequirementsdemos', 'powerwin_reqs', 'slvnvdemo_powerwindowRequirements.slmx');
rmimap.map('slvnvdemo_powerwindowController', otherReqFile);
rmi('highlightModel', 'slvnvdemo_powerwindowController');

%% Moving RMI Links from Internal to External Storage
% A model with existing _embedded_ requirements links can be converted
% to _external storage_. Link data will no longer be stored in .slx file,
% but in a new |.slmx| file. To try this out:
%
% * <matlab:open_system('slvnvdemo_fuelsys_officereq') Open another model>
% that has internally stored RMI data.
% * <matlab:save_system('slvnvdemo_fuelsys_officereq','fuelsys_officereq_copy')
% Resave with a new name> to create a writeable copy.
% * Select *Analysis > Requirements > Links File > Save Links As...* to
% open a file browser.
% * Choose a file name for the new external |.slmx| file and click *OK*.
% Model is resaved with no _embedded_ links and a new |.slmx| file is
%
% <<PowerWindow_Links_SaveAs.png>> 
%
% Your ability to use and manage links in this model now depend on the
% external file. 
%
% * <matlab:close_system('fuelsys_officereq_copy') Close the new model>.
% * <matlab:open_system('fuelsys_officereq_copy') Reopen the model>.
% * <matlab:rmidemo_callback('highlight','fuelsys_officereq_copy')
% Highlight requirements> to confirm that the link data is available.
% * Now <matlab:close_system('fuelsys_officereq_copy') close the model again> and
% <matlab:rmidemo_callback('remove','fuelsys_officereq_copy.slmx') delete the external |.slmx| file>.
% * <matlab:open_system('fuelsys_officereq_copy') Reopen the model> and
% <matlab:rmidemo_callback('highlight','fuelsys_officereq_copy') highlight links>.
% Nothing is highlighted because the data is no longer available.
% * <matlab:rmidemo_callback('remove','fuelsys_officereq_copy') Delete the temporary copy> of the model.
% 
% Points to keep in mind before you move internally stored links to an
% external file:
% 
% * You will need to carry an extra |.slmx| file along with the model file.
% * Non-default file name and location associations are stored in user
% preferences. If you move or rename the |.slmx| file outside MATLAB, you will
% have to manually point RMI to the new location when the model is reopened.
% * When one user has configured a non-default location or name for the
% |.slmx| file associated with the model, other RMI users will need  to
% manually select *Load links* when they open the model.
% The specified location will persist in each user's preferences and does
% not need to change unless files are moved or renamed again.

open_system('slvnvdemo_fuelsys_officereq')
tempModelName = 'fuelsys_officereq_copy';
tempModelCopy = fullfile(tempdir, [tempModelName '.slx']);
save_system('slvnvdemo_fuelsys_officereq', tempModelCopy); 
tempLinkFile = strrep(tempModelCopy, '.slx', '_links.slmx');
rmidata.saveAs(tempModelName, tempLinkFile);
rmi('highlightModel', tempModelName);

%% Moving RMI Links from External to Internal Storage
% To _embed_ RMI data with the Simulink model, so that all information is
% in one place and you do not need to track extra files, select *Analysis >
% Requirements > Links File > Copy to Model*. 
% The external |.slmx| file still exists, but it is NOT read when you
% reopen the model that now has _embedded_ RMI data. You can try this out
% with the
% <matlab:open_system('fuelsys_officereq_copy') |fuelsys_officereq_copy| model>.
%
% <<PowerWindow_Links_CopyToModel.png>>
%
% Points to keep in mind before you _embed_ RMI data with the model file:
%
% * Every change to RMI links will modify the model file.
% * External |.slmx| files are disregarded when |.slx| file contains
% traceability links data.

%% Cleanup
% Steps in this example might have created files inside the examples folder
% and modified your stored mapping of |.slmx/.req| file names. 
% <matlab:rmidemo_callback('cleanup') Click to cleanup>.

close_system('slvnvdemo_powerwindowController', 0);  % close demo model, discard changes
tmpfilepath = fullfile(matlabroot, 'toolbox', 'slrequirements', 'slrequirementsdemos', 'slvnvdemo_powerwindowController.slx');
rmimap.map(tmpfilepath, 'clear');     % forget mdl-to-req mappings
tmpfilepath = strrep(tmpfilepath, '.slx', '.slmx');
if exist(tmpfilepath, 'file') == 2, delete(tmpfilepath); end   % delete links file

close_system('fuelsys_officereq_copy', 0);
rmimap.map(tempModelCopy, 'clear');     % forget model to Links File mappings
if exist(tempModelCopy,'file') == 2, delete(tempModelCopy); end    % delete temporary copy of model file
if exist(tempLinkFile, 'file') == 2, delete(tempLinkFile); end   % delete .slmx file we just saved

clear tmpfilepath tempModelCopy tempLinkFile;

rmiut.closeDlg(getString(message('Slvnv:reqmgt:highlightObjectsWithReqs')));  % close popup if still open 


displayEndOfDemoMessage(mfilename)

