function [changed, skipped] = slRemoveDataTypeAndScale(system, update, verbose)
%SLREMOVEDATATYPEANDSCALE Remove unnecessary calls to
%  slDataTypeAndScale('DT', 'Scale') for DataTypeStr parameters of blocks
%  within a Simulink model and replace them with an equivalent built-in or
%  user-defined (e.g. fixdt) fully-specified data type.
%
%  This function:
%   - Finds the DataTypeStr parameters specified using slDataTypeAndScale('DT',
%     'Scale') for blocks within the model. (This includes the blocks inside
%     masked subsystems but excludes the blocks inside library blocks.)
%   - Determines whether this slDataTypeAndScale() can be safely replaced
%     with an equivalent built-in or user-defined data type, depending on
%     the contents of 'DT' and 'Scale'. 
%   - Proposes changes for those  slDataTypeAndScale()'s that can be safely
%     replaced automatically and performs replacement if requested.
%   - Reports the list of slDataTypeAndScale()'s that require manual
%     inspection to determine whether the calls can be safely replaced.
%
%  Limits of Usage:
%   - Searches for slDataTypeAndScale excludes blocks inside library blocks.
%   - Does not remove unnecessary calls to slDataTypeAndScale if the model is 
%     a library.
%   - Assumes variables referenced by the model can be resolved successfully 
%     and correctly.
% 
%  Syntax:
%    [supported, skipped] = slRemoveDataTypeAndScale(system, update, verbose)
%
%    Arguments:
%     -system (required):   name/handle of a loaded model, a subsystem or
%                           block in that model.
%     -update (optional):   0: check only;
%                           1: update parameter (default);
%     -verbose (optional):  0: silent; 
%                           1: show info about the supported cases;
%                           2: show info about the supported and skipped cases (default);    
%                         
%    Returns:
%     -changed:    an array of structures for cases that can be
%                  automatically replaced.
%     -skipped:    an array of structures for cases that require manual
%                  inspection.
%
%  See also slDataTypeAndScale.

%  Supported cases for slDataTypeAndScale('DT', 'Scale') removal:
%   1. 'DT' is fully specified, 
%       Case 1.1. the block is NOT under masked subsystem.
%       Case 1.2. the block is under the masked subsystem with 'DT'
%                 specified via sint, uint, fixdt, sfrac, ufrac or float.
%   2. 'DT' is NOT fully specified but is specified via sfix, ufix, fixdt,
%       and 'Scale' is specified via any below,
%       Case 2.1. one scalar value expression that does not contain variables.
%       Case 2.2. one expression which contains variables.
%       Case 2.3. an array of two elements, each can be a variable, or an
%                 expression containing no white-space. 
%
%   Case 1.1:
%   o    slDataTypeAndScale('foo', 'Scale') ==> foo
%   o    slDataTypeAndScale('foobar(...)', 'Scale') ==> foobar(...)
%   Case 1.2:
%   o    slDataTypeAndScale('uint(b)', 'Scale') ==> uint(b)
%   o    slDataTypeAndScale('sint(b)', 'Scale') ==> sint(b)    
%   o    slDataTypeAndScale('ufrac(b)', 'Scale') ==> sfrac(b)    
%   o    slDataTypeAndScale('sfrac(b)', 'Scale') ==> sfrac(b)    
%   o    slDataTypeAndScale('float(str)', 'Scale') ==> float(str)     
%   o    slDataTypeAndScale('float(b, c)', 'Scale') ==> float(b, c)     
%   o    slDataTypeAndScale('fixdt(str)', 'Scale') ==> fixdt(str)
%   o    slDataTypeAndScale('fixdt(a, b, c)', 'Scale') ==> fixdt(a, b, c)
%   Case 2.1:
%     Let power2 be a numeric expression equal to 2^exponent, where exponent
%     is an integer.
%   o    slDataTypeAndScale('sfix(b)', 'power2') ==> fixdt(1, b, -exponent)
%   o    slDataTypeAndScale('fixdt(a, b)', 'power2') ==> fixdt(a, b, -exponent) 
%     Let npower2 be any other numeric expression, e.g. 1.5, 1.2*2^-2.
%   o    slDataTypeAndScale('ufix(b)', 'npower2') ==> fixdt(0, b, npower2, 0)
%   o    slDataTypeAndScale('fixdt(a, b)', 'npower2') ==> fixdt(a, b,
%        npower2, 0) 
%   Case 2.2:
%     Let expr be any expression that evaluates to a scalar value one. 
%   o    slDataTypeAndScale('sfix(b)', '2^expr') ==> fixdt(1, b, 2^expr, 0)
%   o    slDataTypeAndScale('ufix(b)', 'expr') ==> fixdt(0, b, expr, 0)
%   o    slDataTypeAndScale('fixdt(a, b)', '2^expr') ==> fixdt(a, b, 2^expr, 0)
%   o    slDataTypeAndScale('fixdt(a, b)', 'expr') ==> fixdt(a, b, expr, 0)
%   Case 2.3:
%     Let Par1 and Par2 each be a numeric values, a variables, or an 
%     expressions containing no white-space. 
%   o    slDataTypeAndScale('sfix(b)', '[Par1, Par2]') ==> fixdt(1, b, Par1,
%        Par2) 
%   o    slDataTypeAndScale('fixdt(a, b)', '[Par1  Par2]') ==> fixdt(a, b,
%        Par1, Par2)
%
%  Skipped cases listed for user inspection:
%   1. The model is a library model.
%   2. The block is under a masked subsystem and 'DT' is fully specified
%      via any below,
%      2.1. a variable, e.g. foo
%      2.2. a function other than sint, uint, fixdt, sfrac, ufrac, and
%           float, e.g. foobar(a,b)
%   3. 'DT' is NOT fully specified, 
%      3.1. 'DT' is NOT specified via a function sfix, ufix or fixdt, e.g.
%           foobar(a)
%      3.2. 'DT' is specified via a function sfix, ufix or fixdt, and
%           'Scale' is specified via any below
%        3.2.1. a single variable but does not resolve to a scalar value.
%        3.2.2. an array of two elements, either of which is an expression
%               containing one or more white-spaces.
%        3.2.3. an array of more than two elements. 
%
%   Copyright 2008-2011 The MathWorks, Inc.
%        

if ( nargin == 0 )
    disp(DAStudio.message('Simulink:fixedandfloat:slRmDTNoArg'));
    return;
elseif ( nargin < 2 )
    update = 1;
    verbose = 2;
elseif ( nargin < 3 )
    verbose = 2;
end

[changed, skipped, ~] = slprivate('slRemoveDataTypeAndScale_private', system, update, verbose);
