function m = set(m,varargin)
%SET Set object properties
%    
%    SET(M,'ATTRNAME1',ATTRVALUE1,'ATTRNAME2',ATTRVALUE2,...)
%    sets the value of the attribute ATTRNAME1, ATTRNAME2, ...
%    associated to the object M.
%    
%    M_OUT =
%    SET(M,'ATTRNAME1',ATTRVALUE1,'ATTRNAME2',ATTRVALUE2,...)
%    sets the value of the attribute ATTRNAME1, ATTRNAME2, ...
%    associated to the object M and return the modified model
%    inside m_out. The original model is not modified. The
%    following ATTRNAME are recognised:
%    
%      NAME: sets the name of the system
%      N_IN: sets the number of inputs of the system
%      N_OUT: sets the number of outputs of the system
%      DATA: sets the data set linked to the system
%      T: sets the sampling period of the discrete system, 0
%          if continuous
%      MAPPING: sets the array of mappings
%      LINKS: sets the links array which defines which
%          output is computed by which mapping
%      LIMITS: sets the limits of the domain of definition
%          of the mapping. The value must be a 2*N_IN matrix
%          where the upper and lever saturation level are
%      USERDATA: sets the 'userData' field
%      OPT: sets the 'opt' field
%      DATE: sets the date of creation of the object
%      MAPFIELD: let the user access directly property of
%          the mappings. When used, VALUE must contain a 3
%          elements cell array {N 'property' MAPVALUE}. N is
%          the index of the	mapping, 'property' is the name
%          of the property which has to be changet and
%          MAPVALUE is the new value. An even more
%          convenient way to change mappings' fields is a
%          achieved through the syntax s{n}.property =
%          mapvalue. In both syntax, if N is negative, the
%          <CODE>abs(n)</CODE> mapping describing the state
%          is accessed.
%      PARAMS: sets the parameters to be optimised
%      N_STATE: sets the number of states
%      STATE: sets the state vector of the system
%      STATEMAPPING: sets the mappings used to describe the
%          state
%      STATELINKS: sets the links array which defines which
%          state is computed using which statemapping
%      STATELIMITS: sets the bounds of the states
%    
%    See also: GET
%    
%    

%MAN_PAGE_BEGIN
%
%		@purpose	Set object properties.
%
%		@synopsis		set(m,'AttrName1',AttrValue1,'AttrName2',AttrValue2,...)
%		@description	sets the value of the attribute <code>AttrName1</code>, <code>AttrName2</code>, ...
%		associated to the object <code>m</code>.
%
%		@synopsis		m_out = set(m,'AttrName1',AttrValue1,'AttrName2',AttrValue2,...)
%		@description	sets the value of the attribute <code>AttrName1</code>, <code>AttrName2</code>, ...
%		associated to the object <code>m</code> and return the modified model inside m_out. The original
%		model is not modified.
%
%		The following <CODE>AttrName</CODE> are recognised:
%
%<dl>
%<dt>		name  <dd>	sets the name of the system
%<dt>     n_in  <dd>      	sets the number of inputs of the system
%<dt>     n_out  <dd>     	sets the number of outputs of the system
%<dt>			data <dd>		sets the data set linked to the system
%<dt>			T <dd>		sets the sampling period of the discrete system, 0 if continuous
%<dt>			mapping <dd>		sets the array of mappings
%<dt>			links <dd>			sets the links array which defines which output is computed by which mapping
%<dt>	 limits	 <dd>				sets the limits of the domain of definition
%								of the mapping. The value must be a <code>2*n_in</code> matrix where
%													the upper and lever saturation level are
%<dt>			userData <dd>		sets the 'userData' field
%<dt>			opt			 <dd>		sets the 'opt' field
%<dt>			date		 <dd>		sets the date of creation of the object
%<dt>	 mapfield	 <dd>	let the user access directly property of the mappings. When used, <CODE>value</CODE>
%must contain a 3 elements cell array {<code>n</code> 'property' <CODE>mapvalue</CODE>}. <code>n</code> is the index of the 
%mapping, 'property' is the name of the property which has to be changet and <CODE>mapvalue</CODE> is the new value. An even more convenient
%way to change mappings' fields is a achieved through the syntax s{n}.property = mapvalue. In both syntax,
%if <CODE>n</CODE> is negative, the <CODE>abs(n)</CODE> mapping describing the state is accessed.
%<dt>			params		 <dd>		sets the parameters to be optimised
%<dt>			n_state <dd>		sets the number of states
%<dt>			state <dd>			sets the state vector of the system
%<dt>			statemapping <dd>		sets the mappings used to describe the state
%<dt>			statelinks <dd>			sets the links array which defines which state is computed using which statemapping
%<dt>			statelimits <dd>			sets the bounds of the states
%</dl>
%
%		@see get
%
%MAN_PAGE_END		


% Check that we have the right number of inputs
ni = nargin;
if (ni<3)|(ni/2 == floor(ni/2)),
	error('Wrong number of inputs'); %
end

if ~isa(m,'system'),
	% Call built-in SET. Handles calls like set(gcf,'user',system)	
	builtin('set',m,varargin{:});
	return
end

% For each couple of inputs
for i=1:(ni - 1)/2,
	name = varargin{i*2-1};
	value = varargin{i*2};
	
	if isstr(name),
		switch lower(name),

%
%	n_state property
%	-------------		
case 'n_state',
	error(checkval(value,'intpos','n_in property',{1 1 0},[1 inf]));
	m.n_state = value;
	m.statelimits=[[-inf;inf] * ones(1,m.n_state)];

%
%	state property
%	-------------		
case 'state',
	error(checkval(value,'real','state property',{1 get(m,'n_state') 0}));
	lims = get(m,'statelimits');
	m.state = max(min(value,lims(2,:)),lims(1,:));

%
%	statemapping property
%	-------------		
case 'statemapping',
	error(checkval(value,'cell','mapping property',{1 -1 0},'mapping'));
	m.statemapping = value;

%
%	statelinks property
%	-------------		
case 'statelinks',
	error(checkval(value,'intpos','links property',{get(m,'n_state') 2 0},[1 inf]));
	m.statelinks = value;

%
%	statelimits property
%	-------------		
case 'statelimits',
	error(checkval(value,'real','limits property',{2 get(m,'n_state') 0},[-inf inf],{'ascending' 'any'}));
	m.statelimits=value;

%
%	other functionalities
%	---------------------
case 'mapfield',
	error(checkval(value,'cell','mapfield property'));
	error(checkargs(value, 3, 'numeric', 'char', 'any'));
	if value{1}>0,
		m.system.mapping{value{1}} = set(m.system.mapping{value{1}}, value{2}, value{3});
	else
		m.statemapping{-value{1}} = set(m.statemapping{value{1}}, value{2}, value{3});
	end
	
		
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

		otherwise
			m.system = set(m.system,name,value);
		end
	else
		error('Arguments mismatch');
	end
end

if nargout == 0,
	assignin('caller',inputname(1),m)
end

