function res = drawtree(tree, linewidth,varargin)
% drawtree(tree, [linewidth])
% nodes should have at least two components
% value: the value to print out
% branches as a cell array. These should be {} if there are no branches
% If a node has a field named "vertical", this should specify where the
% node is to be drawn on the vertical axis.  Otherwise, when drawing trees
% the logical position in the tree will be used.
% optional arguments (args 3 and beyond) are passed to the text handle graphics
% e.g., 'FontSize', and 'Rotation'
if nargin >= 2
    params.linewidth = linewidth;
else
    params.linewidth = 1;
end

rotateleaves = 0;

if isleaf(tree)
   dispstring = tostring(tree.value);
   collect;
   clf;
   collect(maketext(dispstring,0,0,varargin{:}));
   drawset(collect);
   axis off;
   return;
end

counter(0);
res = positiontreehelper2(tree,0);
collect; % initialize the collection
drawtreehelper(res,0,varargin{:});
clf; % clear the figure
drawset(collect,params);
axis off;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Space the leaf nodes horizontally evenly, and the parents centered above them
function res = positiontreehelper2(tree, depth)
if length(tree.branches) == 0
   % it's a leaf
   res.horiz = counter;
   res.branches = {};
else
   pos = [];
   res.branches = cell(1,length(tree.branches));
   for k=1:length(tree.branches)
      res.branches{k} = positiontreehelper2(tree.branches{k}, depth-1);
      pos = [pos, res.branches{k}.horiz];
   end
   res.horiz = mean(pos);
end

if isfield(tree, 'vertical')
   res.depth = tree.vertical;
else
   res.depth = depth;
end

if ~isfield(tree,'value') | isempty(tree.value)
   res.value = '';
else
   res.value = tree.value;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function res = drawtreehelper(tree,rotateleaves,varargin)
str = tostring(tree.value);
if length(tree.branches) == 0
   % it's a leaf node
   collect(maketext(str, tree.horiz, tree.depth-.2,'Rotation', rotateleaves, varargin{:}));
else
   collect(maketext(str, tree.horiz + .2, tree.depth,varargin{:}));
end

for k=1:length(tree.branches)
   collect(makeline(tree.horiz, tree.branches{k}.horiz, ...
      tree.depth, tree.branches{k}.depth, varargin{:}));
   drawtreehelper(tree.branches{k},rotateleaves, varargin{:});
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function res = collect(arg)
% call with no arguments to initialize or to reset
persistent collection;
if isempty(collection)
   collection = {}; % an empty cell array
end
if nargin == 1;
   collection{length(collection)+1} = arg;
   res = {};
else
   res = collection;
   collection = {};
end



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function res = counter(arg)
persistent count;
if isempty(count)
   arg = 0;
end
if nargin == 1
   count = arg;
else
   count = count + 1;
end
res = count;

%%%%
function str = tostring(arg)
if isempty(arg)
   str = '[empty]';
elseif ischar(arg)
   str = arg;
elseif isnumeric(arg)
   str = num2str(arg);
   if length(arg) > 1
      str = ['[', str, ']'];
   end
else
   str = 'Unknown type.';
end
