function [Up,i1]=stack_set(Up,typ,name,val,varargin)

%STACK_SET stack handling routines for use by SDT
%
%       Syntax: Up=stack_set(Up,typ,name,val)
%               [Up,IndPos]=stack_set(Up,SubStack)
%
%       See also : stack_get, stack_rm

%       Etienne Balmes  05/01/01, 14/03/01
%       Copyright (c) 2001-2006 by INRIA and SDTools
%       Use under OpenFEM trademark.html license and LGPL.txt library license
%       All Rights Reserved.

 if ~ischar(Up)
  if ~isfield(Up,'Stack')|~isa(Up.Stack,'cell'); Up.Stack={}; end
 elseif strcmp(Up,'cvs')
  Up='$Revision: 1.6 $  $Date: 2006/04/27 15:47:51 $';return;
 else; error('You must provide a structure for stack_set');
 end
if nargin==2 % set substack
 % two step procedure to bypass pointer callback problems
 r1=struct('Stack',[]);try; r1.Stack=Up.Stack;catch;r1.Stack={};end
 i1=zeros(size(typ,1),1);
 for j1=1:size(typ,1)
   [r1,i1(j1)]=stack_set(r1,typ{j1,1:3});
 end
 Up.Stack=r1.Stack;
elseif nargin>4
  r1=struct('Stack',[]);try; r1.Stack=Up.Stack;catch;r1.Stack={};end
  r1=stack_set(r1,typ,name,val);i1=[];
  for j1=1:3:length(varargin);
   [r1,i1(end+1)]=stack_set(r1,varargin{j1+[0:2]});
  end
  Up.Stack=r1.Stack;

elseif isempty(Up.Stack) % set a new value
 Up.Stack(1,1:3)={typ,name,val};i1=1;
else % search if value exist

 if ~isempty(typ) 
  i1=find(strcmp(typ,Up.Stack(:,1))&strcmp(name,Up.Stack(:,2)));
 elseif ~isempty(name)
  i1=find(strcmp(name,Up.Stack(:,2)));
 end
 if isempty(i1); i1=size(Up.Stack,1)+1;end
 if length(i1)==1
   if isempty(typ) Up.Stack(i1,2:3)={name,val};
   elseif isempty(name) Up.Stack(i1,[1 3])={typ,val};
   else Up.Stack(i1,1:3)={typ,name,val}; end
 else
   sdtw('_nb','Multiple match (%s,%s) in stack_set, probably an error',typ,name);
   Up.Stack(i1(1),1:3)={typ,name,val};
 end

end
