function m=check(m); 
%CHECK checks the consistency of all the fields of a
%    external object
%    
%    This function has been provided in order to make the
%    external class more rouboust since it checks a external
%    object for consistency of the data defined in its fields.
%    If a inconsistency is found, an  error message is
%    displayed.
%    
%    CHECK(M) check the consistency of a external object.
%    
%    

%MAN_PAGE_BEGIN
%
%   @purpose checks the consistency of all the fields of a external object.
%   This function has been provided in order to make the external class
%   more rouboust since it checks a external object for consistency of
%   the data defined in its fields. If a inconsistency is found, an 
%   error message is displayed.
%
%   @synopsis	check(m)
%   @description  check the consistency of a external object.
%
%MAN_PAGE_END
  
%this function needs to check the consistency of the object. In this
%case it is necessary to check the consistency of the dynamics field, in
%the same way done in the add_dynamics method, and the consistency
%between the mappings and the dynamical description of the system.  
    
%Check the fields of the system superclass
%check(m.system);
  
%Check the fields
sm = struct(m);
if ~isfield(sm,'dynamics'),
	error('object external should have a ''dynamics'' attribute');
end

if (isfield (m.dynamics,'ny')|isfield (m.dynamics,'nu')|isfield (m.dynamics,'nd')),
        if ~isfield (m.dynamics,'ny')
             error('the field ''dynamics.ny'' is not defined');
        elseif ~isfield (m.dynamics,'nu')  
             error('the field ''dynamics.nu'' is not defined');
        elseif ~isfield (m.dynamics,'nd')  
             error('the field ''dynamics.nd'' is not defined');
        end
	
	error(checkval(m.dynamics.ny,'intpos','''dynamics.ny'''))
	error(checkval(m.dynamics.nu,'intpos','''dynamics.nu'''))
	error(checkval(m.dynamics.nd,'intpos','''dynamics.nd'''))
	
	if size(m.dynamics.ny,1) ~= size(m.dynamics.ny,2),
	     error('''dynamics.ny'' must be a square matrix');
        end
        if size(m.dynamics.nu,2) ~= size(m.dynamics.nd,2),
	     error('''dynamics.nu'' must have the same number of columns as ''dynamics.nd''');
        end
        if size(m.dynamics.ny,1) ~= size(m.dynamics.nu,1),
	     error('''dynamics.ny'' must have the same number of rows as ''dynamics.nu''');
        end		
        if size(m.dynamics.ny,1) ~= size(m.dynamics.nd,1),
	     error('''dynamics.ny'' must have the same number of rows as ''dynamics.nd''');
        end  
end

%Check the number of inputs and the number of outputs
number_inputs = get(m,'n_in');
number_outputs = get(m,'n_out');
if number_inputs>0 & number_outputs>0,
    if isfield (m.dynamics,'ny') & isfield (m.dynamics,'nu') & isfield (m.dynamics,'nd'),
	if number_outputs ~= size(m.dynamics.ny,2),
	  error('mismatch between the number of outputs and the structure of ''dynamics.ny'''); 
	end

	if number_outputs ~= size(m.dynamics.nu,1),
	  error('mismatch between the number of outputs and the structure of ''dynamics.nu'''); 
	end

	if number_outputs ~= size(m.dynamics.nd,1),
	  error('mismatch between the number of autputs and the structure of ''dynamics.nd'''); 
	end

	if number_inputs ~= size(m.dynamics.nu,2)
	  error('mismatch between the number of inputs and the structure of ''dynamics.nu''');
	end
	if number_inputs ~= size(m.dynamics.nd,2)
	  error('mismatch between the number of inputs and the structure of ''dynamics.nd''');
	end 
     end	
end

%now check for the consistency of the mappings
if isfield (m.dynamics,'ny') & isfield (m.dynamics,'nu') & isfield ...
      (m.dynamics,'nd'),
  links=get(m,'links');
  if ~isempty(links),
    mapping=get(m,'mapping');
    %check the number of arguments of all mappings 
    for i=1:get(m,'n_out'),
      if (get(mapping{links(i,1)},'n_in')-sum(m.dynamics.ny(i,:),2)- ...
	  sum(m.dynamics.nu(i,:),2)) ~= 0,
	error(['mismatch between the dynamics and the mapping for output ' num2str(i)]); 
      end
    end
  end
end  



