function varargout = add(tree,uid,type,parameter)
% XMLTREE/ADD Method (add childs to elements of an XML Tree)
% FORMAT vararout = add(tree,uid,type,parameter)
% 
% tree      - XMLTree object
% uid       - array of uid's
% type      - 'element', 'chardata', 'cdata', 'pi' or 'comment'
% parameter - property name (a character array unless type='pi' for
%             which parameter=struct('target','','value',''))
%
% new_uid   - UID's of the newly created nodes
%
%        tree = add(tree,uid,type,parameter);
%        [tree, new_uid] = add(tree,uid,type,parameter);
%_______________________________________________________________________
%
% Add a node (element, chardata, cdata, pi or comment) in the XML Tree.
% It adds a child to the element whose UID is iud.
% Use attributes({'set','get','add','del','length'},...) function to 
% deal with the attributes of an element node (initialized empty).
% The tree parameter must be in input AND in output.
%_______________________________________________________________________
% @(#)add.m                   Guillaume Flandin                02/03/29

error(nargchk(4,4,nargin));

if ~isa(uid,'double')
	error('[XMLTree] UID must be a double array.');
end
if ~ischar(type)
	error('[XMLTree] TYPE must be a valid item type.');
end
if strcmp(type,'pi')
	if ~isfield(parameter,'target') | ~isfield(parameter,'value') | ...
	   ~ischar(parameter.target) | ~ischar(parameter.value)
		error('[XMLTree] For a Processing Instruction, ',...
						'PARAMETER must be a struct.');
	end
elseif ~ischar(parameter)
	error('[XMLTree] PARAMETER must be a string.');
end

if nargout == 2
	l = length(tree.tree);
	varargout{2} = (l+1):(l+prod(size(uid)));
end

for i=1:prod(size(uid))
	if uid(i)<1 | uid(i)>length(tree.tree)
		error('[XMLTree] Invalid UID.');
	end
	if ~strcmp(tree.tree{uid(i)}.type,'element')
		error('[XMLTree] Cannot add a child to a non-element node.');
	end
	l = length(tree.tree);
	switch type
		case 'element'
			tree.tree{l+1} = struct('type','element',...
        	                        'name',parameter,...
					                'attributes',[],...
					                'contents',[],...
									'parent',[],...
					                'uid',l+1);
		case 'chardata'
			tree.tree{l+1} = struct('type','chardata',...
					                'value',parameter,...
									'parent',[],...
					                'uid',l+1);
		case  'cdata'
			tree.tree{l+1} = struct('type','cdata',...
					                'value',parameter,...
									'parent',[],...
					                'uid',l+1);
		case 'pi'
			tree.tree{l+1} = struct('type','pi',...
									'target',parameter.target,...
					                'value',parameter.value,...
									'parent',[],...
					                'uid',l+1);
		case 'comment'
			tree.tree{l+1} = struct('type','comment',...
					                'value',parameter,...
									'parent',[],...
					                'uid',l+1);
		otherwise
			error(sprintf('[XMLTree] %s: unknown item type.',type));
	end
	tree.tree{uid(i)}.contents = [tree.tree{uid(i)}.contents l+1];
	tree.tree{l+1}.parent = uid(i);
end

varargout{1} = tree;
