function mapstr = htmlareas(items,links)
%  Make HTML code to map objects in a plot to active regions
%
%  Syntax: mapstr = htmlareas(items,links);
%
%  items is a vector of handles to text, line, or patch objects.
%  links is a cell array of strings containing link names,
%
%  mapstr contains the output code, defining an HTML map of active
%  areas.  This only works if the output map is precisely the same size
%  (in pixels) as the figure on the screen.  This can be accomplished
%  with the statements
%
%    set(gcf,'paperpositionmode','auto')
%    print -dpng -r0 figure.png
%
%  However, I've had problems getting some figures with m_contour to show
%  properly with any of the bitmap drivers.  I've had luck with
%
%    set(gcf,'paperpositionmode','auto')
%    print -depsc -loose -r0 figure.eps
%    convert -density 75 figure.eps figure.png
%
%  The density argument value presumably depends on screen resolution,
%  but I haven't chased that down.  You may have to search for the right
%  value on your system.
%
%  To use mapstr, display it and paste it into an HTML file in the
%  following way:
%
%    <MAP NAME="somemap">
%    -->mapstr goes here<--
%    </MAP>
%    <IMG USEMAP="#somemap" SRC="figure.png" ALT="Alternate text">
%
%  BUGS
%
%    This seems to work fine in simple circumstances, but can get confused
%    if the plot box is a different size than the axes.  More work is needed
%    to pin that down.  Patch objects seem to have excess data.  I do not
%    know the cause.  I manually curtail the coordinate string once it
%    starts repeating.  I've only tested htmlareas with very simple
%    polygons--it's probably best not to use anything very complicated.
%
%   Steve Howell  2002/04/22
%

oldfigunits = get(gcf,'Units');
set(gcf,'Units','pixels');
floc = get(gcf,'Position');


fmt = '<AREA SHAPE=%s HREF="%s" COORDS="%s">\n';
cfmt = ' %d';
mapstr = '';

for ii = 1:length(items)
  axH = get(items(ii),'Parent');
  oldaxunits = get(axH,'Units');
  set(axH,'Units','pixels');
  aloc = get(axH,'Position');
  %If the PlotBoxAspect Ratio isn't [1,1,1], then the plot region is
  %smaller than the axes position.  The plot region is what needs to be
  %determined.  This calculation is not well tested!  It may be better to
  %use the dataaspectratio.  In addition, it is unclear whether this
  %calculation is appropriate for text objects.
  pbar = get(axH,'PlotBoxAspectRatio');
  if ~all(pbar==1)
    pbarxy = pbar(1)/pbar(2);		% width:heigh
    axesaspectratio = aloc(3)/aloc(4);
    if pbarxy>axesaspectratio		% plot too wide; some hgt unused
      aydist = aloc(3)/pbarxy;
      aymid = aloc(2)+aloc(4)/2;
      aloc([2,4]) = [aymid-aydist/2, aydist]; % aloc becomes plotbox pos
    else				% not all width used
      axdist = aloc(4)*pbarxy;
      axmid = aloc(1)+aloc(3)/2;
      aloc([1,3]) = [axmid-axdist/2, axdist]; % aloc becomes plotbox pos
    end
    
  end
  
  if strcmp('text',get(items(ii),'Type')) % Text handle?
    atype = '"rect"';
    oldunits = get(items(ii),'Units');
    set(items(ii),'Units','pixels');
    tloc = get(items(ii),'extent');	% text position,pizels

    tloc(3:4) = tloc(1:2)+tloc(3:4);	% from [x y dx dy] to [x y x2 y2]
    tloc = tloc + repmat(aloc(1:2),1,2);% add pixel offset of axes in fig
    tloc([4,2]) = floc(4) - tloc([2,4]);% y is pixels from top
    loc = round(tloc);
    set(items(ii),'Units',oldunits);
  elseif strmatch(get(items(ii),'Type'),{'patch','line'},'exact')
    atype = '"poly"';
    px = get(items(ii),'XData');
    py = get(items(ii),'YData');
    axx = get(axH,'XLim');
    axy = get(axH,'YLim');
    pxp = (px-axx(1))/diff(axx);		% data units to normalized
    pyp = (py-axy(1))/diff(axy);
    pxp = pxp*aloc(3)+aloc(1);		% pixels in figure
    pyp = floc(4) - (pyp*aloc(4)+aloc(2));	% and flipped y
    ploc = reshape([pxp(:)'; pyp(:)'],1,length(px)*2); % format x y x y x y...
    loc = round(ploc);
  else
    error('Only patches, lines, and text are allowed')
  end
  
  coordstr = sprintf(cfmt,loc);
  mapstr = [mapstr sprintf(fmt,atype,links{ii},coordstr)];

  set(axH,'Units',oldaxunits);
end

set(gcf,'Units',oldfigunits);
