function h = gline(fig)
%GLINE Draw a line in a figure interactively.
%   GLINE(FIG) draws a line segment by clicking the mouse at the
%   two end-points of the line segment in the figure FIG.
%   A rubberband line tracks the mouse movement. 
%   H = GLINE(FIG) Returns the handle to the line.
%
%   GLINE with no input arguments draws in the current figure.

%   B.A. Jones 2-8-95
%   Copyright (c) 1993-96 by The MathWorks, Inc.
%   $Revision: 2.3 $  $Date: 1996/02/21 18:34:00 $

if nargin<1, 
  draw_fig = gcf;
  fig = draw_fig;
  s = 'start'; 
end

if isstr(fig), 
   s = fig;
   draw_fig = findobj(0,'Tag','drawfig');
else
   s = 'start';
   draw_fig = fig; 
end

if strcmp(s,'start')
   set(draw_fig,'Tag','drawfig'),
   ax = gca;
   
   % Create an invisible line to preallocate the xor line color.
   xlimits = get(ax,'Xlim');
   x = (xlimits + flipud(xlimits))./2;
   ylimits = get(ax,'Ylim');
   y = (ylimits + flipud(ylimits))./2;
   hline = line(x,y,'Visible','off','eraseMode','xor');
   if any(get(ax,'view')~=[0 90]), 
     error('Works only for 2-D plots.');
   end

   bdown = get(draw_fig,'WindowButtonDownFcn');
   bup = get(draw_fig,'WindowButtonUpFcn');
   bmotion = get(draw_fig,'WindowButtonMotionFcn');
   set(draw_fig,'WindowButtonDownFcn','gline(''down'')')
   set(draw_fig,'WindowButtonMotionFcn','gline(''motion'')')
   set(draw_fig,'WindowButtonupFcn','')
   uicontrol('Style','text','UserData',hline,...
             'Tag','myline','Visible','off');
  
   smat = str2mat(bdown,bup,bmotion);
   uicontrol('Style','text','UserData',smat,...
             'Tag','bstates','Visible','off');

   pts_obj = uicontrol('Style','text','Tag','points','Visible','off',...
             'UserData',zeros(2,2));

   if nargout == 1
      h = hline;
   end

elseif strcmp(s,'motion'),
   set(draw_fig,'Pointer','crosshair');
   pts_obj = findobj(draw_fig,'Tag','points');
   pts = get(pts_obj,'UserData');
   if pts == zeros(2,2);
      return;
   end
   myline = findobj(draw_fig,'Tag','myline');
   hline = get(myline,'UserData');
   set(hline,'Xdata',pts(:,1),'Ydata',pts(:,2),'eraseMode','xor', ...
        'linestyle','-', 'linewidth', 1.5, 'Color','w','Visible','on');
   Pt2 = get(gca,'CurrentPoint'); 
   Pt2 = Pt2(1,1:2);    
   pts(2,:) = Pt2;
   set(hline,'Xdata',pts(:,1),'Ydata',pts(:,2));

elseif strcmp(s,'down')
   pts_obj = findobj(draw_fig,'Tag','points');
   pts = get(pts_obj,'UserData');

   myline = findobj(draw_fig,'Tag','myline');
   hline = get(myline,'UserData');
   
   Pt1 = get(gca,'CurrentPoint'); 
   pts = [Pt1(1,1:2); Pt1(1,1:2)];
   set(hline,'Xdata',pts(:,1),'Ydata',pts(:,2),'eraseMode','xor', ...
        'linestyle','-', 'linewidth', 1.5, 'Color','w','Visible','on');
   set(pts_obj,'UserData',pts);
   myline = findobj(draw_fig,'Tag','myline');
   set(myline,'UserData',hline);   
   set(draw_fig,'WindowButtonDownFcn','gline(''down2'')')
   
elseif strcmp(s,'down2')
   myline = findobj(draw_fig,'Tag','myline');
   hline = get(myline,'UserData');

   pts_obj = findobj(draw_fig,'Tag','points');
   pts = get(pts_obj,'UserData');

   Pt2 = get(gca,'CurrentPoint'); Pt2 = Pt2(1,1:2);    
   pts(2,:) = Pt2;
   set(hline,'Xdata',pts(:,1),'Ydata',pts(:,2),'eraseMode','normal', ...
         'linestyle','-', 'linewidth', 1.5, 'Color','w');

   bstate = findobj(draw_fig,'Tag','bstates');
   ud = get(bstate,'UserData');
   
   bdown   = ud(1,:);
   bup     = ud(2,:);
   bmotion = ud(3,:);
    
   set(draw_fig,'windowbuttondownfcn',bdown,'windowbuttonupfcn',bup, ...
         'windowbuttonmotionfcn',bmotion,'Pointer','arrow')
   
   delete(myline);
   delete(pts_obj);
   delete(bstate);
else
   error('Invalid call-back.');
end




