function h=m_ruler(posx,posy,varargin);
% M_RULER Draws a distance scalebar for a map
%   M_RULER([X1 X2],Y1) draws a horizontal scale bar between the
%   normalized coordinates (X1,Y1) and (X2,Y1) where both X/Y are
%   in the range 0 to 1.  
%   M_RULER(X1,[Y1 Y2]) draws a vertical scalebar
%   M_RULER(...,NINTS) draws the scalebar with NINTS intervals
%   if NINTS is a scalar (default 4).  Distances of each interval are 
%   chosen to be 'nice'. If NINTS is a vector it is understood to be
%   the distances to be used (in meters)
%
%   M_SCALEBAR(....,'parameter','value',...) lets you specify
%   extra parameter/value pairs in the usual handle-graphics way.
%   'color' and 'fontsize' are probably the most useful, 'tickdir'
%   'in' and 'out' chooses between different styles.
%
%   Probably BEST to call this AFTER M_GRID otherwise placement might
%   seem a bit odd.
%
% WARNING - the scalebar is probably not useful for any global
%           (i.e. whole-world) or even a significant-part-of-the-globe
%           map, but I won't stop you using it. Caveat user!

% R. Pawlowicz rich@eos.ubc.ca  8/Nov/2006
% 7/Dec/11 - Octave 3.2.3 compatibility

% Recognize Octave
a=ver;
if strcmp(a(1).Name,'Octave'),
 IsOctave=logical(1);
else
 IsOctave=logical(0);
end;

% I use bitmax in various places as 'a large number', but
% as of 2014b this has been renamed

if verLessThan('matlab','8.3'),
  LARGVAL=bitmax;
else
  LARGVAL=flintmax;
end;    


nints=4;
fixticks=0;

if length(varargin)>0,
 if isnumeric(varargin{1}),
   nints=varargin{1};
   varargin=varargin(2:end);
   fixticks=1;
  end;
end;    

 
gcolor='k';
glinestyle='-';
glinewidth=3;
gfontsize=get(gca,'fontsize');
gfontname=get(gca,'fontname');
gticklen=get(gca,'ticklength'); gticklen=gticklen(1); 
gtickdir=get(gca,'tickdir'); 
 
 
% Parse parameter list for options. I really should do some
% error checking here, but...

k=1;
while k<=length(varargin),
  switch lower(varargin{k}(1:3)),
    case 'col',
      gcolor=varargin{k+1};
    case 'lin',
      switch lower(varargin{k}(1:5)),
         case 'linew',
           glinewidth=varargin{k+1};
         case 'lines',
           glinestyle=varargin{k+1};
      end;
    case 'fon',
       switch lower(varargin{k}(1:5)),
         case 'fonts',
           gfontsize=varargin{k+1};
         case 'fontn',
           gfontname=varargin{k+1};
       end;
    case 'tic',
       switch lower(varargin{k}(1:5)),
         case 'tickl',
           gticklen=varargin{k+1};
         case 'tickd',
           gtickdir=varargin{k+1};
       end;
    case {'get','usa'},
      disp('      ''ticklength'',value');
      disp('      ''tickdir'',( ''in'' | ''out'' )');
      disp('      ''color'',colorspec');
      disp('      ''linewidth'', value');
      disp('      ''linestyle'', ( linespec | ''none'' )');
      disp('      ''fontsize'',value');
      disp('      ''fontname'',name');
       return;
    case 'set',
      disp(['      ticklength = ' num2str(gticklen)]);
      disp(['      tickdir = ' gtickdir]);
       disp(['      color = ' gcolor]);
      disp(['      linewidth = ' num2str(glinewidth)]);
      disp(['      linestyle = ' glinestyle]);
      disp(['      fontsize = ' num2str(gfontsize)]);
      disp(['      fontname = ' gfontname]);
       return;
  end;
  k=k+2;
end;     

 
% Need earth radius, in m.
erad=6378137; %m (from WGS-84)


if  ( length(posx)==2 & length(posy)==1),
  posy=[posy posy];
  horiz=1;
elseif  ( length(posx)==1 & length(posy)==2),
  posx=[posx posx];
  horiz=0;
end;




xlm=get(gca,'xlim');
ylm=get(gca,'ylim');

% Get into screen coords
posx=xlm(1) + posx*diff(xlm);
posy=ylm(1) + posy*diff(ylm);


if diff(xlm)>10, % we are probably already in meters, i.e. UTM
   scfac=1;
else
  scfac=erad;
end;



distance=(diff(posx)+diff(posy))*scfac;


niceints=[ 1      2      5  ...
           10     20     50 ...
	   100    200    500  ...
	   1000   2000   5000  ...
	   10000  20000  50000  ...
	   100000 200000 500000 ...
	   1000000 2000000 5000000 ];
	   
 	   
if length(nints)==1,
	  
  exactint=distance/(nints);
  [dun,I]=min(abs(niceints-exactint));
 
  if ~fixticks,
    nints=fix(distance/niceints(I));
  end;
  dist=[0:nints]*niceints(I);

else
  dist=(nints-nints(1));
  nints=length(dist)-1;
end;

if max(log10(dist(2:end)))>=3,
   numfac=1000;
else
   numfac=1;
end;
      
if horiz,
 
 
  if strcmp(gtickdir,'in'),

    line(posx(1)+[0 dist(end)/scfac],posy(1)+[0 0],'color',gcolor,'linewidth',glinewidth,'linestyle',glinestyle,...
	 'clipping','off','tag','m_ruler_x');
	 
    XX=posx(1)+[dist;dist]/scfac;
    YY=posy(1)+diff(ylm)*gticklen*[-1;1]*ones(1,nints+1);
    if IsOctave,
      for k=1:size(XX,2),
        line(XX(:,k),YY(:,k),...
	 'color',gcolor,'linewidth',glinewidth/3,'linestyle',glinestyle,...
	 'clipping','off','tag','m_ruler_y');
      end;
    else  
      line(XX,YY,...
	 'color',gcolor,'linewidth',glinewidth/3,'linestyle',glinestyle,...
	 'clipping','off','tag','m_ruler_y');
    end;	 
  else
   
    patch(posx(1)+[dist(1:end-1);dist(1:end-1);dist(2:end);dist(2:end)]/scfac,...
           posy(1)+diff(ylm)*gticklen*[-1;1;1;-1]*ones(1,nints),...
	   repmat(LARGVAL  ,4,nints),...
           reshape(rem(rem(0:nints*3-1,nints),2)==0,1,nints,3),...
	 'linewidth',glinewidth/3,'linestyle',glinestyle,...
         'clipping','off','tag','m_ruler');

  end;
   
  if nints>1,
    for k=1:nints,
      text(posx(1)+dist(k)/scfac,posy(1)-diff(ylm)*gticklen*2,sprintf('%d',dist(k)/numfac), ...
          'fontsize',gfontsize,'fontname',gfontname,...
         'verticalalignment','top','horizontalalignment','center','tag','m_ruler_label');
    end;
    text(posx(1)+dist(nints+1)/scfac,posy(1)-diff(ylm)*gticklen*2,sprintf('%d km',dist(end)/numfac),...
          'fontsize',gfontsize,'fontname',gfontname,...
          'verticalalignment','top','horizontalalignment','center','tag','m_ruler_label');
  else 
    text(posx(1)+mean(dist)/scfac,posy(1)-diff(ylm)*gticklen*2,sprintf('%d km',dist(end)/numfac),...
          'fontsize',gfontsize,'fontname',gfontname,...
          'verticalalignment','top','horizontalalignment','center','tag','m_ruler_label');
  end;
  
else,

  if strcmp(gtickdir,'in'),

    line(posx(1)+[0 0],posy(1)+[0 dist(end)/scfac],'color',gcolor,'linewidth',glinewidth,'linestyle',glinestyle,...
	 'clipping','off','tag','m_scalebar_x');
	 
    XX=posx(1)+diff(xlm)*gticklen*[-1;1]*ones(1,nints+1);
    YY=posy(1)+[dist;dist]/scfac;
    
    if IsOctave,
      for k=1:size(XX,2),
       line(XX(:,k),YY(:,k),...
	 'color',gcolor,'linewidth',glinewidth/3,'linestyle',glinestyle,...
	 'clipping','off','tag','m_ruler_y');
      end;
    else  
       line(XX,YY,...
	 'color',gcolor,'linewidth',glinewidth/3,'linestyle',glinestyle,...
	 'clipping','off','tag','m_ruler_y');
    end;	 
  else
   
    patch(posx(1)+diff(xlm)*gticklen*[-1;1;1;-1]*ones(1,nints),...
          posy(1)+[dist(1:end-1);dist(1:end-1);dist(2:end);dist(2:end)]/scfac,...
	   repmat(LARGVAL  ,4,nints),...
           reshape(rem(rem(0:nints*3-1,nints),2)==0,1,nints,3),...
	 'linewidth',glinewidth/3,'linestyle',glinestyle,...
         'clipping','off','tag','m_ruler');

  end;

  if nints>1,
    for k=1:nints,
      text(posx(1)+diff(xlm)*gticklen*2,posy(1)+dist(k)/scfac,sprintf('%d',dist(k)/numfac), ...
          'fontsize',gfontsize,'fontname',gfontname,...
         'verticalalignment','middle','horizontalalignment','left','tag','m_ruler_label');
    end;
    text(posx(1)+diff(xlm)*gticklen*2,posy(1)+dist(nints+1)/scfac,sprintf('%d km',dist(end)/numfac),...
          'fontsize',gfontsize,'fontname',gfontname,...
          'verticalalignment','middle','horizontalalignment','left','tag','m_ruler_label');
  else  
    text(posx(1)+diff(xlm)*gticklen*2,posy(1)+mean(dist)/scfac,sprintf('%d km',dist(end)/numfac),...
          'fontsize',gfontsize,'fontname',gfontname,...
          'verticalalignment','middle','horizontalalignment','left','tag','m_ruler_label');
  end;
       
end;







 







