function TunableStates = getTunableStates(this, model, varargin)
% GETTUNABLESTATES Get list of all state names in the MODEL.  The names in the
% list will be unique.
%
% Will convert the SimMechanics ground block names in sizes vector to the
% correct block names.

% Author(s): Bora Eryilmaz
% Revised: 
% Copyright 1986-2004 The MathWorks, Inc.
% $Revision: 1.1.6.4 $ $Date: 2004/11/18 23:44:38 $

% State vector names from sizes call
if ~isempty(varargin)
  [sys, x0, x0_str, ts, x0_ts] = deal( varargin{:} );
else
  % Will compile model
  [sys, x0, x0_str, ts, x0_ts] = this.evalModel(model);
end
domain = repmat( {''}, size(x0_str) );

% Suffix for SimMechanics ground blocks in sizes vector.
str = '/_mech_engine/Block#1';

% Find the Ground blocks
blks   = unique(x0_str);
match  = regexp( blks, str, 'once');
GroundBlks = blks( ~cellfun('isempty', match) );

% Replace Ground block names with SimMechanics block names
for ct1 = 1:length(GroundBlks)
  block = regexprep( GroundBlks{ct1}, str, '' );
  
  % Get the state vector manager from the block
  Manager = mech_stateVectorMgr( block );
  
  % State size check (Reported by sizes vector vs. state manager)
  idxs = find( strcmp( x0_str, GroundBlks{ct1} ) );
  if ( length(idxs) ~= length(Manager.X) )
    error('Wrong number of states in sizes vector for the state %s.\n', block);
  end
  
  % Substitute all ground block names with actual block names for this manager.
  for ct2 = 1:length(Manager.BlockStates)
    BlockState = Manager.BlockStates(ct2);
    
    % Find states with "partial" state name matching
    PartialStateName = [ BlockState.BlockName, ':', BlockState.Primitive ];
    tf = strncmp( PartialStateName,Manager.StateNames,length(PartialStateName) );
    
    % Preserve order when replacing block name and domain
    x0_str( idxs(tf) ) = { BlockState.BlockName };
    domain( idxs(tf) ) = { get_param(BlockState.BlockName, 'PhysicalDomain') };
  end
end

% Create return structure
TunableStates = struct('Block', x0_str, 'Domain', domain);

% Make unique at the end.
[dummy, idxs] = unique( {TunableStates.Block} );
TunableStates = TunableStates(idxs)';
