function handles = makemenu(fig, labels, calls, tags)
%MAKEMENU Create a menu structure.
%	MAKEMENU(FIG, LABELS, CALLS) creates a menu structure in
%	figure FIG according to the order in the string matrix
%	LABELS.  Cascaded menus are indicated by initial '>'
%	characters in the LABELS matrix.  CALLS is a string
%	matrix containing callbacks.  It should have the same
%	number of rows as LABELS.  A row of LABELS that contains
%	any number of '-' characters after the '>' indicators
%	causes a separator line to be placed in the appropriate
%	place.
%
%	MAKEMENU(FIG, LABELS, CALLS, TAGS) uses the TAGS string
%	matrix to assign the corresponding 'Tag' property of each
%	uimenu item.
%
%	LABELS, CALLS, and TAGS must have the same number of
%	rows.
%
%	H = MAKEMENU( ... ) returns a vector containing the
%	handles of all uimenu objects created.
%
%	Example:
%	labels = str2mat( ...
%	  '&File', ...
%	  '>&New^n', ...
%	  '>&Open', ...
%	  '>>Open &document^d', ...
%	  '>>Open &graph^g', ...
%	  '>-------', ...
%	  '>&Save^s', ...
%	  '&Edit', ...
%	  '&View', ...
%	  '>&Axis^a', ...
%	  '>&Selection region^r' ...
%	  );
%       calls = str2mat( ...
%	  '', ...
%	  'disp(''New'')', ...
%	  '', ...
%	  'disp(''Open doc'')', ...
%	  'disp(''Open graph'')', ...
%	  '', ...
%	  'disp(''Save'')', ...
%	  '', ...
%	  '', ...
%	  'disp(''View axis'')', ...
%	  'disp(''View selection region'')' ...
%	  );
%	handles = makemenu(gcf, labels, calls);

%	Steven L. Eddins, 27 May 1994
%	Copyright (c) 1984-1994 by The MathWorks, Inc.
%	$Revision: 1.6 $  $Date: 1995/05/17 18:23:38 $

num_objects = size(labels,1);
if (num_objects ~= size(calls,1))
  error('LABELS and CALLS must have the same number of rows.');
end
if (nargin == 4)
  if (num_objects ~= size(tags,1))
    error('LABELS and TAGS must have the same number of rows.');
  end
end

remember_handles = fig;
handles = [];
current_level = 0;

tagStr = setstr([]);
for k = 1:num_objects

  labelStr = labels(k,:);
  % The next two lines are a fast replacement for calling deblank.
  loc = find(labelStr ~= ' ');
  labelStr(max(loc)+1:length(labelStr)) = [];
  if (nargin == 4)
    tagStr = tags(k,:);
    % The next two lines are a fast replacement for calling deblank.
    loc = find(tagStr ~= ' ');
    tagStr(max(loc)+1:length(tagStr)) = [];
  end
  
  % Determine which object to attach to by checking the level.
  loc = find(labelStr ~= '>');
  if (isempty(loc))
    error(str2mat('Label strings must have at least one character', ...
	'that''s not a ">"'));
  end
  new_level = loc(1) - 1;
  labelStr = labelStr(loc(1):length(labelStr));
  if (new_level > current_level)
    remember_handles = [remember_handles handles(length(handles))];
  elseif (new_level < current_level)
    N = length(remember_handles);
    remember_handles(N-(current_level-new_level)+1:N) = [];
  end
  current_level = new_level;

  if (labelStr(1) == '-')
    separatorFlag = 1;
  else
    if (separatorFlag)
      separator = 'on';
      separatorFlag = 0;
    else
      separator = 'off';
    end
  
    % Preprocess the label.
    [labelStr, acc] = menulabel(labelStr);
    if (isempty(labelStr))
      error('Empty label field.');
    end
    
    % Note:  much of the overhead in this function is spent in calls
    % to deblank.  So we're going to trade off speed for figure memory
    % overhead and not deblank the callback string.
    h = uimenu(remember_handles(length(remember_handles)), ...
	'Label', labelStr, 'Accelerator', acc, 'Callback', calls(k,:), ...
        'Separator',separator,...
	'Tag', tagStr);
    
    handles = [handles ; h];
  end

end

